2002-10-29 01:41:42 +01:00
|
|
|
/*
|
|
|
|
* 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
|
2006-05-18 14:49:52 +02:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2002-10-29 01:41:42 +01:00
|
|
|
*/
|
|
|
|
|
2003-09-06 01:08:26 +02:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
2002-10-29 01:41:42 +01:00
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winuser.h"
|
|
|
|
#include "wownt32.h"
|
|
|
|
#include "wine/winuser16.h"
|
2004-12-08 19:06:14 +01:00
|
|
|
#include "user_private.h"
|
2002-10-29 01:41:42 +01:00
|
|
|
#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 */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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 */
|
|
|
|
};
|
|
|
|
|
2009-12-23 13:45:06 +01:00
|
|
|
static struct hook16_queue_info *get_hook_info( BOOL create )
|
|
|
|
{
|
|
|
|
static DWORD hook_tls = TLS_OUT_OF_INDEXES;
|
|
|
|
struct hook16_queue_info *info = TlsGetValue( hook_tls );
|
|
|
|
|
|
|
|
if (!info && create)
|
|
|
|
{
|
|
|
|
if (hook_tls == TLS_OUT_OF_INDEXES) hook_tls = TlsAlloc();
|
|
|
|
info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*info) );
|
|
|
|
TlsSetValue( hook_tls, info );
|
|
|
|
}
|
|
|
|
return info;
|
|
|
|
}
|
2002-10-29 01:41:42 +01:00
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* map_msg_16_to_32
|
|
|
|
*/
|
2007-03-17 11:34:08 +01:00
|
|
|
static inline void map_msg_16_to_32( const MSG16 *msg16, MSG *msg32 )
|
2002-10-29 01:41:42 +01:00
|
|
|
{
|
|
|
|
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
|
|
|
|
*/
|
2007-03-17 11:34:08 +01:00
|
|
|
static inline void map_msg_32_to_16( const MSG *msg32, MSG16 *msg16 )
|
2002-10-29 01:41:42 +01:00
|
|
|
{
|
|
|
|
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 )
|
|
|
|
{
|
2009-12-23 13:45:06 +01:00
|
|
|
struct hook16_queue_info *info = get_hook_info( FALSE );
|
2003-02-27 22:09:45 +01:00
|
|
|
WORD args[4];
|
2005-07-06 12:36:28 +02:00
|
|
|
DWORD ret;
|
2002-10-29 01:41:42 +01:00
|
|
|
INT prev_id = info->id;
|
|
|
|
info->id = id;
|
2003-02-27 22:09:45 +01:00
|
|
|
|
|
|
|
args[3] = code;
|
|
|
|
args[2] = wp;
|
|
|
|
args[1] = HIWORD(lp);
|
|
|
|
args[0] = LOWORD(lp);
|
|
|
|
WOWCallback16Ex( (DWORD)info->proc[id - WH_MINHOOK], WCB16_PASCAL, sizeof(args), args, &ret );
|
|
|
|
|
2002-10-29 01:41:42 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-20 16:34:14 +02:00
|
|
|
struct wndproc_hook_params
|
|
|
|
{
|
|
|
|
HHOOK hhook;
|
|
|
|
INT code;
|
|
|
|
WPARAM wparam;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* callback for WINPROC_Call16To32A */
|
|
|
|
static LRESULT wndproc_hook_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
|
|
|
|
LRESULT *result, void *arg )
|
|
|
|
{
|
|
|
|
struct wndproc_hook_params *params = arg;
|
|
|
|
CWPSTRUCT cwp;
|
|
|
|
|
|
|
|
cwp.hwnd = hwnd;
|
|
|
|
cwp.message = msg;
|
|
|
|
cwp.wParam = wp;
|
|
|
|
cwp.lParam = lp;
|
|
|
|
*result = 0;
|
|
|
|
return CallNextHookEx( params->hhook, params->code, params->wparam, (LPARAM)&cwp );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* callback for WINPROC_Call32ATo16 */
|
|
|
|
static LRESULT wndproc_hook_callback16( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp,
|
|
|
|
LRESULT *result, void *arg )
|
|
|
|
{
|
|
|
|
struct wndproc_hook_params *params = arg;
|
|
|
|
CWPSTRUCT16 cwp;
|
|
|
|
LRESULT ret;
|
|
|
|
|
|
|
|
cwp.hwnd = hwnd;
|
|
|
|
cwp.message = msg;
|
|
|
|
cwp.wParam = wp;
|
|
|
|
cwp.lParam = lp;
|
|
|
|
|
|
|
|
lp = MapLS( &cwp );
|
|
|
|
ret = call_hook_16( WH_CALLWNDPROC, params->code, params->wparam, lp );
|
|
|
|
UnMapLS( lp );
|
|
|
|
|
|
|
|
*result = 0;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-03-08 14:50:18 +01:00
|
|
|
/* helper for SendMessage16 */
|
|
|
|
void call_WH_CALLWNDPROC_hook( HWND16 hwnd, UINT16 msg, WPARAM16 wp, LPARAM lp )
|
|
|
|
{
|
|
|
|
CWPSTRUCT16 cwp;
|
|
|
|
struct hook16_queue_info *info = get_hook_info( FALSE );
|
|
|
|
|
|
|
|
if (!info->proc[WH_CALLWNDPROC - WH_MINHOOK]) return;
|
|
|
|
|
|
|
|
cwp.hwnd = hwnd;
|
|
|
|
cwp.message = msg;
|
|
|
|
cwp.wParam = wp;
|
|
|
|
cwp.lParam = lp;
|
|
|
|
|
|
|
|
lp = MapLS( &cwp );
|
|
|
|
call_hook_16( WH_CALLWNDPROC, HC_ACTION, 1, lp );
|
|
|
|
UnMapLS( lp );
|
|
|
|
}
|
2006-05-20 16:34:14 +02:00
|
|
|
|
2002-10-29 01:41:42 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* 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 )
|
|
|
|
{
|
2006-05-20 16:34:14 +02:00
|
|
|
struct wndproc_hook_params params;
|
2002-10-29 01:41:42 +01:00
|
|
|
CWPSTRUCT *cwp32 = (CWPSTRUCT *)lp;
|
2006-05-20 16:34:14 +02:00
|
|
|
LRESULT result;
|
2002-10-29 01:41:42 +01:00
|
|
|
|
2006-05-20 16:34:14 +02:00
|
|
|
params.code = code;
|
|
|
|
params.wparam = wp;
|
|
|
|
return WINPROC_CallProc32ATo16( wndproc_hook_callback16, cwp32->hwnd, cwp32->message,
|
|
|
|
cwp32->wParam, cwp32->lParam, &result, ¶ms );
|
2002-10-29 01:41:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* 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;
|
|
|
|
|
2004-01-28 22:41:56 +01:00
|
|
|
cs16.lpCreateParams = (SEGPTR)cbtcw32->lpcs->lpCreateParams;
|
2003-05-16 22:17:52 +02:00
|
|
|
cs16.hInstance = HINSTANCE_16(cbtcw32->lpcs->hInstance);
|
2002-10-29 01:41:42 +01:00
|
|
|
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;
|
|
|
|
|
2004-08-31 02:02:02 +02:00
|
|
|
rect16.left = rect32->left;
|
|
|
|
rect16.top = rect32->top;
|
|
|
|
rect16.right = rect32->right;
|
|
|
|
rect16.bottom = rect32->bottom;
|
2002-10-29 01:41:42 +01:00
|
|
|
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 )
|
|
|
|
{
|
|
|
|
struct hook16_queue_info *info;
|
|
|
|
HHOOK hook;
|
|
|
|
int index = id - WH_MINHOOK;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2009-12-23 13:45:06 +01:00
|
|
|
if (!(info = get_hook_info( TRUE ))) return 0;
|
2002-10-29 01:41:42 +01:00
|
|
|
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 )
|
|
|
|
{
|
|
|
|
struct hook16_queue_info *info;
|
|
|
|
int index = id - WH_MINHOOK;
|
|
|
|
|
|
|
|
if (id < WH_MINHOOK || id > WH_MAXHOOK16) return FALSE;
|
2009-12-23 13:45:06 +01:00
|
|
|
if (!(info = get_hook_info( FALSE ))) return FALSE;
|
2002-10-29 01:41:42 +01:00
|
|
|
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 )
|
|
|
|
{
|
|
|
|
struct hook16_queue_info *info;
|
|
|
|
int index;
|
|
|
|
|
2009-12-23 13:45:06 +01:00
|
|
|
if (!(info = get_hook_info( FALSE ))) return FALSE;
|
2002-10-29 01:41:42 +01:00
|
|
|
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 )
|
|
|
|
{
|
|
|
|
struct hook16_queue_info *info;
|
|
|
|
LRESULT ret = 0;
|
|
|
|
|
2009-12-23 13:45:06 +01:00
|
|
|
if (!(info = get_hook_info( FALSE ))) return 0;
|
2002-10-29 01:41:42 +01:00
|
|
|
|
|
|
|
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);
|
2006-05-20 16:34:14 +02:00
|
|
|
LRESULT result;
|
|
|
|
struct wndproc_hook_params params;
|
|
|
|
|
|
|
|
params.hhook = hhook;
|
|
|
|
params.code = code;
|
|
|
|
params.wparam = wparam;
|
|
|
|
ret = WINPROC_CallProc16To32A( wndproc_hook_callback, cwp16->hwnd, cwp16->message,
|
|
|
|
cwp16->wParam, cwp16->lParam, &result, ¶ms );
|
2002-10-29 01:41:42 +01:00
|
|
|
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 );
|
|
|
|
|
2004-01-28 22:41:56 +01:00
|
|
|
cs32.lpCreateParams = (LPVOID)cs16->lpCreateParams;
|
2003-05-16 22:17:52 +02:00
|
|
|
cs32.hInstance = HINSTANCE_32(cs16->hInstance);
|
2002-10-29 01:41:42 +01:00
|
|
|
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;
|
|
|
|
|
2004-08-31 02:02:02 +02:00
|
|
|
rect32.left = rect16->left;
|
|
|
|
rect32.top = rect16->top;
|
|
|
|
rect32.right = rect16->right;
|
|
|
|
rect32.bottom = rect16->bottom;
|
2002-10-29 01:41:42 +01:00
|
|
|
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 );
|
|
|
|
}
|