mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
Present for GreatLord:
Implement WH_KEYBOARD_LL hook svn path=/trunk/; revision=15281
This commit is contained in:
parent
f326ceb70f
commit
c1557a2be1
9 changed files with 206 additions and 43 deletions
|
@ -281,6 +281,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra;
|
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra;
|
||||||
WPARAM wParam;
|
WPARAM wParam;
|
||||||
LPARAM lParam;
|
LPARAM lParam;
|
||||||
|
KBDLLHOOKSTRUCT *KeyboardLlData;
|
||||||
|
|
||||||
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
|
Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
|
||||||
|
|
||||||
|
@ -353,6 +354,10 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case WH_KEYBOARD_LL:
|
||||||
|
KeyboardLlData = (KBDLLHOOKSTRUCT *)((PCHAR) Common + Common->lParam);
|
||||||
|
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) KeyboardLlData);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
|
return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ typedef struct _USER_SENT_MESSAGE
|
||||||
ULONG_PTR CompletionCallbackContext;
|
ULONG_PTR CompletionCallbackContext;
|
||||||
/* entry in the dispatching list of the sender's message queue */
|
/* entry in the dispatching list of the sender's message queue */
|
||||||
LIST_ENTRY DispatchingListEntry;
|
LIST_ENTRY DispatchingListEntry;
|
||||||
|
BOOL HookMessage;
|
||||||
} USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
|
} USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
|
||||||
|
|
||||||
typedef struct _USER_SENT_MESSAGE_NOTIFY
|
typedef struct _USER_SENT_MESSAGE_NOTIFY
|
||||||
|
@ -127,7 +128,8 @@ MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue);
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
|
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
|
||||||
UINT uTimeout, BOOL Block, ULONG_PTR *uResult);
|
UINT uTimeout, BOOL Block, BOOL HookMessage,
|
||||||
|
ULONG_PTR *uResult);
|
||||||
PUSER_MESSAGE FASTCALL
|
PUSER_MESSAGE FASTCALL
|
||||||
MsqCreateMessage(LPMSG Msg, BOOLEAN FreeLParam);
|
MsqCreateMessage(LPMSG Msg, BOOLEAN FreeLParam);
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
|
|
|
@ -240,6 +240,43 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only used in ntuser/input.c KeyboardThreadMain(). If it's
|
||||||
|
not called there anymore, please delete */
|
||||||
|
NTSTATUS
|
||||||
|
Win32kInitWin32Thread(PETHREAD Thread)
|
||||||
|
{
|
||||||
|
PEPROCESS Process;
|
||||||
|
|
||||||
|
Process = Thread->ThreadsProcess;
|
||||||
|
|
||||||
|
if (Process->Win32Process == NULL)
|
||||||
|
{
|
||||||
|
/* FIXME - lock the process */
|
||||||
|
Process->Win32Process = ExAllocatePool(NonPagedPool, sizeof(W32PROCESS));
|
||||||
|
|
||||||
|
if (Process->Win32Process == NULL)
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
RtlZeroMemory(Process->Win32Process, sizeof(W32PROCESS));
|
||||||
|
/* FIXME - unlock the process */
|
||||||
|
|
||||||
|
Win32kProcessCallback(Process, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Thread->Tcb.Win32Thread == NULL)
|
||||||
|
{
|
||||||
|
Thread->Tcb.Win32Thread = ExAllocatePool (NonPagedPool, sizeof(W32THREAD));
|
||||||
|
if (Thread->Tcb.Win32Thread == NULL)
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
RtlZeroMemory(Thread->Tcb.Win32Thread, sizeof(W32THREAD));
|
||||||
|
|
||||||
|
Win32kThreadCallback(Thread, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This definition doesn't work
|
* This definition doesn't work
|
||||||
|
|
|
@ -293,6 +293,9 @@ IntCallHookProc(INT HookId,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case WH_KEYBOARD_LL:
|
||||||
|
ArgumentLength += sizeof(KBDLLHOOKSTRUCT);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINT1("Trying to call unsupported window hook %d\n", HookId);
|
DPRINT1("Trying to call unsupported window hook %d\n", HookId);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -343,6 +346,10 @@ IntCallHookProc(INT HookId,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case WH_KEYBOARD_LL:
|
||||||
|
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(KBDLLHOOKSTRUCT));
|
||||||
|
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultPointer = &Result;
|
ResultPointer = &Result;
|
||||||
|
|
|
@ -183,7 +183,9 @@ IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
|
||||||
|
|
||||||
/* Dereference thread if required */
|
/* Dereference thread if required */
|
||||||
if (Hook->Flags & HOOK_THREAD_REFERENCED)
|
if (Hook->Flags & HOOK_THREAD_REFERENCED)
|
||||||
|
{
|
||||||
ObDereferenceObject(Hook->Thread);
|
ObDereferenceObject(Hook->Thread);
|
||||||
|
}
|
||||||
|
|
||||||
/* Close handle */
|
/* Close handle */
|
||||||
ObmCloseHandle(WinStaObj->HandleTable, Hook->Self);
|
ObmCloseHandle(WinStaObj->HandleTable, Hook->Self);
|
||||||
|
@ -191,7 +193,7 @@ IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
|
||||||
|
|
||||||
/* remove a hook, freeing it if the chain is not in use */
|
/* remove a hook, freeing it if the chain is not in use */
|
||||||
STATIC FASTCALL VOID
|
STATIC FASTCALL VOID
|
||||||
IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
|
IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj, BOOL TableAlreadyLocked)
|
||||||
{
|
{
|
||||||
PHOOKTABLE Table = IntGetTable(Hook);
|
PHOOKTABLE Table = IntGetTable(Hook);
|
||||||
|
|
||||||
|
@ -201,7 +203,10 @@ IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! TableAlreadyLocked)
|
||||||
|
{
|
||||||
IntLockHookTable(Table);
|
IntLockHookTable(Table);
|
||||||
|
}
|
||||||
if (0 != Table->Counts[HOOKID_TO_INDEX(Hook->HookId)])
|
if (0 != Table->Counts[HOOKID_TO_INDEX(Hook->HookId)])
|
||||||
{
|
{
|
||||||
Hook->Proc = NULL; /* chain is in use, just mark it and return */
|
Hook->Proc = NULL; /* chain is in use, just mark it and return */
|
||||||
|
@ -210,8 +215,11 @@ IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
|
||||||
{
|
{
|
||||||
IntFreeHook(Table, Hook, WinStaObj);
|
IntFreeHook(Table, Hook, WinStaObj);
|
||||||
}
|
}
|
||||||
|
if (! TableAlreadyLocked)
|
||||||
|
{
|
||||||
IntUnLockHookTable(Table);
|
IntUnLockHookTable(Table);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* release a hook chain, removing deleted hooks if the use count drops to 0 */
|
/* release a hook chain, removing deleted hooks if the use count drops to 0 */
|
||||||
STATIC VOID FASTCALL
|
STATIC VOID FASTCALL
|
||||||
|
@ -249,17 +257,42 @@ IntReleaseHookChain(PHOOKTABLE Table, int HookId, PWINSTATION_OBJECT WinStaObj)
|
||||||
IntUnLockHookTable(Table);
|
IntUnLockHookTable(Table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LRESULT FASTCALL
|
||||||
|
IntCallLowLevelHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam, PHOOK Hook)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG_PTR uResult;
|
||||||
|
|
||||||
|
/* FIXME should get timeout from
|
||||||
|
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
|
||||||
|
Status = MsqSendMessage(Hook->Thread->Tcb.Win32Thread->MessageQueue, (HWND) Code, HookId,
|
||||||
|
wParam, lParam, /*500*/0, TRUE, TRUE, &uResult);
|
||||||
|
|
||||||
|
return NT_SUCCESS(Status) ? uResult : 0;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT FASTCALL
|
LRESULT FASTCALL
|
||||||
HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
|
HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
PHOOK Hook;
|
PHOOK Hook;
|
||||||
PHOOKTABLE Table = MsqGetHooks(PsGetWin32Thread()->MessageQueue);
|
PW32THREAD Win32Thread;
|
||||||
|
PHOOKTABLE Table;
|
||||||
LRESULT Result;
|
LRESULT Result;
|
||||||
PWINSTATION_OBJECT WinStaObj;
|
PWINSTATION_OBJECT WinStaObj;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
|
ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
|
||||||
|
|
||||||
|
Win32Thread = PsGetWin32Thread();
|
||||||
|
if (NULL == Win32Thread)
|
||||||
|
{
|
||||||
|
Table = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Table = MsqGetHooks(Win32Thread->MessageQueue);
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId)))
|
if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId)))
|
||||||
{
|
{
|
||||||
/* try global table */
|
/* try global table */
|
||||||
|
@ -270,6 +303,13 @@ HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Hook->Thread != PsGetCurrentThread()
|
||||||
|
&& (WH_KEYBOARD_LL == HookId || WH_MOUSE_LL == HookId))
|
||||||
|
{
|
||||||
|
DPRINT("Calling hook in owning thread\n");
|
||||||
|
return IntCallLowLevelHook(HookId, Code, wParam, lParam, Hook);
|
||||||
|
}
|
||||||
|
|
||||||
if (Hook->Thread != PsGetCurrentThread())
|
if (Hook->Thread != PsGetCurrentThread())
|
||||||
{
|
{
|
||||||
DPRINT1("Calling hooks in other threads not implemented yet");
|
DPRINT1("Calling hooks in other threads not implemented yet");
|
||||||
|
@ -344,7 +384,7 @@ HOOK_DestroyThreadHooks(PETHREAD Thread)
|
||||||
Elem = Elem->Flink;
|
Elem = Elem->Flink;
|
||||||
if (HookObj->Thread == Thread)
|
if (HookObj->Thread == Thread)
|
||||||
{
|
{
|
||||||
IntRemoveHook(HookObj, WinStaObj);
|
IntRemoveHook(HookObj, WinStaObj, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -433,7 +473,7 @@ NtUserSetWindowsHookEx(
|
||||||
BOOL Ansi)
|
BOOL Ansi)
|
||||||
{
|
{
|
||||||
PWINSTATION_OBJECT WinStaObj;
|
PWINSTATION_OBJECT WinStaObj;
|
||||||
BOOLEAN Global, ReleaseThread;
|
BOOLEAN Global;
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
PHOOK Hook;
|
PHOOK Hook;
|
||||||
UNICODE_STRING ModuleName;
|
UNICODE_STRING ModuleName;
|
||||||
|
@ -473,15 +513,23 @@ NtUserSetWindowsHookEx(
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ReleaseThread = TRUE;
|
|
||||||
}
|
}
|
||||||
else /* system-global hook */
|
else /* system-global hook */
|
||||||
{
|
{
|
||||||
ReleaseThread = FALSE;
|
|
||||||
if (HookId == WH_KEYBOARD_LL || HookId == WH_MOUSE_LL)
|
if (HookId == WH_KEYBOARD_LL || HookId == WH_MOUSE_LL)
|
||||||
{
|
{
|
||||||
Mod = NULL;
|
Mod = NULL;
|
||||||
Thread = PsGetCurrentThread();
|
Thread = PsGetCurrentThread();
|
||||||
|
Status = ObReferenceObjectByPointer(Thread,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
PsThreadType,
|
||||||
|
KernelMode);
|
||||||
|
|
||||||
|
if (! NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastNtError(Status);
|
||||||
|
return (HANDLE) NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (NULL == Mod)
|
else if (NULL == Mod)
|
||||||
{
|
{
|
||||||
|
@ -495,16 +543,20 @@ NtUserSetWindowsHookEx(
|
||||||
Global = TRUE;
|
Global = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We only (partially) support local WH_CBT hooks for now */
|
/* We only (partially) support local WH_CBT hooks and
|
||||||
if (WH_CBT != HookId || Global)
|
* WH_KEYBOARD_LL/WH_MOUSE_LL hooks for now */
|
||||||
|
if ((WH_CBT != HookId || Global)
|
||||||
|
&& WH_KEYBOARD_LL != HookId && WH_MOUSE_LL != HookId)
|
||||||
{
|
{
|
||||||
#if 0 /* Removed to get winEmbed working again */
|
#if 0 /* Removed to get winEmbed working again */
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
#else
|
#else
|
||||||
DPRINT1("Not implemented: HookId %d Global %s\n", HookId, Global ? "TRUE" : "FALSE");
|
DPRINT1("Not implemented: HookId %d Global %s\n", HookId, Global ? "TRUE" : "FALSE");
|
||||||
#endif
|
#endif
|
||||||
if(ReleaseThread)
|
if (NULL != Thread)
|
||||||
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
|
}
|
||||||
SetLastWin32Error(ERROR_NOT_SUPPORTED);
|
SetLastWin32Error(ERROR_NOT_SUPPORTED);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -516,8 +568,10 @@ NtUserSetWindowsHookEx(
|
||||||
|
|
||||||
if (! NT_SUCCESS(Status))
|
if (! NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if(ReleaseThread && Thread)
|
if (NULL != Thread)
|
||||||
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
|
}
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
return (HANDLE) NULL;
|
return (HANDLE) NULL;
|
||||||
}
|
}
|
||||||
|
@ -525,14 +579,18 @@ NtUserSetWindowsHookEx(
|
||||||
Hook = IntAddHook(Thread, HookId, Global, WinStaObj);
|
Hook = IntAddHook(Thread, HookId, Global, WinStaObj);
|
||||||
if (NULL == Hook)
|
if (NULL == Hook)
|
||||||
{
|
{
|
||||||
if(ReleaseThread)
|
if (NULL != Thread)
|
||||||
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
|
}
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ReleaseThread)
|
if (NULL != Thread)
|
||||||
|
{
|
||||||
Hook->Flags |= HOOK_THREAD_REFERENCED;
|
Hook->Flags |= HOOK_THREAD_REFERENCED;
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL != Mod)
|
if (NULL != Mod)
|
||||||
{
|
{
|
||||||
|
@ -540,9 +598,11 @@ NtUserSetWindowsHookEx(
|
||||||
if (! NT_SUCCESS(Status))
|
if (! NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObmDereferenceObject(Hook);
|
ObmDereferenceObject(Hook);
|
||||||
IntRemoveHook(Hook, WinStaObj);
|
IntRemoveHook(Hook, WinStaObj, FALSE);
|
||||||
if(ReleaseThread)
|
if (NULL != Thread)
|
||||||
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
|
}
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -553,9 +613,11 @@ NtUserSetWindowsHookEx(
|
||||||
if (NULL == Hook->ModuleName.Buffer)
|
if (NULL == Hook->ModuleName.Buffer)
|
||||||
{
|
{
|
||||||
ObmDereferenceObject(Hook);
|
ObmDereferenceObject(Hook);
|
||||||
IntRemoveHook(Hook, WinStaObj);
|
IntRemoveHook(Hook, WinStaObj, FALSE);
|
||||||
if(ReleaseThread)
|
if (NULL != Thread)
|
||||||
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
|
}
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -567,9 +629,11 @@ NtUserSetWindowsHookEx(
|
||||||
if (! NT_SUCCESS(Status))
|
if (! NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObmDereferenceObject(Hook);
|
ObmDereferenceObject(Hook);
|
||||||
IntRemoveHook(Hook, WinStaObj);
|
IntRemoveHook(Hook, WinStaObj, FALSE);
|
||||||
if(ReleaseThread)
|
if (NULL != Thread)
|
||||||
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
|
}
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -635,7 +699,7 @@ NtUserUnhookWindowsHookEx(
|
||||||
}
|
}
|
||||||
ASSERT(Hook == HookObj->Self);
|
ASSERT(Hook == HookObj->Self);
|
||||||
|
|
||||||
IntRemoveHook(HookObj, WinStaObj);
|
IntRemoveHook(HookObj, WinStaObj, FALSE);
|
||||||
|
|
||||||
ObmDereferenceObject(HookObj);
|
ObmDereferenceObject(HookObj);
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
|
|
|
@ -184,7 +184,7 @@ MouseThreadMain(PVOID StartContext)
|
||||||
DPRINT("Mouse Input Thread Starting...\n");
|
DPRINT("Mouse Input Thread Starting...\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive and process keyboard input.
|
* Receive and process mouse input.
|
||||||
*/
|
*/
|
||||||
while(InputThreadsRunning)
|
while(InputThreadsRunning)
|
||||||
{
|
{
|
||||||
|
@ -409,6 +409,8 @@ KeyboardThreadMain(PVOID StartContext)
|
||||||
MSG msg;
|
MSG msg;
|
||||||
PUSER_MESSAGE_QUEUE FocusQueue;
|
PUSER_MESSAGE_QUEUE FocusQueue;
|
||||||
struct _ETHREAD *FocusThread;
|
struct _ETHREAD *FocusThread;
|
||||||
|
extern NTSTATUS Win32kInitWin32Thread(PETHREAD Thread);
|
||||||
|
|
||||||
|
|
||||||
PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
|
PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
|
||||||
UINT ModifierState = 0;
|
UINT ModifierState = 0;
|
||||||
|
@ -434,6 +436,22 @@ KeyboardThreadMain(PVOID StartContext)
|
||||||
return; //(Status);
|
return; //(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Not sure if converting this thread to a win32 thread is such
|
||||||
|
a great idea. Since we're posting keyboard messages to the focus
|
||||||
|
window message queue, we'll be (indirectly) doing sendmessage
|
||||||
|
stuff from this thread (for WH_KEYBOARD_LL processing), which
|
||||||
|
means we need our own message queue. If keyboard messages were
|
||||||
|
instead queued to the system message queue, the thread removing
|
||||||
|
the message from the system message queue would be responsible
|
||||||
|
for WH_KEYBOARD_LL processing and we wouldn't need this thread
|
||||||
|
to be a win32 thread. */
|
||||||
|
Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Win32K: Failed making keyboard thread a win32 thread.\n");
|
||||||
|
return; //(Status);
|
||||||
|
}
|
||||||
|
|
||||||
IntKeyboardGetIndicatorTrans(KeyboardDeviceHandle,
|
IntKeyboardGetIndicatorTrans(KeyboardDeviceHandle,
|
||||||
&IndicatorTrans);
|
&IndicatorTrans);
|
||||||
|
|
||||||
|
|
|
@ -1332,7 +1332,7 @@ IntSendMessageTimeoutSingle(HWND hWnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam,
|
Status = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam,
|
||||||
uTimeout, (uFlags & SMTO_BLOCK), uResult);
|
uTimeout, (uFlags & SMTO_BLOCK), FALSE, uResult);
|
||||||
IntReleaseWindowObject(Window);
|
IntReleaseWindowObject(Window);
|
||||||
if (STATUS_TIMEOUT == Status)
|
if (STATUS_TIMEOUT == Status)
|
||||||
{
|
{
|
||||||
|
|
|
@ -618,6 +618,7 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
PUSER_MESSAGE_QUEUE FocusMessageQueue;
|
PUSER_MESSAGE_QUEUE FocusMessageQueue;
|
||||||
MSG Msg;
|
MSG Msg;
|
||||||
LARGE_INTEGER LargeTickCount;
|
LARGE_INTEGER LargeTickCount;
|
||||||
|
KBDLLHOOKSTRUCT KbdHookData;
|
||||||
|
|
||||||
DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
|
DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
|
||||||
uMsg, wParam, lParam);
|
uMsg, wParam, lParam);
|
||||||
|
@ -632,6 +633,20 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
/* We can't get the Msg.pt point here since we don't know thread
|
/* We can't get the Msg.pt point here since we don't know thread
|
||||||
(and thus the window station) the message will end up in yet. */
|
(and thus the window station) the message will end up in yet. */
|
||||||
|
|
||||||
|
KbdHookData.vkCode = Msg.wParam;
|
||||||
|
KbdHookData.scanCode = (Msg.lParam >> 16) & 0xff;
|
||||||
|
KbdHookData.flags = (0 == (Msg.lParam & 0x01000000) ? 0 : LLKHF_EXTENDED) |
|
||||||
|
(0 == (Msg.lParam & 0x20000000) ? 0 : LLKHF_ALTDOWN) |
|
||||||
|
(0 == (Msg.lParam & 0x80000000) ? 0 : LLKHF_UP);
|
||||||
|
KbdHookData.time = Msg.time;
|
||||||
|
KbdHookData.dwExtraInfo = 0;
|
||||||
|
if (HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
|
||||||
|
{
|
||||||
|
DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
|
||||||
|
Msg.message, Msg.wParam, Msg.lParam);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FocusMessageQueue = IntGetFocusMessageQueue();
|
FocusMessageQueue = IntGetFocusMessageQueue();
|
||||||
if( !IntGetScreenDC() ) {
|
if( !IntGetScreenDC() ) {
|
||||||
/* FIXME: What to do about Msg.pt here? */
|
/* FIXME: What to do about Msg.pt here? */
|
||||||
|
@ -793,11 +808,21 @@ MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
|
||||||
|
|
||||||
IntUnLockMessageQueue(MessageQueue);
|
IntUnLockMessageQueue(MessageQueue);
|
||||||
|
|
||||||
|
if (Message->HookMessage)
|
||||||
|
{
|
||||||
|
Result = HOOK_CallHooks(Message->Msg.message,
|
||||||
|
(INT) Message->Msg.hwnd,
|
||||||
|
Message->Msg.wParam,
|
||||||
|
Message->Msg.lParam);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Call the window procedure. */
|
/* Call the window procedure. */
|
||||||
Result = IntSendMessage(Message->Msg.hwnd,
|
Result = IntSendMessage(Message->Msg.hwnd,
|
||||||
Message->Msg.message,
|
Message->Msg.message,
|
||||||
Message->Msg.wParam,
|
Message->Msg.wParam,
|
||||||
Message->Msg.lParam);
|
Message->Msg.lParam);
|
||||||
|
}
|
||||||
|
|
||||||
/* remove the message from the local dispatching list, because it doesn't need
|
/* remove the message from the local dispatching list, because it doesn't need
|
||||||
to be cleaned up on thread termination anymore */
|
to be cleaned up on thread termination anymore */
|
||||||
|
@ -957,7 +982,8 @@ MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
|
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,
|
||||||
UINT uTimeout, BOOL Block, ULONG_PTR *uResult)
|
UINT uTimeout, BOOL Block, BOOL HookMessage,
|
||||||
|
ULONG_PTR *uResult)
|
||||||
{
|
{
|
||||||
PUSER_SENT_MESSAGE Message;
|
PUSER_SENT_MESSAGE Message;
|
||||||
KEVENT CompletionEvent;
|
KEVENT CompletionEvent;
|
||||||
|
@ -992,6 +1018,7 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
Message->SenderQueue = ThreadQueue;
|
Message->SenderQueue = ThreadQueue;
|
||||||
IntReferenceMessageQueue(ThreadQueue);
|
IntReferenceMessageQueue(ThreadQueue);
|
||||||
Message->CompletionCallback = NULL;
|
Message->CompletionCallback = NULL;
|
||||||
|
Message->HookMessage = HookMessage;
|
||||||
|
|
||||||
IntReferenceMessageQueue(MessageQueue);
|
IntReferenceMessageQueue(MessageQueue);
|
||||||
|
|
||||||
|
|
|
@ -2147,7 +2147,10 @@ extern "C" {
|
||||||
#define MOD_ON_KEYUP 2048
|
#define MOD_ON_KEYUP 2048
|
||||||
#define MOD_RIGHT 16384
|
#define MOD_RIGHT 16384
|
||||||
#define MOD_LEFT 32768
|
#define MOD_LEFT 32768
|
||||||
|
#define LLKHF_EXTENDED 0x00000001
|
||||||
|
#define LLKHF_INJECTED 0x00000010
|
||||||
#define LLKHF_ALTDOWN 0x00000020
|
#define LLKHF_ALTDOWN 0x00000020
|
||||||
|
#define LLKHF_UP 0x00000080
|
||||||
#if (WINVER >= 0x0500)
|
#if (WINVER >= 0x0500)
|
||||||
#define FLASHW_STOP 0
|
#define FLASHW_STOP 0
|
||||||
#define FLASHW_CAPTION 1
|
#define FLASHW_CAPTION 1
|
||||||
|
|
Loading…
Reference in a new issue