Author: jimtabor
Date: Thu Nov 4 23:45:34 2010
New Revision: 49472
URL:
http://svn.reactos.org/svn/reactos?rev=49472&view=rev
Log:
[Win32k|User32]
- This hook commit fixes the ros regression testing startup, but consider this a hax fix
until more research in Global hooks has completed. More pointed Global hook tests are
needed. Misc changes, removed unused storage pointers and reordering. For DosBOX, the
mouse low level is now working and the keyboard low level should not be so intermittent as
before, now sending messages from system desktop not from thread desktop, see bug 5670 for
more details.
Modified:
trunk/reactos/dll/win32/user32/windows/hook.c
trunk/reactos/include/reactos/win32k/callback.h
trunk/reactos/subsystems/win32/win32k/main/dllmain.c
trunk/reactos/subsystems/win32/win32k/ntuser/callback.c
trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
trunk/reactos/subsystems/win32/win32k/ntuser/input.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/dll/win32/user32/windows/hook.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/h…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/hook.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/hook.c [iso-8859-1] Thu Nov 4 23:45:34 2010
@@ -154,49 +154,18 @@
LPMSG lpMsg,
int nCode)
{
- BOOL ret = FALSE;
-
- if (nCode != HCBT_CREATEWND) ret = NtUserCallMsgFilter((LPMSG) lpMsg, nCode);
- else
+ MSG Msg;
+ if (NtCurrentTeb()->Win32ThreadInfo &&
IsThreadHooked(GetWin32ClientInfo()))
+ {
+ if ( lpMsg->message & ~WM_MAXIMUM )
{
- UNICODE_STRING usBuffer;
- CBT_CREATEWNDA *cbtcwA = (CBT_CREATEWNDA *)lpMsg->lParam;
- CBT_CREATEWNDW cbtcwW;
- CREATESTRUCTW csW;
- MSG Msg;
-
- Msg.hwnd = lpMsg->hwnd;
- Msg.message = lpMsg->message;
- Msg.time = lpMsg->time;
- Msg.pt = lpMsg->pt;
- Msg.wParam = lpMsg->wParam;
-
- cbtcwW.lpcs = &csW;
- cbtcwW.hwndInsertAfter = cbtcwA->hwndInsertAfter;
- csW = *(CREATESTRUCTW *)cbtcwA->lpcs;
-
- if (HIWORD(cbtcwA->lpcs->lpszName))
- {
-
RtlCreateUnicodeStringFromAsciiz(&usBuffer,cbtcwA->lpcs->lpszName);
- csW.lpszName = usBuffer.Buffer;
- }
- if (HIWORD(cbtcwA->lpcs->lpszClass))
- {
-
RtlCreateUnicodeStringFromAsciiz(&usBuffer,cbtcwA->lpcs->lpszClass);
- csW.lpszClass = usBuffer.Buffer;
- }
- Msg.lParam =(LPARAM) &cbtcwW;
-
- ret = NtUserCallMsgFilter((LPMSG)&Msg, nCode);
-
- lpMsg->time = Msg.time;
- lpMsg->pt = Msg.pt;
-
- cbtcwA->hwndInsertAfter = cbtcwW.hwndInsertAfter;
- if (HIWORD(csW.lpszName)) HeapFree( GetProcessHeap(), 0, (LPWSTR)csW.lpszName );
- if (HIWORD(csW.lpszClass)) HeapFree( GetProcessHeap(), 0, (LPWSTR)csW.lpszClass
);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
- return ret;
+ RtlCopyMemory(&Msg, lpMsg, sizeof(MSG));
+ return NtUserCallMsgFilter( &Msg, nCode);
+ }
+ return FALSE;
}
@@ -209,7 +178,18 @@
LPMSG lpMsg,
int nCode)
{
- return NtUserCallMsgFilter((LPMSG) lpMsg, nCode);
+ MSG Msg;
+ if (NtCurrentTeb()->Win32ThreadInfo &&
IsThreadHooked(GetWin32ClientInfo()))
+ {
+ if ( lpMsg->message & ~WM_MAXIMUM )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ RtlCopyMemory(&Msg, lpMsg, sizeof(MSG));
+ return NtUserCallMsgFilter( &Msg, nCode);
+ }
+ return FALSE;
}
@@ -454,7 +434,7 @@
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
KBDLLHOOKSTRUCT KeyboardLlData, *pKeyboardLlData;
MSLLHOOKSTRUCT MouseLlData, *pMouseLlData;
- MSG Msg, *pMsg;
+ MSG *pcMsg, *pMsg;
PMOUSEHOOKSTRUCT pMHook;
CWPSTRUCT CWP, *pCWP;
CWPRETSTRUCT CWPR, *pCWPR;
@@ -476,13 +456,12 @@
case HCBT_CREATEWND:
CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS)
((PCHAR) Common + Common->lParam);
- Csw = CbtCreatewndExtra->Cs;
- Csw.lpszName = CbtCreatewndExtra->Cs.lpszName;
- Csw.lpszClass = CbtCreatewndExtra->Cs.lpszClass;
- wParam = Common->wParam;
+ RtlCopyMemory(&Csw, &CbtCreatewndExtra->Cs, sizeof(CREATESTRUCTW));
CbtCreatewndw.lpcs = &Csw;
CbtCreatewndw.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
+ wParam = Common->wParam;
lParam = (LPARAM) &CbtCreatewndw;
+ ERR("HCBT_CREATEWND: hWnd 0x%x Name 0x%x Class 0x%x\n",
Common->wParam, Csw.lpszName, Csw.lpszClass);
break;
case HCBT_CLICKSKIPPED:
pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
@@ -524,7 +503,7 @@
}
else
{
- ERR("Common = 0x%x, Proc = 0x%x\n",Common,Common->Proc);
+ ERR("Null Proc! Common = 0x%x, Proc =
0x%x\n",Common,Common->Proc);
}
switch(Common->Code)
{
@@ -545,6 +524,7 @@
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM)
&KeyboardLlData);
break;
case WH_MOUSE_LL:
+ ERR("WH_MOUSE_LL: Code %d, wParam
%d\n",Common->Code,Common->wParam);
pMouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
RtlCopyMemory(&MouseLlData, pMouseLlData, sizeof(MSLLHOOKSTRUCT));
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM)
&MouseLlData);
@@ -562,7 +542,7 @@
_SEH2_END;
break;
case WH_CALLWNDPROC:
- ERR("WH_CALLWNDPROC: Code %d, wParam
%d\n",Common->Code,Common->wParam);
+// ERR("WH_CALLWNDPROC: Code %d, wParam
%d\n",Common->Code,Common->wParam);
pCWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam);
RtlCopyMemory(&CWP, pCWP, sizeof(CWPSTRUCT));
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWP);
@@ -573,14 +553,15 @@
Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWPR);
break;
case WH_MSGFILTER: /* All SEH support */
- ERR("WH_MSGFILTER: Code %d, wParam
%d\n",Common->Code,Common->wParam);
case WH_SYSMSGFILTER:
case WH_GETMESSAGE:
pMsg = (PMSG)((PCHAR) Common + Common->lParam);
- RtlCopyMemory(&Msg, pMsg, sizeof(MSG));
+ pcMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSG));
+ RtlCopyMemory(pcMsg, pMsg, sizeof(MSG));
+// ERR("pMsg %d pcMsg %d\n",pMsg->message, pcMsg->message);
_SEH2_TRY
{
- Result = Common->Proc(Common->Code, Common->wParam, (LPARAM)
&Msg);
+ Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pcMsg);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -588,11 +569,14 @@
}
_SEH2_END;
if (!Hit && Common->HookId == WH_GETMESSAGE)
- RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
- break;
- case WH_FOREGROUNDIDLE: /* <-- SEH support */
+ RtlCopyMemory(pMsg, pcMsg, sizeof(MSG));
+ HeapFree( GetProcessHeap(), 0, pcMsg );
+ break;
case WH_KEYBOARD:
case WH_SHELL:
+ Result = Common->Proc(Common->Code, Common->wParam, Common->lParam);
+ break;
+ case WH_FOREGROUNDIDLE: /* <-- SEH support */
_SEH2_TRY
{
Result = Common->Proc(Common->Code, Common->wParam,
Common->lParam);
Modified: trunk/reactos/include/reactos/win32k/callback.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/cal…
==============================================================================
--- trunk/reactos/include/reactos/win32k/callback.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/win32k/callback.h [iso-8859-1] Thu Nov 4 23:45:34 2010
@@ -48,8 +48,6 @@
LPARAM lParam;
HOOKPROC Proc;
BOOLEAN Ansi;
- UINT ModuleNameLength;
- WCHAR ModuleName[1];
} HOOKPROC_CALLBACK_ARGUMENTS, *PHOOKPROC_CALLBACK_ARGUMENTS;
typedef struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ma…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] Thu Nov 4 23:45:34
2010
@@ -252,17 +252,41 @@
}
}
}
+ else
+ {
+ DPRINT1("No Desktop handle for this Thread!\n");
+ }
Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
co_IntDestroyCaret(Win32Thread);
Win32Thread->ppi = PsGetCurrentProcessWin32Process();
+ if (Win32Thread->rpdesk && !Win32Thread->pDeskInfo)
+ {
+ Win32Thread->pDeskInfo = Win32Thread->rpdesk->pDeskInfo;
+ }
+ Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
+ Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
pTeb = NtCurrentTeb();
if (pTeb)
- {
- Win32Thread->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
- Win32Thread->pClientInfo->pClientThreadInfo = NULL;
- }
- Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
- Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
+ { /* Attempt to startup client support which should have been initialized in
IntSetThreadDesktop. */
+ PCLIENTINFO pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
+ Win32Thread->pClientInfo = pci;
+ pci->pClientThreadInfo = NULL;
+ pci->ppi = Win32Thread->ppi;
+ pci->fsHooks = Win32Thread->fsHooks;
+ if (Win32Thread->KeyboardLayout) pci->hKL =
Win32Thread->KeyboardLayout->hkl;
+ pci->dwTIFlags = Win32Thread->TIF_flags;
+ /* CI may not have been initialized. */
+ if (!pci->pDeskInfo && Win32Thread->pDeskInfo)
+ {
+ if (!pci->ulClientDelta) pci->ulClientDelta =
DesktopHeapGetUserDelta();
+
+ pci->pDeskInfo = (PVOID)((ULONG_PTR)Win32Thread->pDeskInfo -
pci->ulClientDelta);
+ }
+ }
+ else
+ {
+ DPRINT1("No TEB for this Thread!\n");
+ }
Win32Thread->pEThread = Thread;
}
else
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/callback.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/callback.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/callback.c [iso-8859-1] Thu Nov 4
23:45:34 2010
@@ -335,6 +335,7 @@
PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
PTHREADINFO pti;
PWND pWnd;
+ PMSG pMsg = NULL;
BOOL Hit = FALSE;
ASSERT(Proc);
@@ -346,8 +347,8 @@
return 0;
}
- ArgumentLength = sizeof(HOOKPROC_CALLBACK_ARGUMENTS) - sizeof(WCHAR)
- + ModuleName->Length;
+ ArgumentLength = sizeof(HOOKPROC_CALLBACK_ARGUMENTS);
+
switch(HookId)
{
case WH_CBT:
@@ -360,6 +361,7 @@
DPRINT1("WH_CBT HCBT_CREATEWND wParam bad hWnd!\n");
goto Fault_Exit;
}
+ DPRINT1("HCBT_CREATEWND AnsiCreator %s, AnsiHook %s\n",
pWnd->state & WNDS_ANSICREATOR ? "True" : "False", Ansi ?
"True" : "False");
// Due to KsStudio.exe, just pass the callers original pointers
// except class which point to kernel space if not an atom.
// Found by, Olaf Siejka
@@ -432,24 +434,20 @@
Common->lParam = lParam;
Common->Proc = Proc;
Common->Ansi = Ansi;
- Common->ModuleNameLength = ModuleName->Length;
- if (ModuleName->Buffer)
- RtlCopyMemory(Common->ModuleName, ModuleName->Buffer,
ModuleName->Length);
- Extra = (PCHAR) Common->ModuleName + Common->ModuleNameLength;
+ Extra = (PCHAR) Common + sizeof(HOOKPROC_CALLBACK_ARGUMENTS);
switch(HookId)
{
case WH_CBT:
switch(Code)
- {
+ { // Need to remember this is not the first time through! Call Next Hook?
case HCBT_CREATEWND:
- Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS) Extra;
RtlCopyMemory( &CbtCreatewndExtra->Cs, CbtCreateWnd->lpcs,
sizeof(CREATESTRUCTW) );
CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter;
- CbtCreatewndExtra->Cs.lpszClass = CbtCreateWnd->lpcs->lpszClass;
// if Atom
+ CbtCreatewndExtra->Cs.lpszClass = CbtCreateWnd->lpcs->lpszClass;
CbtCreatewndExtra->Cs.lpszName = CbtCreateWnd->lpcs->lpszName;
- Extra = (PCHAR) (CbtCreatewndExtra + 1);
+ Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
break;
case HCBT_CLICKSKIPPED:
RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT));
@@ -488,7 +486,8 @@
case WH_MSGFILTER:
case WH_SYSMSGFILTER:
case WH_GETMESSAGE:
- RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSG));
+ pMsg = (PMSG)lParam;
+ RtlCopyMemory(Extra, (PVOID) pMsg, sizeof(MSG));
Common->lParam = (LPARAM) (Extra - (PCHAR) Common);
break;
case WH_FOREGROUNDIDLE:
@@ -548,9 +547,9 @@
break;
// "The GetMsgProc hook procedure can examine or modify the message."
case WH_GETMESSAGE:
- if (lParam)
+ if (pMsg)
{
- RtlCopyMemory((PVOID) lParam, Extra, sizeof(MSG));
+ RtlCopyMemory((PVOID) pMsg, Extra, sizeof(MSG));
}
break;
}
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c [iso-8859-1] Thu Nov 4
23:45:34 2010
@@ -880,13 +880,23 @@
PUNICODE_STRING lpszDesktopName = NULL;
UNICODE_STRING ClassName, MenuName;
LARGE_STRING WindowName;
+ BOOL NoHooks = FALSE;
PWND pWnd = NULL;
CREATESTRUCTW Cs;
INT i;
+ PTHREADINFO ptiCurrent;
DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
UserEnterExclusive();
+
+ ptiCurrent = PsGetCurrentThreadWin32Thread();
+ if (ptiCurrent)
+ {
+ /* Turn off hooks when calling any CreateWindowEx from inside win32k. */
+ NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
+ ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
+ }
_SEH2_TRY
{
@@ -1102,6 +1112,7 @@
RETURN( Desktop);
CLEANUP:
+ if (!NoHooks && ptiCurrent) ptiCurrent->TIF_flags &=
~TIF_DISABLEHOOKS;
DPRINT("Leave NtUserCreateDesktop, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] Thu Nov 4 23:45:34
2010
@@ -21,6 +21,7 @@
{
PHOOK pHk;
LPARAM lParam;
+ PVOID pHookStructs;
} HOOKPACK, *PHOOKPACK;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -36,6 +37,7 @@
NTSTATUS Status;
PTHREADINFO pti;
PHOOKPACK pHP;
+ INT Size;
ULONG_PTR uResult = 0;
if (Hook->Thread)
@@ -48,6 +50,56 @@
pHP->pHk = Hook;
pHP->lParam = lParam;
+ pHP->pHookStructs = NULL;
+ Size = 0;
+
+// Once the rest is enabled again, This prevents stack corruption from the caller.
+ switch(Hook->HookId)
+ {
+ case WH_CBT:
+ switch(Code)
+ {
+ case HCBT_CREATEWND:
+ Size = sizeof(CBT_CREATEWNDW);
+ break;
+ case HCBT_MOVESIZE:
+ Size = sizeof(RECTL);
+ break;
+ case HCBT_ACTIVATE:
+ Size = sizeof(CBTACTIVATESTRUCT);
+ break;
+ case HCBT_CLICKSKIPPED:
+ Size = sizeof(MOUSEHOOKSTRUCT);
+ break;
+ }
+ break;
+ case WH_KEYBOARD_LL:
+ Size = sizeof(KBDLLHOOKSTRUCT);
+ break;
+ case WH_MOUSE_LL:
+ Size = sizeof(MSLLHOOKSTRUCT);
+ break;
+ case WH_MOUSE:
+ Size = sizeof(MOUSEHOOKSTRUCT);
+ break;
+ case WH_CALLWNDPROC:
+ Size = sizeof(CWPSTRUCT);
+ break;
+ case WH_CALLWNDPROCRET:
+ Size = sizeof(CWPRETSTRUCT);
+ break;
+ case WH_MSGFILTER:
+ case WH_SYSMSGFILTER:
+ case WH_GETMESSAGE:
+ Size = sizeof(MSG);
+ break;
+ }
+
+ if (Size)
+ {
+ pHP->pHookStructs = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_HOOK);
+ if (pHP->pHookStructs) RtlCopyMemory(pHP->pHookStructs, (PVOID)lParam,
Size);
+ }
/* FIXME should get timeout from
* HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
@@ -63,35 +115,12 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Error Hook Call SendMsg. %d Status: 0x%x\n", Hook->HookId,
Status);
+ if (pHP->pHookStructs) ExFreePoolWithTag(pHP->pHookStructs, TAG_HOOK);
ExFreePoolWithTag(pHP, TAG_HOOK);
}
return NT_SUCCESS(Status) ? uResult : 0;
}
-static
-LRESULT
-FASTCALL
-co_HOOK_CallHookNext( PHOOK Hook,
- INT Code,
- WPARAM wParam,
- LPARAM lParam)
-{
- if ( (Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL)
)
- {
- DPRINT1("Calling Next HOOK from another Thread. %d\n",
Hook->HookId);
- return IntCallLowLevelHook(Hook, Code, wParam, lParam);
- }
-
- DPRINT("Calling Next HOOK %d\n", Hook->HookId);
-
- return co_IntCallHookProc( Hook->HookId,
- Code,
- wParam,
- lParam,
- Hook->Proc,
- Hook->Ansi,
- &Hook->ModuleName);
-}
//
// Dispatch MsgQueue Hook Call processor!
@@ -108,17 +137,71 @@
PHOOKPACK pHP = (PHOOKPACK)lParam;
phk = pHP->pHk;
+ lParam = pHP->lParam;
+
+ switch(HookId)
+ {
+ case WH_CBT:
+ switch(Code)
+ {
+ case HCBT_CREATEWND:
+ case HCBT_MOVESIZE:
+ case HCBT_ACTIVATE:
+ case HCBT_CLICKSKIPPED:
+ lParam = (LPARAM)pHP->pHookStructs;
+ break;
+ }
+ break;
+ case WH_KEYBOARD_LL:
+ case WH_MOUSE_LL:
+ case WH_MOUSE:
+ case WH_CALLWNDPROC:
+ case WH_CALLWNDPROCRET:
+ case WH_MSGFILTER:
+ case WH_SYSMSGFILTER:
+ case WH_GETMESSAGE:
+ lParam = (LPARAM)pHP->pHookStructs;
+ break;
+ }
+
/* The odds are high for this to be a Global call. */
Result = co_IntCallHookProc( HookId,
Code,
wParam,
- pHP->lParam,
+ lParam,
phk->Proc,
phk->Ansi,
&phk->ModuleName);
+ /* The odds so high, no one is waiting for the results. */
+ if (pHP->pHookStructs) ExFreePoolWithTag(pHP->pHookStructs, TAG_HOOK);
ExFreePoolWithTag(pHP, TAG_HOOK);
return Result;
+}
+
+static
+LRESULT
+FASTCALL
+co_HOOK_CallHookNext( PHOOK Hook,
+ INT Code,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ if ( (Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL)
)
+ {
+ DPRINT1("Calling Next HOOK from another Thread. %d\n",
Hook->HookId);
+ return IntCallLowLevelHook(Hook, Code, wParam, lParam);
+ }
+
+ DPRINT("Calling Next HOOK %d\n", Hook->HookId);
+
+ return co_IntCallHookProc( Hook->HookId,
+ Code,
+ wParam,
+ lParam,
+ Hook->Proc,
+ Hook->Ansi,
+ &Hook->ModuleName);
}
LRESULT
@@ -704,6 +787,20 @@
return Elem == Table ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain);
}
+static
+PHOOK
+FASTCALL
+IntGetNextGlobalHook(PHOOK Hook, PDESKTOP pdo)
+{
+ int HookId = Hook->HookId;
+ PLIST_ENTRY Elem;
+
+ Elem = Hook->Chain.Flink;
+ if (Elem != &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)])
+ return CONTAINING_RECORD(Elem, HOOK, Chain);
+ return NULL;
+}
+
/* find the next hook in the chain */
PHOOK
FASTCALL
@@ -724,10 +821,7 @@
else
{
pti = PsGetCurrentThreadWin32Thread();
-
- Elem = Hook->Chain.Flink;
- if (Elem !=
&pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)])
- return CONTAINING_RECORD(Elem, HOOK, Chain);
+ return IntGetNextGlobalHook(Hook, pti->rpdesk);
}
return NULL;
}
@@ -756,6 +850,7 @@
{
INT HookId;
PTHREADINFO pti;
+ PDESKTOP pdo;
HookId = Hook->HookId;
@@ -783,13 +878,13 @@
{
IntFreeHook( Hook);
- pti = PsGetCurrentThreadWin32Thread();
-
- if ( pti->rpdesk &&
- pti->rpdesk->pDeskInfo &&
-
IsListEmpty(&pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]) )
- {
- pti->rpdesk->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId);
+ pdo = IntGetActiveDesktop();
+
+ if ( pdo &&
+ pdo->pDeskInfo &&
+ IsListEmpty(&pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]) )
+ {
+ pdo->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId);
return TRUE;
}
}
@@ -808,13 +903,13 @@
pti = Thread->Tcb.Win32Thread;
pdo = IntGetActiveDesktop();
-DPRINT1("DestroyThreadHooks 1\n");
+
if (!pti || !pdo)
{
DPRINT1("Kill Thread Hooks pti 0x%x pdo 0x%x\n",pti,pdo);
return;
}
- ObReferenceObject(pti->pEThread);
+ ObReferenceObject(Thread);
// Local Thread cleanup.
if (pti->fsHooks)
@@ -838,7 +933,6 @@
}
pti->fsHooks = 0;
}
-DPRINT1("DestroyThreadHooks 2\n");
// Global search based on Thread and cleanup.
if (pdo->pDeskInfo->fsHooks)
{
@@ -854,7 +948,7 @@
{
if (!HookObj) break;
if (HookObj->head.pti == pti)
- { DPRINT1("Global Hook Removed\n");
+ {
if (IntRemoveHook(HookObj)) break;
}
pElem = HookObj->Chain.Flink;
@@ -863,8 +957,7 @@
while (pElem != pGLE);
}
}
- ObDereferenceObject(pti->pEThread);
-DPRINT1("DestroyThreadHooks 3\n");
+ ObDereferenceObject(Thread);
return;
}
@@ -882,6 +975,7 @@
PTHREADINFO pti;
PCLIENTINFO ClientInfo;
PLIST_ENTRY pLLE, pGLE;
+ PDESKTOP pdo;
BOOL Local = FALSE, Global = FALSE;
LRESULT Result = 0;
@@ -889,9 +983,20 @@
pti = PsGetCurrentThreadWin32Thread();
if (!pti || !pti->rpdesk || !pti->rpdesk->pDeskInfo)
- goto Exit; // Must have a desktop running for hooks.
-
- if ( pti->TIF_flags & TIF_INCLEANUP)
+ {
+ pdo = IntGetActiveDesktop();
+ /* If KeyboardThread|MouseThread|(RawInputThread or RIT) aka system threads,
+ pti->fsHooks most likely, is zero. So process KbT & MsT to "send"
the message.
+ */
+ if ( !pti || !pdo || (!(HookId == WH_KEYBOARD_LL) && !(HookId ==
WH_MOUSE_LL)) )
+ goto Exit;
+ }
+ else
+ {
+ pdo = pti->rpdesk;
+ }
+
+ if ( pti->TIF_flags & (TIF_INCLEANUP|TIF_DISABLEHOOKS))
goto Exit;
if ( ISITHOOKED(HookId) )
@@ -900,7 +1005,7 @@
Local = TRUE;
}
- if ( pti->rpdesk->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId) )
+ if ( pdo->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId) )
{
DPRINT("Global Hooker %d\n", HookId);
Global = TRUE;
@@ -908,8 +1013,6 @@
if ( !Local && !Global ) goto Exit; // No work!
- pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
- pGLE = &pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
Hook = NULL;
/* SetWindowHookEx sorts out the Thread issue by placing the Hook to
@@ -917,6 +1020,7 @@
*/
if ( Local )
{
+ pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
Hook = IntGetFirstHook(pLLE);
if (!Hook)
{
@@ -970,6 +1074,7 @@
{
PTHREADINFO ptiHook;
+ pGLE = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
Hook = IntGetFirstHook(pGLE);
if (!Hook)
{
@@ -988,10 +1093,11 @@
/* "Global hook monitors messages for all threads in the same desktop
* as the calling thread."
*/
- if ( ptiHook->TIF_flags & TIF_INCLEANUP ||
- ptiHook->rpdesk != pti->rpdesk)
+ if ( ptiHook->TIF_flags & (TIF_INCLEANUP|TIF_DISABLEHOOKS) ||
+ ptiHook->rpdesk != pdo)
{
- Hook = IntGetNextHook(Hook);
+ DPRINT("Next Hook 0x%x, 0x%x\n",ptiHook->rpdesk,pdo);
+ Hook = IntGetNextGlobalHook(Hook, pdo);
if (!Hook) break;
continue;
}
@@ -999,8 +1105,14 @@
ObReferenceObject(ptiHook->pEThread);
if (ptiHook != pti )
{
- DPRINT("\nGlobal Hook posting to another Thread! %d\n",HookId );
- Result = IntCallLowLevelHook(Hook, Code, wParam, lParam);
+ /* This fixed the ros regtest. Wine does this too. Need more time
+ to investigate this. MSDN "Hooks Overview" can't be wrong?
+ */
+ if (HookId == WH_KEYBOARD_LL || HookId == WH_MOUSE_LL)
+ {
+ DPRINT("\nGlobal Hook posting to another Thread! %d\n",HookId
);
+ Result = IntCallLowLevelHook(Hook, Code, wParam, lParam);
+ }
}
else
{ /* Make the direct call. */
@@ -1014,7 +1126,7 @@
&Hook->ModuleName);
}
ObDereferenceObject(ptiHook->pEThread);
- Hook = IntGetNextHook(Hook);
+ Hook = IntGetNextGlobalHook(Hook, pdo);
}
while ( Hook );
DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId,Result);
@@ -1248,7 +1360,7 @@
}
}
else /* system-global hook */
- {
+ {
pti = ptiCurrent; // gptiCurrent;
if ( !Mod &&
(HookId == WH_GETMESSAGE ||
@@ -1293,6 +1405,8 @@
Hook->phkNext = NULL; /* Dont use as a chain! Use link lists for chaining. */
Hook->Proc = HookProc;
Hook->Ansi = Ansi;
+
+ DPRINT1("Set Hook Desk 0x%x DeskInfo 0x%x Handle Desk
0x%x\n",pti->rpdesk, pti->pDeskInfo,Hook->head.rpdesk);
if (ThreadId) /* thread-local hook */
{
@@ -1343,10 +1457,10 @@
}
else
{
- InsertHeadList(&pti->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)],
&Hook->Chain);
+
InsertHeadList(&pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)],
&Hook->Chain);
Hook->ptiHooked = NULL;
//gptiCurrent->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
- pti->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
+ pti->rpdesk->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
}
RtlInitUnicodeString(&Hook->ModuleName, NULL);
@@ -1393,7 +1507,7 @@
else
Hook->offPfn = 0;
- DPRINT1("Installing: HookId %d Global %s\n", HookId, !ThreadId ?
"TRUE" : "FALSE");
+ DPRINT("Installing: HookId %d Global %s\n", HookId, !ThreadId ?
"TRUE" : "FALSE");
RETURN( Handle);
CLEANUP:
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Thu Nov 4 23:45:34
2010
@@ -22,6 +22,8 @@
/* GLOBALS *******************************************************************/
PTHREADINFO ptiRawInput;
+PTHREADINFO ptiKeyboard;
+PTHREADINFO ptiMouse;
PKTIMER MasterTimer = NULL;
PATTACHINFO gpai = NULL;
@@ -234,6 +236,18 @@
FILE_SYNCHRONOUS_IO_ALERT);
} while (!NT_SUCCESS(Status));
+ /* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
+ Status = Win32kInitWin32Thread(PsGetCurrentThread());
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Win32K: Failed making mouse thread a win32 thread.\n");
+ return; //(Status);
+ }
+
+ ptiMouse = PsGetCurrentThreadWin32Thread();
+ ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT1("\nMouse Thread 0x%x \n", ptiMouse);
+
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
@@ -529,6 +543,10 @@
DPRINT1("Win32K: Failed making keyboard thread a win32 thread.\n");
return; //(Status);
}
+
+ ptiKeyboard = PsGetCurrentThreadWin32Thread();
+ ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT1("\nKeyboard Thread 0x%x \n", ptiKeyboard);
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
@@ -890,8 +908,8 @@
}
ptiRawInput = PsGetCurrentThreadWin32Thread();
- DPRINT("\nRaw Input Thread 0x%x \n", ptiRawInput);
-
+ ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT1("\nRaw Input Thread 0x%x \n", ptiRawInput);
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] Thu Nov 4 23:45:34
2010
@@ -1910,9 +1910,9 @@
LRESULT Result;
USER_REFERENCE_ENTRY ParentRef, Ref;
PTHREADINFO pti;
- ANSI_STRING asClassName;
DWORD dwShowMode = SW_SHOW;
CREATESTRUCTW *pCsw;
+ PVOID pszClass = NULL, pszName = NULL;
DECLARE_RETURN(PWND);
/* Get the current window station and reference it */
@@ -1927,7 +1927,6 @@
pCsw = NULL;
pCbtCreate = NULL;
- RtlInitAnsiString(&asClassName, NULL);
/* Get the class and reference it*/
Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
@@ -2008,17 +2007,58 @@
pCsw->dwExStyle = Cs->dwExStyle;
dwStyle = Cs->style; // Save it anyway.
pCsw->style = Window->style; /* HCBT_CREATEWND needs the real window style */
-
- pCsw->lpszName = (LPCWSTR) WindowName->Buffer;
- pCsw->lpszClass = (LPCWSTR) ClassName->Buffer;
-
- if (Window->state & WNDS_ANSICREATOR)
- {
- if (!IS_ATOM(ClassName->Buffer))
- {
- RtlUnicodeStringToAnsiString(&asClassName, ClassName, TRUE);
- pCsw->lpszClass = (LPCWSTR) asClassName.Buffer;
- }
+ pCsw->lpszName = Cs->lpszName;
+ pCsw->lpszClass = Cs->lpszClass;
+
+ // Based on the assumption this is from "unicode source" user32, ReactOS,
answer is yes.
+ if (!IS_ATOM(ClassName->Buffer))
+ {
+ if (Window->state & WNDS_ANSICREATOR)
+ {
+ ANSI_STRING AnsiString;
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(ClassName)+sizeof(CHAR);
+ pszClass = UserHeapAlloc(AnsiString.MaximumLength);
+ RtlZeroMemory(pszClass, AnsiString.MaximumLength);
+ AnsiString.Buffer = (PCHAR)pszClass;
+ RtlUnicodeStringToAnsiString(&AnsiString, ClassName, FALSE);
+ }
+ else
+ {
+ UNICODE_STRING UnicodeString;
+ UnicodeString.MaximumLength = ClassName->Length + sizeof(UNICODE_NULL);
+ pszClass = UserHeapAlloc(UnicodeString.MaximumLength);
+ RtlZeroMemory(pszClass, UnicodeString.MaximumLength);
+ UnicodeString.Buffer = (PWSTR)pszClass;
+ RtlCopyUnicodeString(&UnicodeString, ClassName);
+ }
+ if (pszClass) pCsw->lpszClass = UserHeapAddressToUser(pszClass);
+ }
+ if (WindowName->Length)
+ {
+ UNICODE_STRING Name;
+ Name.Buffer = WindowName->Buffer;
+ Name.Length = WindowName->Length;
+ Name.MaximumLength = WindowName->MaximumLength;
+
+ if (Window->state & WNDS_ANSICREATOR)
+ {
+ ANSI_STRING AnsiString;
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name)+sizeof(CHAR);
+ pszName = UserHeapAlloc(AnsiString.MaximumLength);
+ RtlZeroMemory(pszName, AnsiString.MaximumLength);
+ AnsiString.Buffer = (PCHAR)pszName;
+ RtlUnicodeStringToAnsiString(&AnsiString, &Name, FALSE);
+ }
+ else
+ {
+ UNICODE_STRING UnicodeString;
+ UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL);
+ pszName = UserHeapAlloc(UnicodeString.MaximumLength);
+ RtlZeroMemory(pszName, UnicodeString.MaximumLength);
+ UnicodeString.Buffer = (PWSTR)pszName;
+ RtlCopyUnicodeString(&UnicodeString, &Name);
+ }
+ if (pszName) pCsw->lpszName = UserHeapAddressToUser(pszName);
}
pCbtCreate->lpcs = pCsw;
@@ -2037,7 +2077,10 @@
Cs->y = pCsw->y;
hwndInsertAfter = pCbtCreate->hwndInsertAfter;
- Cs->style = dwStyle; /* NCCREATE and WM_NCCALCSIZE need the original values*/
+ /* NCCREATE and WM_NCCALCSIZE need the original values */
+ Cs->style = dwStyle;
+ Cs->lpszName = (LPCWSTR) WindowName;
+ Cs->lpszClass = (LPCWSTR) ClassName;
/* Send the WM_GETMINMAXINFO message*/
Size.cx = Cs->cx;
@@ -2187,7 +2230,8 @@
if (pCsw) ExFreePoolWithTag(pCsw, TAG_HOOK);
if (pCbtCreate) ExFreePoolWithTag(pCbtCreate, TAG_HOOK);
- RtlFreeAnsiString(&asClassName);
+ if (pszName) UserHeapFree(pszName);
+ if (pszClass) UserHeapFree(pszClass);
if (Window)
{
@@ -2337,10 +2381,11 @@
Cs.cy = nHeight;
Cs.x = x;
Cs.y = y;
-// Cs.lpszName = (LPCWSTR) WindowName->Buffer;
-// Cs.lpszClass = (LPCWSTR) ClassName->Buffer;
- Cs.lpszName = (LPCWSTR) plstrWindowName;
- Cs.lpszClass = (LPCWSTR) &ustrClassName;
+ Cs.lpszName = (LPCWSTR) plstrWindowName->Buffer;
+ if (IS_ATOM(plstrClassName))
+ Cs.lpszClass = (LPCWSTR) plstrClassName;
+ else
+ Cs.lpszClass = (LPCWSTR) plstrClassName->Buffer;
Cs.dwExStyle = dwExStyle;
UserEnterExclusive();