mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 20:30:01 +00:00
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.
This commit is contained in:
parent
bdb44555a3
commit
0286135de3
@ -26,7 +26,6 @@
|
||||
#include "winpos.h"
|
||||
#include "wownt32.h"
|
||||
#include "wine/debug.h"
|
||||
#include "hook.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ttydrv);
|
||||
|
||||
@ -44,6 +43,7 @@ BOOL TTYDRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
|
||||
{
|
||||
BOOL ret;
|
||||
HWND hwndLinkAfter;
|
||||
CBT_CREATEWNDA cbtc;
|
||||
|
||||
#ifdef WINE_CURSES
|
||||
WND *wndPtr = WIN_GetPtr( hwnd );
|
||||
@ -81,22 +81,12 @@ BOOL TTYDRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
|
||||
hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
|
||||
? HWND_BOTTOM : HWND_TOP;
|
||||
|
||||
if (HOOK_IsHooked( WH_CBT ))
|
||||
cbtc.lpcs = cs;
|
||||
cbtc.hwndInsertAfter = hwndLinkAfter;
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode ))
|
||||
{
|
||||
CBT_CREATEWNDA cbtc;
|
||||
LRESULT lret;
|
||||
|
||||
cbtc.lpcs = cs;
|
||||
cbtc.hwndInsertAfter = hwndLinkAfter;
|
||||
lret = (unicode) ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND,
|
||||
(WPARAM)hwnd, (LPARAM)&cbtc)
|
||||
: HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND,
|
||||
(WPARAM)hwnd, (LPARAM)&cbtc);
|
||||
if (lret)
|
||||
{
|
||||
TRACE("CBT-hook returned !0\n");
|
||||
return FALSE;
|
||||
}
|
||||
TRACE("CBT-hook returned !0\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (unicode)
|
||||
|
@ -30,7 +30,6 @@ C_SRCS = \
|
||||
$(TOPOBJDIR)/windows/defwnd.c \
|
||||
$(TOPOBJDIR)/windows/dialog.c \
|
||||
$(TOPOBJDIR)/windows/driver.c \
|
||||
$(TOPOBJDIR)/windows/hook.c \
|
||||
$(TOPOBJDIR)/windows/input.c \
|
||||
$(TOPOBJDIR)/windows/keyboard.c \
|
||||
$(TOPOBJDIR)/windows/mdi.c \
|
||||
@ -63,6 +62,7 @@ C_SRCS = \
|
||||
display.c \
|
||||
exticon.c \
|
||||
focus.c \
|
||||
hook.c \
|
||||
lstr.c \
|
||||
message.c \
|
||||
misc.c \
|
||||
@ -77,6 +77,7 @@ C_SRCS = \
|
||||
|
||||
C_SRCS16 = \
|
||||
bidi16.c \
|
||||
hook16.c \
|
||||
network.c \
|
||||
user16.c \
|
||||
wnd16.c
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "win.h"
|
||||
#include "hook.h"
|
||||
#include "message.h"
|
||||
#include "user.h"
|
||||
#include "wine/server.h"
|
||||
@ -74,6 +73,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
HWND previous = GetActiveWindow();
|
||||
BOOL ret;
|
||||
DWORD old_thread, new_thread;
|
||||
CBTACTIVATESTRUCT cbt;
|
||||
|
||||
if (previous == hwnd)
|
||||
{
|
||||
@ -82,13 +82,9 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
}
|
||||
|
||||
/* call CBT hook chain */
|
||||
if (HOOK_IsHooked( WH_CBT ))
|
||||
{
|
||||
CBTACTIVATESTRUCT cbt;
|
||||
cbt.fMouse = mouse;
|
||||
cbt.hWndActive = previous;
|
||||
if (HOOK_CallHooksW( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt )) return FALSE;
|
||||
}
|
||||
cbt.fMouse = mouse;
|
||||
cbt.hWndActive = previous;
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE )) return FALSE;
|
||||
|
||||
if (IsWindow(previous))
|
||||
{
|
||||
@ -265,7 +261,7 @@ HWND WINAPI SetFocus( HWND hwnd )
|
||||
}
|
||||
|
||||
/* call hooks */
|
||||
if (HOOK_CallHooksW( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous )) return 0;
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE )) return 0;
|
||||
|
||||
/* activate hwndTop if needed. */
|
||||
if (hwndTop != GetActiveWindow())
|
||||
@ -277,8 +273,7 @@ HWND WINAPI SetFocus( HWND hwnd )
|
||||
else /* NULL hwnd passed in */
|
||||
{
|
||||
if (!previous) return 0; /* nothing to do */
|
||||
if( HOOK_CallHooksW( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous ) )
|
||||
return 0;
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous, TRUE )) return 0;
|
||||
}
|
||||
|
||||
/* change focus and send messages */
|
||||
|
518
dlls/user/hook.c
Normal file
518
dlls/user/hook.c
Normal file
@ -0,0 +1,518 @@
|
||||
/*
|
||||
* Windows hook functions
|
||||
*
|
||||
* Copyright 2002 Alexandre Julliard
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* NOTES:
|
||||
* Status of the various hooks:
|
||||
* WH_MSGFILTER OK
|
||||
* WH_JOURNALRECORD Partially implemented
|
||||
* WH_JOURNALPLAYBACK Partially implemented
|
||||
* WH_KEYBOARD OK
|
||||
* WH_GETMESSAGE OK (FIXME: A/W mapping?)
|
||||
* WH_CALLWNDPROC OK (FIXME: A/W mapping?)
|
||||
* WH_CBT
|
||||
* HCBT_MOVESIZE OK
|
||||
* HCBT_MINMAX OK
|
||||
* HCBT_QS OK
|
||||
* HCBT_CREATEWND OK
|
||||
* HCBT_DESTROYWND OK
|
||||
* HCBT_ACTIVATE OK
|
||||
* HCBT_CLICKSKIPPED OK
|
||||
* HCBT_KEYSKIPPED OK
|
||||
* HCBT_SYSCOMMAND Not implemented
|
||||
* HCBT_SETFOCUS OK
|
||||
* WH_SYSMSGFILTER OK
|
||||
* WH_MOUSE OK
|
||||
* WH_HARDWARE Not supported in Win32
|
||||
* WH_DEBUG Not implemented
|
||||
* WH_SHELL
|
||||
* HSHELL_WINDOWCREATED OK
|
||||
* HSHELL_WINDOWDESTROYED OK
|
||||
* HSHELL_ACTIVATESHELLWINDOW Not implemented
|
||||
* HSHELL_WINDOWACTIVATED Not implemented
|
||||
* HSHELL_GETMINRECT Not implemented
|
||||
* HSHELL_REDRAW Not implemented
|
||||
* HSHELL_TASKMAN Not implemented
|
||||
* HSHELL_LANGUAGE Not implemented
|
||||
* HSHELL_SYSMENU Not implemented
|
||||
* HSHELL_ENDTASK Not implemented
|
||||
* HSHELL_ACCESSIBILITYSTATE Not implemented
|
||||
* HSHELL_APPCOMMAND Not implemented
|
||||
* HSHELL_WINDOWREPLACED Not implemented
|
||||
* HSHELL_WINDOWREPLACING Not implemented
|
||||
* WH_FOREGROUNDIDLE Not implemented
|
||||
* WH_CALLWNDPROCRET OK (FIXME: A/W mapping?)
|
||||
* WH_KEYBOARD_LL Implemented but should use SendMessage instead
|
||||
* WH_MOUSE_LL Implemented but should use SendMessage instead
|
||||
*/
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "heap.h"
|
||||
#include "queue.h"
|
||||
#include "win.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(hook);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||
|
||||
static const char * const hook_names[WH_MAXHOOK - WH_MINHOOK + 1] =
|
||||
{
|
||||
"WH_MSGFILTER",
|
||||
"WH_JOURNALRECORD",
|
||||
"WH_JOURNALPLAYBACK",
|
||||
"WH_KEYBOARD",
|
||||
"WH_GETMESSAGE",
|
||||
"WH_CALLWNDPROC",
|
||||
"WH_CBT",
|
||||
"WH_SYSMSGFILTER",
|
||||
"WH_MOUSE",
|
||||
"WH_HARDWARE",
|
||||
"WH_DEBUG",
|
||||
"WH_SHELL",
|
||||
"WH_FOREGROUNDIDLE",
|
||||
"WH_CALLWNDPROCRET",
|
||||
"WH_KEYBOARD_LL",
|
||||
"WH_MOUSE_LL"
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_windows_hook
|
||||
*
|
||||
* Implementation of SetWindowsHookExA and SetWindowsHookExW.
|
||||
*/
|
||||
static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL unicode )
|
||||
{
|
||||
HHOOK handle = 0;
|
||||
|
||||
if (tid) /* thread-local hook */
|
||||
{
|
||||
if (id == WH_JOURNALRECORD ||
|
||||
id == WH_JOURNALPLAYBACK ||
|
||||
id == WH_KEYBOARD_LL ||
|
||||
id == WH_MOUSE_LL ||
|
||||
id == WH_SYSMSGFILTER)
|
||||
{
|
||||
/* these can only be global */
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else /* system-global hook */
|
||||
{
|
||||
if (!inst)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
FIXME( "system hook %s won't work right\n", hook_names[id-WH_MINHOOK] );
|
||||
}
|
||||
|
||||
SERVER_START_REQ( set_hook )
|
||||
{
|
||||
req->id = id;
|
||||
req->tid = tid;
|
||||
req->proc = proc;
|
||||
req->unicode = unicode;
|
||||
if (!wine_server_call_err( req )) handle = reply->handle;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
TRACE( "%s %p %lx -> %x\n", hook_names[id-WH_MINHOOK], proc, tid, handle );
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* call_hook_AtoW
|
||||
*/
|
||||
static LRESULT call_hook_AtoW( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM lparam )
|
||||
{
|
||||
LRESULT ret;
|
||||
|
||||
if (id != WH_CBT || code != HCBT_CREATEWND) ret = proc( code, wparam, lparam );
|
||||
else
|
||||
{
|
||||
CBT_CREATEWNDA *cbtcwA = (CBT_CREATEWNDA *)lparam;
|
||||
CBT_CREATEWNDW cbtcwW;
|
||||
CREATESTRUCTW csW;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* call_hook_WtoA
|
||||
*/
|
||||
static LRESULT call_hook_WtoA( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM lparam )
|
||||
{
|
||||
LRESULT ret;
|
||||
|
||||
if (id != WH_CBT || code != HCBT_CREATEWND) ret = proc( code, wparam, lparam );
|
||||
else
|
||||
{
|
||||
CBT_CREATEWNDW *cbtcwW = (CBT_CREATEWNDW *)lparam;
|
||||
CBT_CREATEWNDA cbtcwA;
|
||||
CREATESTRUCTA csA;
|
||||
|
||||
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
|
||||
*/
|
||||
static LRESULT call_hook( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM lparam,
|
||||
BOOL prev_unicode, BOOL next_unicode )
|
||||
{
|
||||
LRESULT ret;
|
||||
|
||||
if (TRACE_ON(relay))
|
||||
DPRINTF( "%08lx:Call hook proc %p (id=%s,code=%x,wp=%08x,lp=%08lx)\n",
|
||||
GetCurrentThreadId(), proc, hook_names[id-WH_MINHOOK], code, wparam, lparam );
|
||||
|
||||
if (!prev_unicode == !next_unicode) ret = proc( code, wparam, lparam );
|
||||
else if (prev_unicode) ret = call_hook_WtoA( proc, id, code, wparam, lparam );
|
||||
else ret = call_hook_AtoW( proc, id, code, wparam, lparam );
|
||||
|
||||
if (TRACE_ON(relay))
|
||||
DPRINTF( "%08lx:Ret hook proc %p (id=%s,code=%x,wp=%08x,lp=%08lx) retval=%08lx\n",
|
||||
GetCurrentThreadId(), proc, hook_names[id-WH_MINHOOK], code, wparam, lparam, ret );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* HOOK_CallHooks
|
||||
*/
|
||||
LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode )
|
||||
{
|
||||
MESSAGEQUEUE *queue = QUEUE_Current();
|
||||
HOOKPROC proc = NULL;
|
||||
HHOOK prev;
|
||||
BOOL unicode_hook = FALSE;
|
||||
LRESULT ret = 0;
|
||||
int locks;
|
||||
|
||||
if (!queue) return 0;
|
||||
prev = queue->hook;
|
||||
SERVER_START_REQ( start_hook_chain )
|
||||
{
|
||||
req->id = id;
|
||||
if (!wine_server_call_err( req ))
|
||||
{
|
||||
queue->hook = reply->handle;
|
||||
proc = reply->proc;
|
||||
unicode_hook = reply->unicode;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (proc)
|
||||
{
|
||||
TRACE( "calling hook %p %s code %x wp %x lp %lx\n",
|
||||
proc, hook_names[id-WH_MINHOOK], code, wparam, lparam );
|
||||
|
||||
locks = WIN_SuspendWndsLock();
|
||||
ret = call_hook( proc, id, code, wparam, lparam, unicode, unicode_hook );
|
||||
WIN_RestoreWndsLock( locks );
|
||||
|
||||
SERVER_START_REQ( finish_hook_chain )
|
||||
{
|
||||
req->id = id;
|
||||
wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
queue->hook = prev;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* HOOK_IsHooked
|
||||
*/
|
||||
BOOL HOOK_IsHooked( INT id )
|
||||
{
|
||||
return TRUE; /* FIXME */
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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() );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetWindowsHookExA (USER32.@)
|
||||
*/
|
||||
HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid )
|
||||
{
|
||||
return set_windows_hook( id, proc, inst, tid, FALSE );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetWindowsHookExW (USER32.@)
|
||||
*/
|
||||
HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid )
|
||||
{
|
||||
return set_windows_hook( id, proc, inst, tid, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* UnhookWindowsHook (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE( "%s %p\n", hook_names[id-WH_MINHOOK], proc );
|
||||
|
||||
SERVER_START_REQ( remove_hook )
|
||||
{
|
||||
req->id = id;
|
||||
req->proc = proc;
|
||||
ret = !wine_server_call_err( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* UnhookWindowsHookEx (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE( "%x\n", hhook );
|
||||
|
||||
SERVER_START_REQ( remove_hook )
|
||||
{
|
||||
req->handle = hhook;
|
||||
ret = !wine_server_call_err( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CallNextHookEx (USER32.@)
|
||||
*/
|
||||
LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam )
|
||||
{
|
||||
MESSAGEQUEUE *queue = QUEUE_Current();
|
||||
HHOOK prev;
|
||||
HOOKPROC proc = NULL;
|
||||
INT id = 0;
|
||||
BOOL prev_unicode = FALSE, next_unicode = FALSE;
|
||||
LRESULT ret = 0;
|
||||
|
||||
if (!queue) return 0;
|
||||
prev = queue->hook;
|
||||
SERVER_START_REQ( get_next_hook )
|
||||
{
|
||||
req->handle = prev;
|
||||
if (!wine_server_call_err( req ))
|
||||
{
|
||||
queue->hook = reply->next;
|
||||
id = reply->id;
|
||||
proc = reply->proc;
|
||||
prev_unicode = reply->prev_unicode;
|
||||
next_unicode = reply->next_unicode;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (proc)
|
||||
{
|
||||
TRACE( "calling hook %p %s code %x wp %x lp %lx\n",
|
||||
proc, hook_names[id-WH_MINHOOK], code, wparam, lparam );
|
||||
|
||||
return call_hook( proc, id, code, wparam, lparam, prev_unicode, next_unicode );
|
||||
}
|
||||
queue->hook = prev;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CallMsgFilterA (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
|
||||
{
|
||||
if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, FALSE )) return TRUE;
|
||||
return HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CallMsgFilterW (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
|
||||
{
|
||||
if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, TRUE )) return TRUE;
|
||||
return HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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 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("(%x)-stub!\n", hEventHook);
|
||||
|
||||
return (hEventHook != 0);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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;
|
||||
}
|
617
dlls/user/hook16.c
Normal file
617
dlls/user/hook16.c
Normal file
@ -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 );
|
||||
}
|
@ -32,7 +32,6 @@
|
||||
#include "queue.h"
|
||||
#include "input.h"
|
||||
#include "message.h"
|
||||
#include "hook.h"
|
||||
#include "spy.h"
|
||||
#include "user.h"
|
||||
#include "win.h"
|
||||
@ -1339,10 +1338,13 @@ static BOOL unpack_dde_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM
|
||||
*
|
||||
* Call a window procedure and the corresponding hooks.
|
||||
*/
|
||||
static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL unicode )
|
||||
static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
|
||||
BOOL unicode, BOOL same_thread )
|
||||
{
|
||||
LRESULT result = 0;
|
||||
WNDPROC winproc;
|
||||
CWPSTRUCT cwp;
|
||||
CWPRETSTRUCT cwpret;
|
||||
MESSAGEQUEUE *queue = QUEUE_Current();
|
||||
|
||||
if (queue->recursion_count > MAX_SENDMSG_RECURSION) return 0;
|
||||
@ -1355,20 +1357,12 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
|
||||
}
|
||||
|
||||
/* first the WH_CALLWNDPROC hook */
|
||||
if (HOOK_IsHooked( WH_CALLWNDPROC ))
|
||||
{
|
||||
CWPSTRUCT cwp;
|
||||
cwp.lParam = lparam;
|
||||
cwp.wParam = wparam;
|
||||
cwp.message = msg;
|
||||
cwp.hwnd = WIN_GetFullHandle( hwnd );
|
||||
if (unicode) HOOK_CallHooksW( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp );
|
||||
else HOOK_CallHooksA( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp );
|
||||
lparam = cwp.lParam;
|
||||
wparam = cwp.wParam;
|
||||
msg = cwp.message;
|
||||
hwnd = cwp.hwnd;
|
||||
}
|
||||
hwnd = WIN_GetFullHandle( hwnd );
|
||||
cwp.lParam = lparam;
|
||||
cwp.wParam = wparam;
|
||||
cwp.message = msg;
|
||||
cwp.hwnd = hwnd;
|
||||
HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, same_thread, (LPARAM)&cwp, unicode );
|
||||
|
||||
/* now call the window procedure */
|
||||
if (unicode)
|
||||
@ -1383,17 +1377,12 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
|
||||
}
|
||||
|
||||
/* and finally the WH_CALLWNDPROCRET hook */
|
||||
if (HOOK_IsHooked( WH_CALLWNDPROCRET ))
|
||||
{
|
||||
CWPRETSTRUCT cwp;
|
||||
cwp.lResult = result;
|
||||
cwp.lParam = lparam;
|
||||
cwp.wParam = wparam;
|
||||
cwp.message = msg;
|
||||
cwp.hwnd = WIN_GetFullHandle( hwnd );
|
||||
if (unicode) HOOK_CallHooksW( WH_CALLWNDPROCRET, HC_ACTION, 1, (LPARAM)&cwp );
|
||||
else HOOK_CallHooksA( WH_CALLWNDPROCRET, HC_ACTION, 1, (LPARAM)&cwp );
|
||||
}
|
||||
cwpret.lResult = result;
|
||||
cwpret.lParam = lparam;
|
||||
cwpret.wParam = wparam;
|
||||
cwpret.message = msg;
|
||||
cwpret.hwnd = hwnd;
|
||||
HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, same_thread, (LPARAM)&cwpret, unicode );
|
||||
done:
|
||||
queue->recursion_count--;
|
||||
return result;
|
||||
@ -1521,7 +1510,7 @@ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags )
|
||||
old_info = queue->receive_info;
|
||||
queue->receive_info = &info;
|
||||
result = call_window_proc( info.msg.hwnd, info.msg.message, info.msg.wParam,
|
||||
info.msg.lParam, (info.type != MSG_ASCII) );
|
||||
info.msg.lParam, (info.type != MSG_ASCII), FALSE );
|
||||
reply_message( &info, result, TRUE );
|
||||
queue->receive_info = old_info;
|
||||
next:
|
||||
@ -1745,7 +1734,7 @@ LRESULT WINAPI SendMessageTimeoutW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
|
||||
|
||||
if (dest_tid == GetCurrentThreadId())
|
||||
{
|
||||
result = call_window_proc( hwnd, msg, wparam, lparam, TRUE );
|
||||
result = call_window_proc( hwnd, msg, wparam, lparam, TRUE, TRUE );
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
@ -1793,7 +1782,7 @@ LRESULT WINAPI SendMessageTimeoutA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
|
||||
|
||||
if (dest_tid == GetCurrentThreadId())
|
||||
{
|
||||
result = call_window_proc( hwnd, msg, wparam, lparam, FALSE );
|
||||
result = call_window_proc( hwnd, msg, wparam, lparam, FALSE, TRUE );
|
||||
ret = 1;
|
||||
}
|
||||
else if (dest_pid == GetCurrentProcessId())
|
||||
@ -1884,7 +1873,7 @@ BOOL WINAPI SendNotifyMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
|
||||
|
||||
if (dest_tid == GetCurrentThreadId())
|
||||
{
|
||||
call_window_proc( hwnd, msg, wparam, lparam, TRUE );
|
||||
call_window_proc( hwnd, msg, wparam, lparam, TRUE, TRUE );
|
||||
return TRUE;
|
||||
}
|
||||
return send_inter_thread_message( dest_tid, &info, &result );
|
||||
@ -1938,7 +1927,7 @@ BOOL WINAPI SendMessageCallbackW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa
|
||||
|
||||
if (dest_tid == GetCurrentThreadId())
|
||||
{
|
||||
result = call_window_proc( hwnd, msg, wparam, lparam, TRUE );
|
||||
result = call_window_proc( hwnd, msg, wparam, lparam, TRUE, TRUE );
|
||||
callback( hwnd, msg, data, result );
|
||||
return TRUE;
|
||||
}
|
||||
@ -2085,9 +2074,6 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
|
||||
if (!MSG_peek_message( &msg, hwnd, first, last,
|
||||
(flags & PM_REMOVE) ? GET_MSG_REMOVE : 0 ))
|
||||
{
|
||||
/* FIXME: should be done before checking for hw events */
|
||||
MSG_JournalPlayBackMsg();
|
||||
|
||||
if (!(flags & PM_NOYIELD))
|
||||
{
|
||||
DWORD count;
|
||||
@ -2119,7 +2105,7 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
|
||||
msg.pt.y = HIWORD( queue->GetMessagePosVal );
|
||||
}
|
||||
|
||||
HOOK_CallHooksW( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)&msg );
|
||||
HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, flags & PM_REMOVE, (LPARAM)&msg, TRUE );
|
||||
|
||||
/* copy back our internal safe copy of message data to msg_out.
|
||||
* msg_out is a variable from the *program*, so it can't be used
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "wine/winuser16.h"
|
||||
#include "wownt32.h"
|
||||
#include "winerror.h"
|
||||
#include "hook.h"
|
||||
#include "message.h"
|
||||
#include "spy.h"
|
||||
#include "thread.h"
|
||||
@ -38,6 +37,8 @@ DWORD USER16_AlertableWait = 0;
|
||||
LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
|
||||
{
|
||||
LRESULT result;
|
||||
UINT msg32;
|
||||
WPARAM wparam32;
|
||||
HWND hwnd = WIN_Handle32( hwnd16 );
|
||||
|
||||
if (hwnd != HWND_BROADCAST && WIN_IsCurrentThread(hwnd))
|
||||
@ -48,24 +49,20 @@ LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM
|
||||
/* first the WH_CALLWNDPROC hook */
|
||||
if (HOOK_IsHooked( WH_CALLWNDPROC ))
|
||||
{
|
||||
CWPSTRUCT16 cwp;
|
||||
SEGPTR seg_cwp;
|
||||
LPARAM lparam32 = lparam;
|
||||
|
||||
cwp.hwnd = hwnd16;
|
||||
cwp.message = msg;
|
||||
cwp.wParam = wparam;
|
||||
cwp.lParam = lparam;
|
||||
seg_cwp = MapLS( &cwp );
|
||||
HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, seg_cwp );
|
||||
UnMapLS( seg_cwp );
|
||||
if (cwp.hwnd != hwnd16)
|
||||
if (WINPROC_MapMsg16To32A( hwnd, msg, wparam, &msg32, &wparam32, &lparam32 ) != -1)
|
||||
{
|
||||
hwnd16 = cwp.hwnd;
|
||||
hwnd = WIN_Handle32( hwnd16 );
|
||||
CWPSTRUCT cwp;
|
||||
|
||||
cwp.hwnd = hwnd;
|
||||
cwp.message = msg32;
|
||||
cwp.wParam = wparam32;
|
||||
cwp.lParam = lparam32;
|
||||
HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp, FALSE );
|
||||
WINPROC_UnmapMsg16To32A( hwnd, msg32, wparam32, lparam32, 0 );
|
||||
/* FIXME: should reflect changes back into the message we send */
|
||||
}
|
||||
msg = cwp.message;
|
||||
wparam = cwp.wParam;
|
||||
lparam = cwp.lParam;
|
||||
}
|
||||
|
||||
if (!(winproc = (WNDPROC16)GetWindowLong16( hwnd16, GWL_WNDPROC ))) return 0;
|
||||
@ -76,9 +73,6 @@ LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM
|
||||
}
|
||||
else /* map to 32-bit unicode for inter-thread/process message */
|
||||
{
|
||||
UINT msg32;
|
||||
WPARAM wparam32;
|
||||
|
||||
if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
|
||||
return 0;
|
||||
result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
|
||||
|
@ -121,7 +121,7 @@ rsrc resources/version16.res
|
||||
120 pascal GetMessageTime() GetMessageTime
|
||||
121 pascal SetWindowsHook(s_word segptr) SetWindowsHook16
|
||||
122 pascal CallWindowProc(segptr word word word long) CallWindowProc16
|
||||
123 pascal16 CallMsgFilter(segptr s_word) CallMsgFilter16
|
||||
123 pascal16 CallMsgFilter(ptr s_word) CallMsgFilter16
|
||||
124 pascal16 UpdateWindow(word) UpdateWindow16
|
||||
125 pascal16 InvalidateRect(word ptr word) InvalidateRect16
|
||||
126 pascal16 InvalidateRgn(word word word) InvalidateRgn16
|
||||
@ -531,7 +531,7 @@ rsrc resources/version16.res
|
||||
821 pascal16 TranslateMessage32(ptr word) TranslateMessage32_16
|
||||
#821 stub IsDialogMessage32 # FIXME: two ordinal 821???
|
||||
822 pascal DispatchMessage32(ptr word) DispatchMessage32_16
|
||||
823 pascal16 CallMsgFilter32(segptr word word) CallMsgFilter32_16
|
||||
823 pascal16 CallMsgFilter32(ptr word word) CallMsgFilter32_16
|
||||
825 stub PostMessage32
|
||||
826 stub PostThreadMessage32
|
||||
827 pascal16 MessageBoxIndirect(ptr) MessageBoxIndirect16
|
||||
|
@ -686,9 +686,7 @@ init UserClientDllInitialize
|
||||
@ cdecl CLIPBOARD_LookupFormat(long) CLIPBOARD_LookupFormat
|
||||
@ cdecl CLIPBOARD_ReleaseOwner() CLIPBOARD_ReleaseOwner
|
||||
@ cdecl DCE_InvalidateDCE(long ptr) DCE_InvalidateDCE
|
||||
@ cdecl HOOK_CallHooksA(long long long long) HOOK_CallHooksA
|
||||
@ cdecl HOOK_CallHooksW(long long long long) HOOK_CallHooksW
|
||||
@ cdecl HOOK_IsHooked(long) HOOK_IsHooked
|
||||
@ cdecl HOOK_CallHooks(long long long long) HOOK_CallHooks
|
||||
@ cdecl NC_GetInsideRect(long ptr) NC_GetInsideRect
|
||||
@ cdecl NC_HandleNCHitTest(long long long) NC_HandleNCHitTest
|
||||
@ cdecl NC_HandleSetCursor(long long long) NC_HandleSetCursor
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "cursoricon.h"
|
||||
#include "global.h"
|
||||
#include "input.h"
|
||||
#include "hook.h"
|
||||
#include "message.h"
|
||||
#include "queue.h"
|
||||
#include "spy.h"
|
||||
@ -294,7 +293,6 @@ static void thread_detach(void)
|
||||
if (hQueue)
|
||||
{
|
||||
TIMER_RemoveThreadTimers();
|
||||
HOOK_FreeQueueHooks();
|
||||
WIN_DestroyThreadWindows( GetDesktopWindow() );
|
||||
QUEUE_DeleteMsgQueue();
|
||||
}
|
||||
@ -309,7 +307,7 @@ static void thread_detach(void)
|
||||
if (GetModuleUsage16( hModule ) <= 1)
|
||||
{
|
||||
/* ModuleUnload() in "Internals" */
|
||||
HOOK_FreeModuleHooks( hModule );
|
||||
/* HOOK_FreeModuleHooks( hModule ); */
|
||||
CLASS_FreeModuleClasses( hModule );
|
||||
CURSORICON_FreeModuleIcons( hModule );
|
||||
}
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "win.h"
|
||||
#include "winpos.h"
|
||||
#include "dce.h"
|
||||
#include "hook.h"
|
||||
#include "mwm.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
|
||||
@ -854,6 +853,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
|
||||
WND *wndPtr;
|
||||
struct x11drv_win_data *data;
|
||||
RECT rect;
|
||||
CBT_CREATEWNDA cbtc;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (cs->cx > 65535)
|
||||
@ -897,29 +897,16 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
|
||||
|
||||
/* Call the WH_CBT hook */
|
||||
|
||||
hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
|
||||
? HWND_BOTTOM : HWND_TOP;
|
||||
hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
|
||||
|
||||
if (HOOK_IsHooked( WH_CBT ))
|
||||
cbtc.lpcs = cs;
|
||||
cbtc.hwndInsertAfter = hwndLinkAfter;
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode ))
|
||||
{
|
||||
CBT_CREATEWNDA cbtc;
|
||||
LRESULT lret;
|
||||
|
||||
cbtc.lpcs = cs;
|
||||
cbtc.hwndInsertAfter = hwndLinkAfter;
|
||||
lret = (unicode) ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND,
|
||||
(WPARAM)hwnd, (LPARAM)&cbtc)
|
||||
: HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND,
|
||||
(WPARAM)hwnd, (LPARAM)&cbtc);
|
||||
if (lret)
|
||||
{
|
||||
TRACE("CBT-hook returned !0\n");
|
||||
goto failed;
|
||||
}
|
||||
TRACE("CBT-hook returned !0\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Send the WM_GETMINMAXINFO message and fix the size if needed */
|
||||
if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
|
||||
{
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "winerror.h"
|
||||
|
||||
#include "x11drv.h"
|
||||
#include "hook.h"
|
||||
#include "win.h"
|
||||
#include "winpos.h"
|
||||
#include "dce.h"
|
||||
@ -1122,7 +1121,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
|
||||
wpl.length = sizeof(wpl);
|
||||
GetWindowPlacement( hwnd, &wpl );
|
||||
|
||||
if (HOOK_CallHooksA( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd ))
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd, TRUE ))
|
||||
return SWP_NOSIZE | SWP_NOMOVE;
|
||||
|
||||
if (IsIconic( hwnd ))
|
||||
@ -2094,7 +2093,8 @@ void X11DRV_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
|
||||
}
|
||||
wine_tsx11_unlock();
|
||||
|
||||
if (HOOK_CallHooksA( WH_CBT, HCBT_MOVESIZE, (WPARAM)hwnd, (LPARAM)&sizingRect )) moved = FALSE;
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_MOVESIZE, (WPARAM)hwnd, (LPARAM)&sizingRect, TRUE ))
|
||||
moved = FALSE;
|
||||
|
||||
SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
|
||||
SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Windows hook definitions
|
||||
*
|
||||
* Copyright 1994 Alexandre Julliard
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __WINE_HOOK_H
|
||||
#define __WINE_HOOK_H
|
||||
|
||||
#include "windef.h"
|
||||
|
||||
#define HOOK_WIN16 0x00
|
||||
#define HOOK_WIN32A 0x01
|
||||
#define HOOK_WIN32W 0x02
|
||||
#define HOOK_INUSE 0x80
|
||||
|
||||
|
||||
/* hook type mask */
|
||||
#define HOOK_MAPTYPE (HOOK_WIN16 | HOOK_WIN32A | HOOK_WIN32W)
|
||||
|
||||
extern BOOL HOOK_IsHooked( INT16 id );
|
||||
extern LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
|
||||
LPARAM lParam );
|
||||
extern LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
|
||||
LPARAM lParam );
|
||||
extern LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
|
||||
LPARAM lParam );
|
||||
extern void HOOK_FreeModuleHooks( HMODULE16 hModule );
|
||||
extern void HOOK_FreeQueueHooks(void);
|
||||
|
||||
#endif /* __WINE_HOOK_H */
|
@ -27,9 +27,8 @@
|
||||
#include "winuser.h"
|
||||
#include "thread.h"
|
||||
|
||||
#define WH_NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
|
||||
|
||||
struct received_message_info;
|
||||
struct hook16_queue_info;
|
||||
|
||||
/* Message queue */
|
||||
typedef struct tagMESSAGEQUEUE
|
||||
@ -37,7 +36,9 @@ typedef struct tagMESSAGEQUEUE
|
||||
HQUEUE16 self; /* Handle to self (was: reserved) */
|
||||
HANDLE server_queue; /* Handle to server-side queue */
|
||||
DWORD recursion_count; /* Counter to prevent infinite SendMessage recursion */
|
||||
HHOOK hook; /* Current hook */
|
||||
struct received_message_info *receive_info; /* Info about message being currently received */
|
||||
struct hook16_queue_info *hook16_info; /* Opaque pointer for 16-bit hook support */
|
||||
|
||||
DWORD magic; /* magic number should be QUEUE_MAGIC */
|
||||
DWORD lockCount; /* reference counter */
|
||||
@ -48,9 +49,6 @@ typedef struct tagMESSAGEQUEUE
|
||||
|
||||
HCURSOR cursor; /* current cursor */
|
||||
INT cursor_count; /* cursor show count */
|
||||
|
||||
HANDLE16 hCurHook; /* Current hook */
|
||||
HANDLE16 hooks[WH_NB_HOOKS]; /* Task hooks list */
|
||||
} MESSAGEQUEUE;
|
||||
|
||||
|
||||
|
@ -137,6 +137,10 @@ extern WINE_LOOK TWEAK_WineLook;
|
||||
/* gray brush cache */
|
||||
extern HBRUSH CACHE_GetPattern55AABrush(void);
|
||||
|
||||
/* hook.c */
|
||||
extern LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode );
|
||||
extern BOOL HOOK_IsHooked( INT id );
|
||||
|
||||
/* syscolor.c */
|
||||
extern HPEN SYSCOLOR_GetPen( INT index );
|
||||
|
||||
|
@ -2866,6 +2866,80 @@ struct set_caret_info_reply
|
||||
#define SET_CARET_STATE 0x04
|
||||
|
||||
|
||||
|
||||
struct set_hook_request
|
||||
{
|
||||
struct request_header __header;
|
||||
int id;
|
||||
thread_id_t tid;
|
||||
void* proc;
|
||||
int unicode;
|
||||
};
|
||||
struct set_hook_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
user_handle_t handle;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct remove_hook_request
|
||||
{
|
||||
struct request_header __header;
|
||||
user_handle_t handle;
|
||||
int id;
|
||||
void* proc;
|
||||
};
|
||||
struct remove_hook_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct start_hook_chain_request
|
||||
{
|
||||
struct request_header __header;
|
||||
int id;
|
||||
};
|
||||
struct start_hook_chain_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
user_handle_t handle;
|
||||
void* proc;
|
||||
int unicode;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct finish_hook_chain_request
|
||||
{
|
||||
struct request_header __header;
|
||||
int id;
|
||||
};
|
||||
struct finish_hook_chain_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct get_next_hook_request
|
||||
{
|
||||
struct request_header __header;
|
||||
user_handle_t handle;
|
||||
};
|
||||
struct get_next_hook_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
user_handle_t next;
|
||||
int id;
|
||||
void* proc;
|
||||
int prev_unicode;
|
||||
int next_unicode;
|
||||
};
|
||||
|
||||
|
||||
enum request
|
||||
{
|
||||
REQ_new_process,
|
||||
@ -3032,6 +3106,11 @@ enum request
|
||||
REQ_set_capture_window,
|
||||
REQ_set_caret_window,
|
||||
REQ_set_caret_info,
|
||||
REQ_set_hook,
|
||||
REQ_remove_hook,
|
||||
REQ_start_hook_chain,
|
||||
REQ_finish_hook_chain,
|
||||
REQ_get_next_hook,
|
||||
REQ_NB_REQUESTS
|
||||
};
|
||||
|
||||
@ -3203,6 +3282,11 @@ union generic_request
|
||||
struct set_capture_window_request set_capture_window_request;
|
||||
struct set_caret_window_request set_caret_window_request;
|
||||
struct set_caret_info_request set_caret_info_request;
|
||||
struct set_hook_request set_hook_request;
|
||||
struct remove_hook_request remove_hook_request;
|
||||
struct start_hook_chain_request start_hook_chain_request;
|
||||
struct finish_hook_chain_request finish_hook_chain_request;
|
||||
struct get_next_hook_request get_next_hook_request;
|
||||
};
|
||||
union generic_reply
|
||||
{
|
||||
@ -3372,8 +3456,13 @@ union generic_reply
|
||||
struct set_capture_window_reply set_capture_window_reply;
|
||||
struct set_caret_window_reply set_caret_window_reply;
|
||||
struct set_caret_info_reply set_caret_info_reply;
|
||||
struct set_hook_reply set_hook_reply;
|
||||
struct remove_hook_reply remove_hook_reply;
|
||||
struct start_hook_chain_reply start_hook_chain_reply;
|
||||
struct finish_hook_chain_reply finish_hook_chain_reply;
|
||||
struct get_next_hook_reply get_next_hook_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 88
|
||||
#define SERVER_PROTOCOL_VERSION 89
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
@ -632,8 +632,8 @@ UINT16 WINAPI ArrangeIconicWindows16(HWND16);
|
||||
HDWP16 WINAPI BeginDeferWindowPos16(INT16);
|
||||
HDC16 WINAPI BeginPaint16(HWND16,LPPAINTSTRUCT16);
|
||||
BOOL16 WINAPI BringWindowToTop16(HWND16);
|
||||
BOOL16 WINAPI CallMsgFilter16(SEGPTR,INT16);
|
||||
BOOL16 WINAPI CallMsgFilter32_16(SEGPTR,INT16,BOOL16);
|
||||
BOOL16 WINAPI CallMsgFilter16(MSG16*,INT16);
|
||||
BOOL16 WINAPI CallMsgFilter32_16(MSG32_16*,INT16,BOOL16);
|
||||
LRESULT WINAPI CallNextHookEx16(HHOOK,INT16,WPARAM16,LPARAM);
|
||||
LRESULT WINAPI CallWindowProc16(WNDPROC16,HWND16,UINT16,WPARAM16,LPARAM);
|
||||
BOOL16 WINAPI ChangeClipboardChain16(HWND16,HWND16);
|
||||
|
@ -18,6 +18,7 @@ C_SRCS = \
|
||||
event.c \
|
||||
file.c \
|
||||
handle.c \
|
||||
hook.c \
|
||||
main.c \
|
||||
mapping.c \
|
||||
mutex.c \
|
||||
|
316
server/hook.c
Normal file
316
server/hook.c
Normal file
@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Server-side window hooks support
|
||||
*
|
||||
* Copyright (C) 2002 Alexandre Julliard
|
||||
*
|
||||
* 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 "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#include "object.h"
|
||||
#include "request.h"
|
||||
#include "user.h"
|
||||
|
||||
struct hook_table;
|
||||
|
||||
struct hook
|
||||
{
|
||||
struct list chain; /* hook chain entry */
|
||||
user_handle_t handle; /* user handle for this hook */
|
||||
struct thread *thread; /* thread owning the hook */
|
||||
int index; /* hook table index */
|
||||
void *proc; /* hook function */
|
||||
int unicode; /* is it a unicode hook? */
|
||||
};
|
||||
|
||||
#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
|
||||
#define HOOK_ENTRY(p) LIST_ENTRY( (p), struct hook, chain )
|
||||
|
||||
struct hook_table
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
struct list hooks[NB_HOOKS]; /* array of hook chains */
|
||||
int counts[NB_HOOKS]; /* use counts for each hook chain */
|
||||
};
|
||||
|
||||
static void hook_table_dump( struct object *obj, int verbose );
|
||||
static void hook_table_destroy( struct object *obj );
|
||||
|
||||
static const struct object_ops hook_table_ops =
|
||||
{
|
||||
sizeof(struct hook_table), /* size */
|
||||
hook_table_dump, /* dump */
|
||||
no_add_queue, /* add_queue */
|
||||
NULL, /* remove_queue */
|
||||
NULL, /* signaled */
|
||||
NULL, /* satisfied */
|
||||
NULL, /* get_poll_events */
|
||||
NULL, /* poll_event */
|
||||
no_get_fd, /* get_fd */
|
||||
no_flush, /* flush */
|
||||
no_get_file_info, /* get_file_info */
|
||||
NULL, /* queue_async */
|
||||
hook_table_destroy /* destroy */
|
||||
};
|
||||
|
||||
|
||||
/* create a new hook table */
|
||||
static struct hook_table *alloc_hook_table(void)
|
||||
{
|
||||
struct hook_table *table;
|
||||
int i;
|
||||
|
||||
if ((table = alloc_object( &hook_table_ops, -1 )))
|
||||
{
|
||||
for (i = 0; i < NB_HOOKS; i++)
|
||||
{
|
||||
list_init( &table->hooks[i] );
|
||||
table->counts[i] = 0;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/* create a new hook and add it to the specified table */
|
||||
static struct hook *add_hook( struct thread *thread, int index )
|
||||
{
|
||||
struct hook *hook;
|
||||
struct hook_table *table = thread->hooks;
|
||||
|
||||
if (!table)
|
||||
{
|
||||
if (!(table = alloc_hook_table())) return NULL;
|
||||
thread->hooks = table;
|
||||
}
|
||||
if (!(hook = mem_alloc( sizeof(*hook) ))) return NULL;
|
||||
|
||||
if (!(hook->handle = alloc_user_handle( hook, USER_HOOK )))
|
||||
{
|
||||
free( hook );
|
||||
return NULL;
|
||||
}
|
||||
hook->thread = thread ? (struct thread *)grab_object( thread ) : NULL;
|
||||
hook->index = index;
|
||||
list_add_head( &table->hooks[index], &hook->chain );
|
||||
return hook;
|
||||
}
|
||||
|
||||
/* free a hook, removing it from its chain */
|
||||
static void free_hook( struct hook *hook )
|
||||
{
|
||||
free_user_handle( hook->handle );
|
||||
if (hook->thread) release_object( hook->thread );
|
||||
list_remove( &hook->chain );
|
||||
free( hook );
|
||||
}
|
||||
|
||||
/* find a hook from its index and proc */
|
||||
static struct hook *find_hook( struct thread *thread, int index, void *proc )
|
||||
{
|
||||
struct list *p;
|
||||
struct hook_table *table = thread->hooks;
|
||||
|
||||
if (table)
|
||||
{
|
||||
LIST_FOR_EACH( p, &table->hooks[index] )
|
||||
{
|
||||
struct hook *hook = HOOK_ENTRY( p );
|
||||
if (hook->proc == proc) return hook;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the hook table that a given hook belongs to */
|
||||
inline static struct hook_table *get_table( struct hook *hook )
|
||||
{
|
||||
return hook->thread->hooks;
|
||||
}
|
||||
|
||||
/* get the first hook in the chain */
|
||||
inline static struct hook *get_first_hook( struct hook_table *table, int index )
|
||||
{
|
||||
struct list *elem = list_head( &table->hooks[index] );
|
||||
return elem ? HOOK_ENTRY( elem ) : NULL;
|
||||
}
|
||||
|
||||
/* find the next hook in the chain, skipping the deleted ones */
|
||||
static struct hook *get_next_hook( struct hook *hook )
|
||||
{
|
||||
struct hook_table *table = get_table( hook );
|
||||
struct hook *next;
|
||||
|
||||
while ((next = HOOK_ENTRY( list_next( &table->hooks[hook->index], &hook->chain ) )))
|
||||
{
|
||||
if (next->proc) break;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
static void hook_table_dump( struct object *obj, int verbose )
|
||||
{
|
||||
/* struct hook_table *table = (struct hook_table *)obj; */
|
||||
fprintf( stderr, "Hook table\n" );
|
||||
}
|
||||
|
||||
static void hook_table_destroy( struct object *obj )
|
||||
{
|
||||
int i;
|
||||
struct hook *hook;
|
||||
struct hook_table *table = (struct hook_table *)obj;
|
||||
|
||||
for (i = 0; i < NB_HOOKS; i++)
|
||||
{
|
||||
while ((hook = get_first_hook( table, i )) != NULL) free_hook( hook );
|
||||
}
|
||||
}
|
||||
|
||||
/* remove a hook, freeing it if the chain is not in use */
|
||||
static void remove_hook( struct hook *hook )
|
||||
{
|
||||
struct hook_table *table = get_table( hook );
|
||||
if (table->counts[hook->index])
|
||||
hook->proc = NULL; /* chain is in use, just mark it and return */
|
||||
else
|
||||
free_hook( hook );
|
||||
}
|
||||
|
||||
/* release a hook chain, removing deleted hooks if the use count drops to 0 */
|
||||
static void release_hook_chain( struct hook_table *table, int index )
|
||||
{
|
||||
if (!table->counts[index]) /* use count shouldn't already be 0 */
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
if (!--table->counts[index])
|
||||
{
|
||||
struct hook *hook = get_first_hook( table, index );
|
||||
while (hook)
|
||||
{
|
||||
struct hook *next = HOOK_ENTRY( list_next( &table->hooks[hook->index], &hook->chain ) );
|
||||
if (!hook->proc) free_hook( hook );
|
||||
hook = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* set a window hook */
|
||||
DECL_HANDLER(set_hook)
|
||||
{
|
||||
struct thread *thread;
|
||||
struct hook *hook;
|
||||
|
||||
if (!req->proc || req->id < WH_MINHOOK || req->id > WH_MAXHOOK)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
if (!(thread = get_thread_from_id( req->tid ))) return;
|
||||
|
||||
if ((hook = add_hook( thread, req->id - WH_MINHOOK )))
|
||||
{
|
||||
hook->proc = req->proc;
|
||||
hook->unicode = req->unicode;
|
||||
reply->handle = hook->handle;
|
||||
}
|
||||
release_object( thread );
|
||||
}
|
||||
|
||||
|
||||
/* remove a window hook */
|
||||
DECL_HANDLER(remove_hook)
|
||||
{
|
||||
struct hook *hook;
|
||||
|
||||
if (req->handle) hook = get_user_object( req->handle, USER_HOOK );
|
||||
else
|
||||
{
|
||||
if (!req->proc || req->id < WH_MINHOOK || req->id > WH_MAXHOOK)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
if (!(hook = find_hook( current, req->id - WH_MINHOOK, req->proc )))
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
}
|
||||
if (hook) remove_hook( hook );
|
||||
}
|
||||
|
||||
|
||||
/* start calling a hook chain */
|
||||
DECL_HANDLER(start_hook_chain)
|
||||
{
|
||||
struct hook *hook;
|
||||
struct hook_table *table = current->hooks;
|
||||
|
||||
if (req->id < WH_MINHOOK || req->id > WH_MAXHOOK)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
if (!table) return; /* no hook set */
|
||||
if (!(hook = get_first_hook( table, req->id - WH_MINHOOK ))) return; /* no hook set */
|
||||
reply->handle = hook->handle;
|
||||
reply->proc = hook->proc;
|
||||
reply->unicode = hook->unicode;
|
||||
table->counts[hook->index]++;
|
||||
}
|
||||
|
||||
|
||||
/* finished calling a hook chain */
|
||||
DECL_HANDLER(finish_hook_chain)
|
||||
{
|
||||
struct hook_table *table = current->hooks;
|
||||
int index = req->id - WH_MINHOOK;
|
||||
|
||||
if (req->id < WH_MINHOOK || req->id > WH_MAXHOOK)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
if (table) release_hook_chain( table, index );
|
||||
}
|
||||
|
||||
|
||||
/* get the next hook to call */
|
||||
DECL_HANDLER(get_next_hook)
|
||||
{
|
||||
struct hook *hook, *next;
|
||||
|
||||
if (!(hook = get_user_object( req->handle, USER_HOOK ))) return;
|
||||
if (hook->thread != current)
|
||||
{
|
||||
set_error( STATUS_INVALID_HANDLE );
|
||||
return;
|
||||
}
|
||||
if ((next = get_next_hook( hook )))
|
||||
{
|
||||
reply->next = next->handle;
|
||||
reply->id = next->index + WH_MINHOOK;
|
||||
reply->proc = next->proc;
|
||||
reply->prev_unicode = hook->unicode;
|
||||
reply->next_unicode = next->unicode;
|
||||
}
|
||||
}
|
@ -52,6 +52,34 @@ inline static void list_remove( struct list *elem )
|
||||
elem->prev->next = elem->next;
|
||||
}
|
||||
|
||||
/* get the next element */
|
||||
inline static struct list *list_next( struct list *list, struct list *elem )
|
||||
{
|
||||
struct list *ret = elem->next;
|
||||
if (elem->next == list) ret = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get the previous element */
|
||||
inline static struct list *list_prev( struct list *list, struct list *elem )
|
||||
{
|
||||
struct list *ret = elem->prev;
|
||||
if (elem->prev == list) ret = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get the first element */
|
||||
inline static struct list *list_head( struct list *list )
|
||||
{
|
||||
return list_next( list, list );
|
||||
}
|
||||
|
||||
/* get the last element */
|
||||
inline static struct list *list_tail( struct list *list )
|
||||
{
|
||||
return list_prev( list, list );
|
||||
}
|
||||
|
||||
/* initialize a list */
|
||||
inline static void list_init( struct list *list )
|
||||
{
|
||||
|
@ -2004,3 +2004,50 @@ enum message_type
|
||||
#define SET_CARET_POS 0x01 /* set the caret position from x,y */
|
||||
#define SET_CARET_HIDE 0x02 /* increment the caret hide count */
|
||||
#define SET_CARET_STATE 0x04 /* set the caret on/off state */
|
||||
|
||||
|
||||
/* Set a window hook */
|
||||
@REQ(set_hook)
|
||||
int id; /* id of the hook */
|
||||
thread_id_t tid; /* id of thread to set the hook into */
|
||||
void* proc; /* hook procedure */
|
||||
int unicode; /* is it a unicode hook? */
|
||||
@REPLY
|
||||
user_handle_t handle; /* handle to the hook */
|
||||
@END
|
||||
|
||||
|
||||
/* Remove a window hook */
|
||||
@REQ(remove_hook)
|
||||
user_handle_t handle; /* handle to the hook */
|
||||
int id; /* id of the hook if handle is 0 */
|
||||
void* proc; /* hook procedure if handle is 0 */
|
||||
@END
|
||||
|
||||
|
||||
/* Start calling a hook chain */
|
||||
@REQ(start_hook_chain)
|
||||
int id; /* id of the hook */
|
||||
@REPLY
|
||||
user_handle_t handle; /* handle to the next hook */
|
||||
void* proc; /* hook procedure */
|
||||
int unicode; /* is it a unicode hook? */
|
||||
@END
|
||||
|
||||
|
||||
/* Finished calling a hook chain */
|
||||
@REQ(finish_hook_chain)
|
||||
int id; /* id of the hook */
|
||||
@END
|
||||
|
||||
|
||||
/* Get the next hook to call */
|
||||
@REQ(get_next_hook)
|
||||
user_handle_t handle; /* handle to the current hook */
|
||||
@REPLY
|
||||
user_handle_t next; /* handle to the next hook */
|
||||
int id; /* id of the next hook */
|
||||
void* proc; /* next hook procedure */
|
||||
int prev_unicode; /* was the previous a unicode hook? */
|
||||
int next_unicode; /* is the next a unicode hook? */
|
||||
@END
|
||||
|
@ -267,6 +267,11 @@ DECL_HANDLER(set_active_window);
|
||||
DECL_HANDLER(set_capture_window);
|
||||
DECL_HANDLER(set_caret_window);
|
||||
DECL_HANDLER(set_caret_info);
|
||||
DECL_HANDLER(set_hook);
|
||||
DECL_HANDLER(remove_hook);
|
||||
DECL_HANDLER(start_hook_chain);
|
||||
DECL_HANDLER(finish_hook_chain);
|
||||
DECL_HANDLER(get_next_hook);
|
||||
|
||||
#ifdef WANT_REQUEST_HANDLERS
|
||||
|
||||
@ -437,6 +442,11 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
||||
(req_handler)req_set_capture_window,
|
||||
(req_handler)req_set_caret_window,
|
||||
(req_handler)req_set_caret_info,
|
||||
(req_handler)req_set_hook,
|
||||
(req_handler)req_remove_hook,
|
||||
(req_handler)req_start_hook_chain,
|
||||
(req_handler)req_finish_hook_chain,
|
||||
(req_handler)req_get_next_hook,
|
||||
};
|
||||
#endif /* WANT_REQUEST_HANDLERS */
|
||||
|
||||
|
@ -110,6 +110,7 @@ inline static void init_thread_structure( struct thread *thread )
|
||||
thread->debug_ctx = NULL;
|
||||
thread->debug_event = NULL;
|
||||
thread->queue = NULL;
|
||||
thread->hooks = NULL;
|
||||
thread->info = NULL;
|
||||
thread->wait = NULL;
|
||||
thread->system_apc.head = NULL;
|
||||
@ -187,6 +188,7 @@ static void cleanup_thread( struct thread *thread )
|
||||
if (thread->request_fd != -1) close( thread->request_fd );
|
||||
if (thread->reply_fd != -1) close( thread->reply_fd );
|
||||
if (thread->wait_fd != -1) close( thread->wait_fd );
|
||||
if (thread->hooks) release_object( thread->hooks );
|
||||
free_msg_queue( thread );
|
||||
destroy_thread_windows( thread );
|
||||
for (i = 0; i < MAX_INFLIGHT_FDS; i++)
|
||||
@ -202,6 +204,7 @@ static void cleanup_thread( struct thread *thread )
|
||||
thread->request_fd = -1;
|
||||
thread->reply_fd = -1;
|
||||
thread->wait_fd = -1;
|
||||
thread->hooks = NULL;
|
||||
|
||||
if (thread == booting_thread) /* killing booting thread */
|
||||
{
|
||||
|
@ -33,6 +33,7 @@ struct debug_ctx;
|
||||
struct debug_event;
|
||||
struct startup_info;
|
||||
struct msg_queue;
|
||||
struct hook_table;
|
||||
|
||||
enum run_state
|
||||
{
|
||||
@ -66,6 +67,7 @@ struct thread
|
||||
struct debug_ctx *debug_ctx; /* debugger context if this thread is a debugger */
|
||||
struct debug_event *debug_event; /* debug event being sent to debugger */
|
||||
struct msg_queue *queue; /* message queue */
|
||||
struct hook_table *hooks; /* hooks table */
|
||||
struct startup_info *info; /* startup info for child process */
|
||||
struct thread_wait *wait; /* current wait condition if sleeping */
|
||||
struct apc_queue system_apc; /* queue of system async procedure calls */
|
||||
|
@ -2282,6 +2282,57 @@ static void dump_set_caret_info_reply( const struct set_caret_info_reply *req )
|
||||
fprintf( stderr, " old_state=%d", req->old_state );
|
||||
}
|
||||
|
||||
static void dump_set_hook_request( const struct set_hook_request *req )
|
||||
{
|
||||
fprintf( stderr, " id=%d,", req->id );
|
||||
fprintf( stderr, " tid=%08x,", req->tid );
|
||||
fprintf( stderr, " proc=%p,", req->proc );
|
||||
fprintf( stderr, " unicode=%d", req->unicode );
|
||||
}
|
||||
|
||||
static void dump_set_hook_reply( const struct set_hook_reply *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p", req->handle );
|
||||
}
|
||||
|
||||
static void dump_remove_hook_request( const struct remove_hook_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p,", req->handle );
|
||||
fprintf( stderr, " id=%d,", req->id );
|
||||
fprintf( stderr, " proc=%p", req->proc );
|
||||
}
|
||||
|
||||
static void dump_start_hook_chain_request( const struct start_hook_chain_request *req )
|
||||
{
|
||||
fprintf( stderr, " id=%d", req->id );
|
||||
}
|
||||
|
||||
static void dump_start_hook_chain_reply( const struct start_hook_chain_reply *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p,", req->handle );
|
||||
fprintf( stderr, " proc=%p,", req->proc );
|
||||
fprintf( stderr, " unicode=%d", req->unicode );
|
||||
}
|
||||
|
||||
static void dump_finish_hook_chain_request( const struct finish_hook_chain_request *req )
|
||||
{
|
||||
fprintf( stderr, " id=%d", req->id );
|
||||
}
|
||||
|
||||
static void dump_get_next_hook_request( const struct get_next_hook_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p", req->handle );
|
||||
}
|
||||
|
||||
static void dump_get_next_hook_reply( const struct get_next_hook_reply *req )
|
||||
{
|
||||
fprintf( stderr, " next=%p,", req->next );
|
||||
fprintf( stderr, " id=%d,", req->id );
|
||||
fprintf( stderr, " proc=%p,", req->proc );
|
||||
fprintf( stderr, " prev_unicode=%d,", req->prev_unicode );
|
||||
fprintf( stderr, " next_unicode=%d", req->next_unicode );
|
||||
}
|
||||
|
||||
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_new_process_request,
|
||||
(dump_func)dump_get_new_process_info_request,
|
||||
@ -2447,6 +2498,11 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_set_capture_window_request,
|
||||
(dump_func)dump_set_caret_window_request,
|
||||
(dump_func)dump_set_caret_info_request,
|
||||
(dump_func)dump_set_hook_request,
|
||||
(dump_func)dump_remove_hook_request,
|
||||
(dump_func)dump_start_hook_chain_request,
|
||||
(dump_func)dump_finish_hook_chain_request,
|
||||
(dump_func)dump_get_next_hook_request,
|
||||
};
|
||||
|
||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
@ -2614,6 +2670,11 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_set_capture_window_reply,
|
||||
(dump_func)dump_set_caret_window_reply,
|
||||
(dump_func)dump_set_caret_info_reply,
|
||||
(dump_func)dump_set_hook_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_start_hook_chain_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_get_next_hook_reply,
|
||||
};
|
||||
|
||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
@ -2781,6 +2842,11 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
"set_capture_window",
|
||||
"set_caret_window",
|
||||
"set_caret_info",
|
||||
"set_hook",
|
||||
"remove_hook",
|
||||
"start_hook_chain",
|
||||
"finish_hook_chain",
|
||||
"get_next_hook",
|
||||
};
|
||||
|
||||
/* ### make_requests end ### */
|
||||
|
@ -29,7 +29,8 @@ struct msg_queue;
|
||||
|
||||
enum user_object
|
||||
{
|
||||
USER_WINDOW = 1
|
||||
USER_WINDOW = 1,
|
||||
USER_HOOK
|
||||
};
|
||||
|
||||
/* user handles functions */
|
||||
|
1236
windows/hook.c
1236
windows/hook.c
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,6 @@
|
||||
#include "wine/winuser16.h"
|
||||
#include "wine/server.h"
|
||||
#include "win.h"
|
||||
#include "hook.h"
|
||||
#include "input.h"
|
||||
#include "message.h"
|
||||
#include "queue.h"
|
||||
@ -181,7 +180,7 @@ static void queue_kbd_event( const KEYBDINPUT *ki, UINT injected_flags )
|
||||
hook.flags = (keylp.lp2 >> 24) | injected_flags;
|
||||
hook.time = ki->time;
|
||||
hook.dwExtraInfo = ki->dwExtraInfo;
|
||||
if (!HOOK_CallHooksW( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook ))
|
||||
if (!HOOK_CallHooks( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook, TRUE ))
|
||||
queue_raw_hardware_message( message, ki->wVk, keylp.lp2,
|
||||
PosX, PosY, ki->time, ki->dwExtraInfo );
|
||||
}
|
||||
@ -201,7 +200,7 @@ static void queue_raw_mouse_message( UINT message, UINT flags, INT x, INT y, con
|
||||
hook.time = mi->time;
|
||||
hook.dwExtraInfo = mi->dwExtraInfo;
|
||||
|
||||
if (!HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook ))
|
||||
if (!HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook, TRUE ))
|
||||
queue_raw_hardware_message( message, MAKEWPARAM( get_key_state(), mi->mouseData ),
|
||||
0, x, y, mi->time, mi->dwExtraInfo );
|
||||
}
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "wine/server.h"
|
||||
#include "win.h"
|
||||
#include "heap.h"
|
||||
#include "hook.h"
|
||||
#include "input.h"
|
||||
#include "spy.h"
|
||||
#include "winpos.h"
|
||||
@ -230,6 +229,8 @@ static void MSG_SendParentNotify( HWND hwnd, WORD event, WORD idChild, POINT pt
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* this is broken for now, will require proper support in the server */
|
||||
|
||||
/***********************************************************************
|
||||
* MSG_JournalPlayBackMsg
|
||||
*
|
||||
@ -242,9 +243,7 @@ void MSG_JournalPlayBackMsg(void)
|
||||
LRESULT wtime;
|
||||
int keyDown,i;
|
||||
|
||||
if (!HOOK_IsHooked( WH_JOURNALPLAYBACK )) return;
|
||||
|
||||
wtime=HOOK_CallHooksA( WH_JOURNALPLAYBACK, HC_GETNEXT, 0, (LPARAM)&tmpMsg );
|
||||
wtime=HOOK_CallHooks( WH_JOURNALPLAYBACK, HC_GETNEXT, 0, (LPARAM)&tmpMsg, TRUE );
|
||||
/* TRACE(msg,"Playback wait time =%ld\n",wtime); */
|
||||
if (wtime<=0)
|
||||
{
|
||||
@ -316,15 +315,14 @@ void MSG_JournalPlayBackMsg(void)
|
||||
msg.pt.y = tmpMsg.paramH;
|
||||
queue_hardware_message( &msg, 0, MSG_HARDWARE_RAW );
|
||||
}
|
||||
HOOK_CallHooksA( WH_JOURNALPLAYBACK, HC_SKIP, 0, (LPARAM)&tmpMsg);
|
||||
HOOK_CallHooks( WH_JOURNALPLAYBACK, HC_SKIP, 0, (LPARAM)&tmpMsg, TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( tmpMsg.message == WM_QUEUESYNC )
|
||||
if (HOOK_IsHooked( WH_CBT ))
|
||||
HOOK_CallHooksA( WH_CBT, HCBT_QS, 0, 0L);
|
||||
if( tmpMsg.message == WM_QUEUESYNC ) HOOK_CallHooks( WH_CBT, HCBT_QS, 0, 0, TRUE );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
@ -334,6 +332,8 @@ void MSG_JournalPlayBackMsg(void)
|
||||
*/
|
||||
static BOOL process_raw_keyboard_message( MSG *msg, ULONG_PTR extra_info )
|
||||
{
|
||||
EVENTMSG event;
|
||||
|
||||
if (!(msg->hwnd = GetFocus()))
|
||||
{
|
||||
/* Send the message to the active window instead, */
|
||||
@ -342,18 +342,13 @@ static BOOL process_raw_keyboard_message( MSG *msg, ULONG_PTR extra_info )
|
||||
if (msg->message < WM_SYSKEYDOWN) msg->message += WM_SYSKEYDOWN - WM_KEYDOWN;
|
||||
}
|
||||
|
||||
if (HOOK_IsHooked( WH_JOURNALRECORD ))
|
||||
{
|
||||
EVENTMSG event;
|
||||
|
||||
event.message = msg->message;
|
||||
event.hwnd = msg->hwnd;
|
||||
event.time = msg->time;
|
||||
event.paramL = (msg->wParam & 0xFF) | (HIWORD(msg->lParam) << 8);
|
||||
event.paramH = msg->lParam & 0x7FFF;
|
||||
if (HIWORD(msg->lParam) & 0x0100) event.paramH |= 0x8000; /* special_key - bit */
|
||||
HOOK_CallHooksA( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event );
|
||||
}
|
||||
event.message = msg->message;
|
||||
event.hwnd = msg->hwnd;
|
||||
event.time = msg->time;
|
||||
event.paramL = (msg->wParam & 0xFF) | (HIWORD(msg->lParam) << 8);
|
||||
event.paramH = msg->lParam & 0x7FFF;
|
||||
if (HIWORD(msg->lParam) & 0x0100) event.paramH |= 0x8000; /* special_key - bit */
|
||||
HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE );
|
||||
|
||||
/* if we are going to throw away the message, update the queue state now */
|
||||
if (!msg->hwnd) update_queue_key_state( msg->message, msg->wParam, msg->lParam );
|
||||
@ -390,11 +385,11 @@ static BOOL process_cooked_keyboard_message( MSG *msg, BOOL remove )
|
||||
}
|
||||
}
|
||||
|
||||
if (HOOK_CallHooksA( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
|
||||
LOWORD(msg->wParam), msg->lParam ))
|
||||
if (HOOK_CallHooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
|
||||
LOWORD(msg->wParam), msg->lParam, TRUE ))
|
||||
{
|
||||
/* skip this message */
|
||||
HOOK_CallHooksA( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam );
|
||||
HOOK_CallHooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam, TRUE );
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@ -412,6 +407,7 @@ static BOOL process_raw_mouse_message( MSG *msg, ULONG_PTR extra_info )
|
||||
|
||||
POINT pt;
|
||||
INT hittest;
|
||||
EVENTMSG event;
|
||||
GUITHREADINFO info;
|
||||
|
||||
/* find the window to dispatch this mouse message to */
|
||||
@ -429,16 +425,12 @@ static BOOL process_raw_mouse_message( MSG *msg, ULONG_PTR extra_info )
|
||||
msg->hwnd = GetDesktopWindow();
|
||||
}
|
||||
|
||||
if (HOOK_IsHooked( WH_JOURNALRECORD ))
|
||||
{
|
||||
EVENTMSG event;
|
||||
event.message = msg->message;
|
||||
event.time = msg->time;
|
||||
event.hwnd = msg->hwnd;
|
||||
event.paramL = msg->pt.x;
|
||||
event.paramH = msg->pt.y;
|
||||
HOOK_CallHooksA( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event );
|
||||
}
|
||||
event.message = msg->message;
|
||||
event.time = msg->time;
|
||||
event.hwnd = msg->hwnd;
|
||||
event.paramL = msg->pt.x;
|
||||
event.paramH = msg->pt.y;
|
||||
HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE );
|
||||
|
||||
/* translate double clicks */
|
||||
|
||||
@ -495,6 +487,7 @@ static BOOL process_raw_mouse_message( MSG *msg, ULONG_PTR extra_info )
|
||||
*/
|
||||
static BOOL process_cooked_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL remove )
|
||||
{
|
||||
MOUSEHOOKSTRUCT hook;
|
||||
INT hittest = HTCLIENT;
|
||||
UINT raw_message = msg->message;
|
||||
BOOL eatMsg;
|
||||
@ -513,23 +506,19 @@ static BOOL process_cooked_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL r
|
||||
|
||||
if (remove) update_queue_key_state( raw_message, 0, 0 );
|
||||
|
||||
if (HOOK_IsHooked( WH_MOUSE ))
|
||||
hook.pt = msg->pt;
|
||||
hook.hwnd = msg->hwnd;
|
||||
hook.wHitTestCode = hittest;
|
||||
hook.dwExtraInfo = extra_info;
|
||||
if (HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
|
||||
msg->message, (LPARAM)&hook, TRUE ))
|
||||
{
|
||||
MOUSEHOOKSTRUCT hook;
|
||||
hook.pt = msg->pt;
|
||||
hook.hwnd = msg->hwnd;
|
||||
hook.wHitTestCode = hittest;
|
||||
hook.dwExtraInfo = extra_info;
|
||||
if (HOOK_CallHooksA( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
|
||||
msg->message, (LPARAM)&hook ))
|
||||
{
|
||||
hook.pt = msg->pt;
|
||||
hook.hwnd = msg->hwnd;
|
||||
hook.wHitTestCode = hittest;
|
||||
hook.dwExtraInfo = extra_info;
|
||||
HOOK_CallHooksA( WH_CBT, HCBT_CLICKSKIPPED, msg->message, (LPARAM)&hook );
|
||||
return FALSE;
|
||||
}
|
||||
HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, msg->message, (LPARAM)&hook, TRUE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((hittest == HTERROR) || (hittest == HTNOWHERE))
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "controls.h"
|
||||
#include "cursoricon.h"
|
||||
#include "winpos.h"
|
||||
#include "hook.h"
|
||||
#include "nonclient.h"
|
||||
#include "wine/debug.h"
|
||||
#include "shellapi.h"
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "queue.h"
|
||||
#include "win.h"
|
||||
#include "user.h"
|
||||
#include "hook.h"
|
||||
#include "thread.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/server.h"
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "win.h"
|
||||
#include "controls.h"
|
||||
#include "cursoricon.h"
|
||||
#include "hook.h"
|
||||
#include "message.h"
|
||||
#include "miscemu.h"
|
||||
#include "sysmetrics.h"
|
||||
@ -140,7 +139,7 @@ void USER_CheckNotLock(void)
|
||||
*/
|
||||
static void USER_ModuleUnload( HMODULE16 hModule )
|
||||
{
|
||||
HOOK_FreeModuleHooks( hModule );
|
||||
/* HOOK_FreeModuleHooks( hModule ); */
|
||||
CLASS_FreeModuleClasses( hModule );
|
||||
CURSORICON_FreeModuleIcons( hModule );
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "dce.h"
|
||||
#include "controls.h"
|
||||
#include "cursoricon.h"
|
||||
#include "hook.h"
|
||||
#include "message.h"
|
||||
#include "queue.h"
|
||||
#include "winpos.h"
|
||||
@ -1188,7 +1187,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
|
||||
/* Call WH_SHELL hook */
|
||||
|
||||
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) && !GetWindow( hwnd, GW_OWNER ))
|
||||
HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0 );
|
||||
HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0, TRUE );
|
||||
|
||||
TRACE("created window %04x\n", hwnd);
|
||||
return hwnd;
|
||||
@ -1457,7 +1456,7 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
|
||||
|
||||
/* Call hooks */
|
||||
|
||||
if( HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0L) ) return FALSE;
|
||||
if (HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0, TRUE )) return FALSE;
|
||||
|
||||
is_child = (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) != 0;
|
||||
|
||||
@ -1468,7 +1467,7 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
|
||||
}
|
||||
else if (!GetWindow( hwnd, GW_OWNER ))
|
||||
{
|
||||
HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L );
|
||||
HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
|
||||
/* FIXME: clean up palette - see "Internals" p.352 */
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user