win32u: Move NtUserNotifyWinEvent implementation from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d76b38ffb6
commit
01b3674247
|
@ -74,7 +74,7 @@ static HWND set_focus_window( HWND hwnd )
|
|||
SendMessageW( ime_default, WM_IME_INTERNAL, IME_INTERNAL_ACTIVATE, (LPARAM)hwnd );
|
||||
|
||||
if (previous)
|
||||
NotifyWinEvent( EVENT_OBJECT_FOCUS, hwnd, OBJID_CLIENT, 0 );
|
||||
NtUserNotifyWinEvent( EVENT_OBJECT_FOCUS, hwnd, OBJID_CLIENT, 0 );
|
||||
|
||||
SendMessageW( hwnd, WM_SETFOCUS, (WPARAM)previous, 0 );
|
||||
}
|
||||
|
|
|
@ -726,161 +726,30 @@ HWINEVENTHOOK WINAPI SetWinEventHook(DWORD event_min, DWORD event_max,
|
|||
return NtUserSetWinEventHook( event_min, event_max, inst, &str, proc, pid, tid, flags );
|
||||
}
|
||||
|
||||
static inline BOOL find_first_hook(DWORD id, DWORD event, HWND hwnd, LONG object_id,
|
||||
LONG child_id, struct hook_info *info)
|
||||
BOOL WINAPI User32CallWinEventHook( const struct win_hook_proc_params *params, ULONG size )
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
BOOL ret;
|
||||
WINEVENTPROC proc = params->proc;
|
||||
HMODULE free_module = 0;
|
||||
|
||||
if (!HOOK_IsHooked( id ))
|
||||
{
|
||||
TRACE( "skipping hook %s mask %x\n", hook_names[id-WH_MINHOOK], thread_info->active_hooks );
|
||||
return FALSE;
|
||||
}
|
||||
USER_CheckNotLock(); /* FIXME: move to NtUserNotifyWinEvent */
|
||||
|
||||
SERVER_START_REQ( start_hook_chain )
|
||||
{
|
||||
req->id = id;
|
||||
req->event = event;
|
||||
req->window = wine_server_user_handle( hwnd );
|
||||
req->object_id = object_id;
|
||||
req->child_id = child_id;
|
||||
wine_server_set_reply( req, info->module, sizeof(info->module)-sizeof(WCHAR) );
|
||||
ret = !wine_server_call( req );
|
||||
if (ret)
|
||||
{
|
||||
info->module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
|
||||
info->handle = wine_server_ptr_handle( reply->handle );
|
||||
info->proc = wine_server_get_ptr( reply->proc );
|
||||
info->tid = reply->tid;
|
||||
thread_info->active_hooks = reply->active_hooks;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret && (info->tid || info->proc);
|
||||
if (params->module[0] && !(proc = get_hook_proc( proc, params->module, &free_module ))) return FALSE;
|
||||
|
||||
TRACE_(relay)( "\1Call winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n",
|
||||
proc, params->handle, params->event, params->hwnd, params->object_id,
|
||||
params->child_id, GetCurrentThreadId(), GetCurrentTime() );
|
||||
|
||||
proc( params->handle, params->event, params->hwnd, params->object_id, params->child_id,
|
||||
GetCurrentThreadId(), GetCurrentTime() );
|
||||
|
||||
TRACE_(relay)( "\1Ret winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n",
|
||||
proc, params->handle, params->event, params->hwnd, params->object_id,
|
||||
params->child_id, GetCurrentThreadId(), GetCurrentTime() );
|
||||
|
||||
if (free_module) FreeLibrary( free_module );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline BOOL find_next_hook(DWORD event, HWND hwnd, LONG object_id,
|
||||
LONG child_id, struct hook_info *info)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
SERVER_START_REQ( get_hook_info )
|
||||
{
|
||||
req->handle = wine_server_user_handle( info->handle );
|
||||
req->get_next = 1;
|
||||
req->event = event;
|
||||
req->window = wine_server_user_handle( hwnd );
|
||||
req->object_id = object_id;
|
||||
req->child_id = child_id;
|
||||
wine_server_set_reply( req, info->module, sizeof(info->module)-sizeof(WCHAR) );
|
||||
ret = !wine_server_call( req );
|
||||
if (ret)
|
||||
{
|
||||
info->module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
|
||||
info->handle = wine_server_ptr_handle( reply->handle );
|
||||
info->proc = wine_server_get_ptr( reply->proc );
|
||||
info->tid = reply->tid;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void find_hook_close(DWORD id)
|
||||
{
|
||||
SERVER_START_REQ( finish_hook_chain )
|
||||
{
|
||||
req->id = id;
|
||||
wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NotifyWinEvent [USER32.@]
|
||||
*
|
||||
* Inform the OS that an event has occurred.
|
||||
*
|
||||
* PARAMS
|
||||
* event [I] Id of the event
|
||||
* hwnd [I] Window holding the object that created the event
|
||||
* object_id [I] Type of object that created the event
|
||||
* child_id [I] Child object of nId, or CHILDID_SELF.
|
||||
*
|
||||
* RETURNS
|
||||
* Nothing.
|
||||
*/
|
||||
void WINAPI NotifyWinEvent(DWORD event, HWND hwnd, LONG object_id, LONG child_id)
|
||||
{
|
||||
struct hook_info info;
|
||||
|
||||
TRACE("%04x,%p,%d,%d\n", event, hwnd, object_id, child_id);
|
||||
|
||||
if (!hwnd)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
USER_CheckNotLock();
|
||||
|
||||
#if 0
|
||||
if (event & 0x80000000)
|
||||
{
|
||||
/* FIXME: on 64-bit platforms we need to invent some other way for
|
||||
* passing parameters, nId and nChildId can't hold full [W|L]PARAM.
|
||||
* struct call_hook *hook = (LRESULT *)hWnd;
|
||||
* wparam = hook->wparam;
|
||||
* lparam = hook->lparam;
|
||||
*/
|
||||
LRESULT *ret = (LRESULT *)hwnd;
|
||||
INT id, code, unicode;
|
||||
|
||||
id = (dwEvent & 0x7fff0000) >> 16;
|
||||
code = event & 0x7fff;
|
||||
unicode = event & 0x8000;
|
||||
*ret = HOOK_CallHooks(id, code, object_id, child_id, unicode);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!find_first_hook(WH_WINEVENT, event, hwnd, object_id, child_id, &info)) return;
|
||||
|
||||
do
|
||||
{
|
||||
WINEVENTPROC proc = info.proc;
|
||||
if (proc)
|
||||
{
|
||||
HMODULE free_module = 0;
|
||||
TRACE( "calling WH_WINEVENT hook %p event %x hwnd %p %x %x module %s\n",
|
||||
proc, event, hwnd, object_id, child_id, debugstr_w(info.module) );
|
||||
|
||||
if (!info.module[0] || (proc = get_hook_proc( proc, info.module, &free_module )) != NULL)
|
||||
{
|
||||
TRACE_(relay)( "\1Call winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n",
|
||||
proc, info.handle, event, hwnd, object_id,
|
||||
child_id, GetCurrentThreadId(), GetCurrentTime());
|
||||
|
||||
proc( info.handle, event, hwnd, object_id, child_id,
|
||||
GetCurrentThreadId(), GetCurrentTime());
|
||||
|
||||
TRACE_(relay)( "\1Ret winevent hook proc %p (hhook=%p,event=%x,hwnd=%p,object_id=%x,child_id=%x,tid=%04x,time=%x)\n",
|
||||
proc, info.handle, event, hwnd, object_id,
|
||||
child_id, GetCurrentThreadId(), GetCurrentTime());
|
||||
|
||||
if (free_module) FreeLibrary(free_module);
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
while (find_next_hook(event, hwnd, object_id, child_id, &info));
|
||||
|
||||
find_hook_close(WH_WINEVENT);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* IsWinEventHookInstalled [USER32.@]
|
||||
*
|
||||
|
|
|
@ -545,7 +545,7 @@
|
|||
@ stdcall MoveWindow(long long long long long long)
|
||||
@ stdcall MsgWaitForMultipleObjects(long ptr long long long)
|
||||
@ stdcall MsgWaitForMultipleObjectsEx(long ptr long long long)
|
||||
@ stdcall NotifyWinEvent(long long long long)
|
||||
@ stdcall NotifyWinEvent(long long long long) NtUserNotifyWinEvent
|
||||
@ stdcall OemKeyScan(long)
|
||||
@ stdcall OemToCharA(str ptr)
|
||||
@ stdcall OemToCharBuffA(ptr ptr long)
|
||||
|
|
|
@ -212,6 +212,7 @@ static void dpiaware_init(void)
|
|||
static const void *kernel_callback_table[NtUserCallCount] =
|
||||
{
|
||||
User32CallEnumDisplayMonitor,
|
||||
User32CallWinEventHook,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -194,6 +194,7 @@ extern const WCHAR *CLASS_GetVersionedName(const WCHAR *classname, UINT *basenam
|
|||
/* kernel callbacks */
|
||||
|
||||
BOOL WINAPI User32CallEnumDisplayMonitor( struct enum_display_monitor_params *params, ULONG size );
|
||||
BOOL WINAPI User32CallWinEventHook( const struct win_hook_proc_params *params, ULONG size );
|
||||
|
||||
/* message spy definitions */
|
||||
|
||||
|
|
|
@ -1777,7 +1777,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
|
|||
|
||||
if (!USER_Driver->pCreateWindow( hwnd )) goto failed;
|
||||
|
||||
NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0);
|
||||
NtUserNotifyWinEvent( EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0 );
|
||||
|
||||
/* send the size messages */
|
||||
|
||||
|
|
|
@ -33,6 +33,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(hook);
|
|||
#define WH_WINEVENT (WH_MAXHOOK+1)
|
||||
|
||||
|
||||
static BOOL is_hooked( INT id )
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
|
||||
if (!thread_info->active_hooks) return TRUE;
|
||||
return (thread_info->active_hooks & (1 << (id - WH_MINHOOK))) != 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserSetWinEventHook (win32u.@)
|
||||
*/
|
||||
|
@ -102,3 +110,91 @@ BOOL WINAPI NtUserUnhookWinEvent( HWINEVENTHOOK handle )
|
|||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserNotifyWinEvent (win32u.@)
|
||||
*/
|
||||
void WINAPI NtUserNotifyWinEvent( DWORD event, HWND hwnd, LONG object_id, LONG child_id )
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
struct win_hook_proc_params info;
|
||||
void *ret_ptr;
|
||||
ULONG ret_len;
|
||||
BOOL ret;
|
||||
|
||||
TRACE( "%04x, %p, %d, %d\n", event, hwnd, object_id, child_id );
|
||||
|
||||
if (!hwnd)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_hooked( WH_WINEVENT ))
|
||||
{
|
||||
TRACE( "skipping hook mask %x\n", thread_info->active_hooks );
|
||||
return;
|
||||
}
|
||||
|
||||
info.event = event;
|
||||
info.hwnd = hwnd;
|
||||
info.object_id = object_id;
|
||||
info.child_id = child_id;
|
||||
|
||||
SERVER_START_REQ( start_hook_chain )
|
||||
{
|
||||
req->id = WH_WINEVENT;
|
||||
req->event = event;
|
||||
req->window = wine_server_user_handle( hwnd );
|
||||
req->object_id = object_id;
|
||||
req->child_id = child_id;
|
||||
wine_server_set_reply( req, info.module, sizeof(info.module) - sizeof(WCHAR) );
|
||||
ret = !wine_server_call( req ) && reply->proc;
|
||||
if (ret)
|
||||
{
|
||||
info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
|
||||
info.handle = wine_server_ptr_handle( reply->handle );
|
||||
info.proc = wine_server_get_ptr( reply->proc );
|
||||
thread_info->active_hooks = reply->active_hooks;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!ret) return;
|
||||
|
||||
do
|
||||
{
|
||||
TRACE( "calling WH_WINEVENT hook %p event %x hwnd %p %x %x module %s\n",
|
||||
info.proc, event, hwnd, object_id, child_id, debugstr_w(info.module) );
|
||||
|
||||
KeUserModeCallback( NtUserCallWinEventHook, &info,
|
||||
FIELD_OFFSET( struct win_hook_proc_params, module[lstrlenW(info.module) + 1] ),
|
||||
&ret_ptr, &ret_len );
|
||||
|
||||
SERVER_START_REQ( get_hook_info )
|
||||
{
|
||||
req->handle = wine_server_user_handle( info.handle );
|
||||
req->get_next = 1;
|
||||
req->event = event;
|
||||
req->window = wine_server_user_handle( hwnd );
|
||||
req->object_id = object_id;
|
||||
req->child_id = child_id;
|
||||
wine_server_set_reply( req, info.module, sizeof(info.module) - sizeof(WCHAR) );
|
||||
ret = !wine_server_call( req ) && reply->proc;
|
||||
if (ret)
|
||||
{
|
||||
info.module[wine_server_reply_size(req) / sizeof(WCHAR)] = 0;
|
||||
info.handle = wine_server_ptr_handle( reply->handle );
|
||||
info.proc = wine_server_get_ptr( reply->proc );
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
while (ret);
|
||||
|
||||
SERVER_START_REQ( finish_hook_chain )
|
||||
{
|
||||
req->id = WH_WINEVENT;
|
||||
wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
|
|
@ -128,6 +128,7 @@ static void * const syscalls[] =
|
|||
NtUserGetProp,
|
||||
NtUserGetSystemDpiForProcess,
|
||||
NtUserGetThreadDesktop,
|
||||
NtUserNotifyWinEvent,
|
||||
NtUserOpenDesktop,
|
||||
NtUserOpenInputDesktop,
|
||||
NtUserOpenWindowStation,
|
||||
|
|
|
@ -1089,7 +1089,7 @@
|
|||
@ stub NtUserNavigateFocus
|
||||
@ stub NtUserNotifyIMEStatus
|
||||
@ stub NtUserNotifyProcessCreate
|
||||
@ stub NtUserNotifyWinEvent
|
||||
@ stdcall -syscall NtUserNotifyWinEvent(long long long long)
|
||||
@ stub NtUserOpenClipboard
|
||||
@ stdcall -syscall NtUserOpenDesktop(ptr long long)
|
||||
@ stdcall -syscall NtUserOpenInputDesktop(long long long)
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
SYSCALL_ENTRY( NtUserGetProp ) \
|
||||
SYSCALL_ENTRY( NtUserGetSystemDpiForProcess ) \
|
||||
SYSCALL_ENTRY( NtUserGetThreadDesktop ) \
|
||||
SYSCALL_ENTRY( NtUserNotifyWinEvent ) \
|
||||
SYSCALL_ENTRY( NtUserOpenDesktop ) \
|
||||
SYSCALL_ENTRY( NtUserOpenInputDesktop ) \
|
||||
SYSCALL_ENTRY( NtUserOpenWindowStation ) \
|
||||
|
|
|
@ -356,6 +356,17 @@ NTSTATUS WINAPI wow64_NtUserGetDoubleClickTime( UINT *args )
|
|||
return NtUserGetDoubleClickTime();
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserNotifyWinEvent( UINT *args )
|
||||
{
|
||||
DWORD event = get_ulong( &args );
|
||||
HWND hwnd = get_handle( &args );
|
||||
LONG object_id = get_ulong( &args );
|
||||
LONG child_id = get_ulong( &args );
|
||||
|
||||
NtUserNotifyWinEvent( event, hwnd, object_id, child_id );
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserSetWinEventHook( UINT *args )
|
||||
{
|
||||
DWORD event_min = get_ulong( &args );
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
enum
|
||||
{
|
||||
NtUserCallEnumDisplayMonitor,
|
||||
NtUserCallWinEventHook,
|
||||
NtUserCallVulkanDebugReportCallback,
|
||||
NtUserCallVulkanDebugUtilsCallback,
|
||||
NtUserCallCount
|
||||
|
@ -42,6 +43,18 @@ struct enum_display_monitor_params
|
|||
LPARAM lparam;
|
||||
};
|
||||
|
||||
/* NtUserCallWinEventHook params */
|
||||
struct win_hook_proc_params
|
||||
{
|
||||
DWORD event;
|
||||
HWND hwnd;
|
||||
LONG object_id;
|
||||
LONG child_id;
|
||||
void *handle;
|
||||
WINEVENTPROC proc;
|
||||
WCHAR module[MAX_PATH];
|
||||
};
|
||||
|
||||
/* process DPI awareness contexts */
|
||||
#define NTUSER_DPI_UNAWARE 0x00006010
|
||||
#define NTUSER_DPI_SYSTEM_AWARE 0x00006011
|
||||
|
@ -163,6 +176,7 @@ HDESK WINAPI NtUserGetThreadDesktop( DWORD thread );
|
|||
BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size );
|
||||
BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format );
|
||||
UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout );
|
||||
void WINAPI NtUserNotifyWinEvent( DWORD event, HWND hwnd, LONG object_id, LONG child_id );
|
||||
HWINSTA WINAPI NtUserOpenWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK access );
|
||||
BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DWORD len );
|
||||
HDESK WINAPI NtUserOpenDesktop( OBJECT_ATTRIBUTES *attr, DWORD flags, ACCESS_MASK access );
|
||||
|
|
Loading…
Reference in New Issue