Commit fcf7d2a1 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move NtUserSetWindowsHookEx implementation from user32.

parent 01b36742
......@@ -140,73 +140,28 @@ static UINT get_ll_hook_timeout(void)
*
* Implementation of SetWindowsHookExA and SetWindowsHookExW.
*/
static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL unicode )
static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid, BOOL ansi )
{
HHOOK handle = 0;
WCHAR module[MAX_PATH];
DWORD len;
UNICODE_STRING str;
if (!proc)
if (!inst)
{
SetLastError( ERROR_INVALID_FILTER_PROC );
return 0;
RtlInitUnicodeString( &str, NULL );
}
if (tid) /* thread-local hook */
else
{
if (id == WH_JOURNALRECORD ||
id == WH_JOURNALPLAYBACK ||
id == WH_KEYBOARD_LL ||
id == WH_MOUSE_LL ||
id == WH_SYSMSGFILTER)
size_t len = GetModuleFileNameW( inst, module, ARRAYSIZE(module) );
if (!len || len >= ARRAYSIZE(module))
{
/* these can only be global */
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
str.Buffer = module;
str.MaximumLength = str.Length = len * sizeof(WCHAR);
}
else /* system-global hook */
{
if (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0;
else if (!inst)
{
SetLastError( ERROR_HOOK_NEEDS_HMOD );
return 0;
}
}
if (inst && (!(len = GetModuleFileNameW( inst, module, MAX_PATH )) || len >= MAX_PATH))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
SERVER_START_REQ( set_hook )
{
req->id = id;
req->pid = 0;
req->tid = tid;
req->event_min = EVENT_MIN;
req->event_max = EVENT_MAX;
req->flags = WINEVENT_INCONTEXT;
req->unicode = unicode;
if (inst) /* make proc relative to the module base */
{
req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) );
wine_server_add_data( req, module, lstrlenW(module) * sizeof(WCHAR) );
}
else req->proc = wine_server_client_ptr( proc );
if (!wine_server_call_err( req ))
{
handle = wine_server_ptr_handle( reply->handle );
get_user_thread_info()->active_hooks = reply->active_hooks;
}
}
SERVER_END_REQ;
TRACE( "%s %p %x -> %p\n", hook_names[id-WH_MINHOOK], proc, tid, handle );
return handle;
return NtUserSetWindowsHookEx( inst, &str, tid, id, proc, ansi );
}
#ifdef __i386__
......@@ -548,7 +503,7 @@ HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
*/
HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid )
{
return set_windows_hook( id, proc, inst, tid, FALSE );
return set_windows_hook( id, proc, inst, tid, TRUE );
}
/***********************************************************************
......@@ -556,7 +511,7 @@ HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid
*/
HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid )
{
return set_windows_hook( id, proc, inst, tid, TRUE );
return set_windows_hook( id, proc, inst, tid, FALSE );
}
......
......@@ -32,6 +32,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(hook);
#define WH_WINEVENT (WH_MAXHOOK+1)
static const char * const hook_names[WH_WINEVENT - 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",
"WH_WINEVENT"
};
static BOOL is_hooked( INT id )
{
......@@ -42,6 +62,71 @@ static BOOL is_hooked( INT id )
}
/***********************************************************************
* NtUserSetWindowsHookEx (win32u.@)
*/
HHOOK WINAPI NtUserSetWindowsHookEx( HINSTANCE inst, UNICODE_STRING *module, DWORD tid, INT id,
HOOKPROC proc, BOOL ansi )
{
HHOOK handle = 0;
if (!proc)
{
SetLastError( ERROR_INVALID_FILTER_PROC );
return 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 (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0;
else if (!inst)
{
SetLastError( ERROR_HOOK_NEEDS_HMOD );
return 0;
}
}
SERVER_START_REQ( set_hook )
{
req->id = id;
req->pid = 0;
req->tid = tid;
req->event_min = EVENT_MIN;
req->event_max = EVENT_MAX;
req->flags = WINEVENT_INCONTEXT;
req->unicode = !ansi;
if (inst) /* make proc relative to the module base */
{
req->proc = wine_server_client_ptr( (void *)((char *)proc - (char *)inst) );
wine_server_add_data( req, module->Buffer, module->Length );
}
else req->proc = wine_server_client_ptr( proc );
if (!wine_server_call_err( req ))
{
handle = wine_server_ptr_handle( reply->handle );
get_user_thread_info()->active_hooks = reply->active_hooks;
}
}
SERVER_END_REQ;
TRACE( "%s %p %x -> %p\n", hook_names[id - WH_MINHOOK], proc, tid, handle );
return handle;
}
/***********************************************************************
* NtUserSetWinEventHook (win32u.@)
*/
HWINEVENTHOOK WINAPI NtUserSetWinEventHook( DWORD event_min, DWORD event_max, HMODULE inst,
......
......@@ -141,6 +141,7 @@ static void * const syscalls[] =
NtUserSetProp,
NtUserSetThreadDesktop,
NtUserSetWinEventHook,
NtUserSetWindowsHookEx,
NtUserUnhookWinEvent,
};
......
......@@ -1256,7 +1256,7 @@
@ stub NtUserSetWindowStationUser
@ stub NtUserSetWindowWord
@ stub NtUserSetWindowsHookAW
@ stub NtUserSetWindowsHookEx
@ stdcall -syscall NtUserSetWindowsHookEx(ptr ptr long long ptr long)
@ stub NtUserShowCaret
@ stdcall NtUserShowCursor(long)
@ stub NtUserShowScrollBar
......
......@@ -128,6 +128,7 @@
SYSCALL_ENTRY( NtUserSetProp ) \
SYSCALL_ENTRY( NtUserSetThreadDesktop ) \
SYSCALL_ENTRY( NtUserSetWinEventHook ) \
SYSCALL_ENTRY( NtUserSetWindowsHookEx ) \
SYSCALL_ENTRY( NtUserUnhookWinEvent )
#endif /* __WOW64WIN_SYSCALL_H */
......@@ -392,3 +392,19 @@ NTSTATUS WINAPI wow64_NtUserUnhookWinEvent( UINT *args )
return NtUserUnhookWinEvent( handle );
}
NTSTATUS WINAPI wow64_NtUserSetWindowsHookEx( UINT *args )
{
HINSTANCE inst = get_handle( &args );
UNICODE_STRING32 *module32 = get_ptr( &args );
DWORD tid = get_ulong( &args );
INT id = get_ulong( &args );
HOOKPROC proc = get_ptr( &args );
BOOL ansi = get_ulong( &args );
UNICODE_STRING module;
HHOOK ret;
ret = NtUserSetWindowsHookEx( inst, unicode_str_32to64( &module, module32 ),
tid, id, proc, ansi );
return HandleToUlong( ret );
}
......@@ -193,6 +193,8 @@ BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle );
BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle );
BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *values );
BOOL WINAPI NtUserSetThreadDesktop( HDESK handle );
HHOOK WINAPI NtUserSetWindowsHookEx( HINSTANCE inst, UNICODE_STRING *module, DWORD tid, INT id,
HOOKPROC proc, BOOL ansi );
HWINEVENTHOOK WINAPI NtUserSetWinEventHook( DWORD event_min, DWORD event_max, HMODULE inst,
UNICODE_STRING *module, WINEVENTPROC proc,
DWORD pid, DWORD tid, DWORD flags );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment