Author: jimtabor
Date: Mon Feb 16 03:32:46 2015
New Revision: 66310
URL:
http://svn.reactos.org/svn/reactos?rev=66310&view=rev
Log:
[Win32ss]
- Fix wine msg:test_winevents.
- Fix global hooks while sending to same process different thread. Yes, interesting.
- Fix event hooks, use posting (faster) instead of sending. This fixed a problem while
sending to the same thread.
Modified:
trunk/reactos/win32ss/include/callback.h
trunk/reactos/win32ss/user/ntuser/callback.c
trunk/reactos/win32ss/user/ntuser/callback.h
trunk/reactos/win32ss/user/ntuser/event.c
trunk/reactos/win32ss/user/ntuser/hook.c
trunk/reactos/win32ss/user/ntuser/message.c
trunk/reactos/win32ss/user/ntuser/msgqueue.c
trunk/reactos/win32ss/user/ntuser/msgqueue.h
trunk/reactos/win32ss/user/user32/windows/hook.c
Modified: trunk/reactos/win32ss/include/callback.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/include/callback.h…
==============================================================================
--- trunk/reactos/win32ss/include/callback.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/include/callback.h [iso-8859-1] Mon Feb 16 03:32:46 2015
@@ -79,6 +79,8 @@
DWORD dwEventThread;
DWORD dwmsEventTime;
WINEVENTPROC Proc;
+ INT Mod;
+ ULONG_PTR offPfn;
} EVENTPROC_CALLBACK_ARGUMENTS, *PEVENTPROC_CALLBACK_ARGUMENTS;
typedef struct _LOADMENU_CALLBACK_ARGUMENTS
Modified: trunk/reactos/win32ss/user/ntuser/callback.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/callba…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/callback.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/callback.c [iso-8859-1] Mon Feb 16 03:32:46 2015
@@ -805,7 +805,9 @@
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime,
- WINEVENTPROC Proc)
+ WINEVENTPROC Proc,
+ INT Mod,
+ ULONG_PTR offPfn)
{
LRESULT Result = 0;
NTSTATUS Status;
@@ -830,6 +832,8 @@
Common->dwEventThread = dwEventThread;
Common->dwmsEventTime = dwmsEventTime;
Common->Proc = Proc;
+ Common->Mod = Mod;
+ Common->offPfn = offPfn;
ResultPointer = NULL;
ResultLength = sizeof(LRESULT);
Modified: trunk/reactos/win32ss/user/ntuser/callback.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/callba…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/callback.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/callback.h [iso-8859-1] Mon Feb 16 03:32:46 2015
@@ -42,7 +42,9 @@
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime,
- WINEVENTPROC Proc);
+ WINEVENTPROC Proc,
+ INT Mod,
+ ULONG_PTR offPfn);
VOID FASTCALL
IntCleanupThreadCallbacks(PTHREADINFO W32Thread);
Modified: trunk/reactos/win32ss/user/ntuser/event.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/event.…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/event.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/event.c [iso-8859-1] Mon Feb 16 03:32:46 2015
@@ -14,6 +14,7 @@
PEVENTHOOK pEH;
LONG idObject;
LONG idChild;
+ LONG idThread;
} EVENTPACK, *PEVENTPACK;
static PEVENTTABLE GlobalEvents = NULL;
@@ -98,11 +99,11 @@
DWORD event,
HWND hwnd,
LONG idObject,
- LONG idChild)
-{
- NTSTATUS Status;
+ LONG idChild,
+ LONG idThread)
+{
PEVENTPACK pEP;
- ULONG_PTR uResult = 0;
+ MSG Msg;
pEP = ExAllocatePoolWithTag(NonPagedPool, sizeof(EVENTPACK), TAG_HOOK);
if (!pEP) return 0;
@@ -110,23 +111,16 @@
pEP->pEH = pEH;
pEP->idObject = idObject;
pEP->idChild = idChild;
-
- /* FIXME: Should get timeout from
- * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
- Status = co_MsqSendMessage( pEH->head.pti,
- hwnd,
- event,
- 0,
- (LPARAM)pEP,
- 300,
- TRUE,
- MSQ_ISEVENT,
- &uResult);
- if (!NT_SUCCESS(Status))
- {
- ExFreePoolWithTag(pEP, TAG_HOOK);
- }
- return NT_SUCCESS(Status) ? uResult : 0;
+ pEP->idThread = idThread;
+
+ Msg.message = event;
+ Msg.hwnd = hwnd;
+ Msg.wParam = 0;
+ Msg.lParam = POSTEVENT_NWE;
+ Msg.time = 0;
+
+ MsqPostMessage(pEH->head.pti, &Msg, FALSE, QS_EVENT, POSTEVENT_NWE,
(LONG_PTR)pEP);
+ return 0;
}
BOOLEAN
@@ -155,7 +149,7 @@
LRESULT
APIENTRY
co_EVENT_CallEvents( DWORD event,
- HWND hwnd,
+ HWND hwnd,
UINT_PTR idObject,
LONG_PTR idChild)
{
@@ -164,15 +158,17 @@
PEVENTPACK pEP = (PEVENTPACK)idChild;
pEH = pEP->pEH;
-
+ TRACE("Dispatch Event 0x%x, idObject %d hwnd %p\n", event, idObject, hwnd);
Result = co_IntCallEventProc( UserHMGetHandle(pEH),
event,
hwnd,
pEP->idObject,
pEP->idChild,
- PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
+ pEP->idThread,
(DWORD)EngGetTickCount(),
- pEH->Proc);
+ pEH->Proc,
+ pEH->ihmod,
+ pEH->offPfn);
ExFreePoolWithTag(pEP, TAG_HOOK);
return Result;
@@ -211,29 +207,19 @@
if (!pEH) break;
UserReferenceObject(pEH);
// Must be inside the event window.
- if ( (pEH->eventMin <= Event) && (pEH->eventMax >= Event))
+ if ( Event >= pEH->eventMin && Event <= pEH->eventMax )
{
// if all process || all thread || other thread same process
// if ^skip own thread && ((Pid && CPid == Pid && ^skip own
process) || all process)
- if ( (!pEH->idProcess || pEH->idProcess ==
PtrToUint(pti->pEThread->Cid.UniqueProcess)) &&
- (!(pEH->Flags & WINEVENT_SKIPOWNPROCESS) || pEH->head.pti->ppi
!= pti->ppi) &&
- (!pEH->idThread || pEH->idThread ==
PtrToUint(pti->pEThread->Cid.UniqueThread)) &&
- (!(pEH->Flags & WINEVENT_SKIPOWNTHREAD) || pEH->head.pti != pti)
&&
- pEH->head.pti->rpdesk == ptiCurrent->rpdesk ) // Same as hooks.
+ if (!( (pEH->idProcess && pEH->idProcess !=
PtrToUint(pti->pEThread->Cid.UniqueProcess)) ||
+ (pEH->Flags & WINEVENT_SKIPOWNPROCESS &&
pEH->head.pti->ppi == pti->ppi) ||
+ (pEH->idThread && pEH->idThread !=
PtrToUint(pti->pEThread->Cid.UniqueThread)) ||
+ (pEH->Flags & WINEVENT_SKIPOWNTHREAD && pEH->head.pti ==
pti) ||
+ pEH->head.pti->rpdesk != ptiCurrent->rpdesk ) ) // Same as
hooks.
{
- // Send message to the thread if pEH is not current.
- if (pEH->head.pti != ptiCurrent)
+ if (pEH->Flags & WINEVENT_INCONTEXT)
{
- ERR("Global Event 0x%x, idObject %d\n", Event, idObject);
- IntCallLowLevelEvent( pEH,
- Event,
- pWnd ? UserHMGetHandle(pWnd) : NULL,
- idObject,
- idChild);
- }
- else
- {
- ERR("Local Event 0x%x, idObject %d\n", Event, idObject);
+ TRACE("In Event 0x%x, idObject %d hwnd %p\n", Event,
idObject, pWnd ? UserHMGetHandle(pWnd) : NULL);
co_IntCallEventProc( UserHMGetHandle(pEH),
Event,
pWnd ? UserHMGetHandle(pWnd) : NULL,
@@ -241,7 +227,19 @@
idChild,
PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
(DWORD)EngGetTickCount(),
- pEH->Proc);
+ pEH->Proc,
+ pEH->ihmod,
+ pEH->offPfn);
+ }
+ else
+ {
+ TRACE("Out Event 0x%x, idObject %d hwnd %p\n", Event,
idObject, pWnd ? UserHMGetHandle(pWnd) : NULL);
+ IntCallLowLevelEvent( pEH,
+ Event,
+ pWnd ? UserHMGetHandle(pWnd) : NULL,
+ idObject,
+ idChild,
+
PtrToUint(NtCurrentTeb()->ClientId.UniqueThread));
}
}
}
@@ -329,10 +327,25 @@
goto SetEventExit;
}
- if ((dwflags & WINEVENT_INCONTEXT) && !hmodWinEventProc)
- {
- EngSetLastError(ERROR_HOOK_NEEDS_HMOD);
- goto SetEventExit;
+ if (dwflags & WINEVENT_INCONTEXT)
+ {
+ if (!hmodWinEventProc)
+ {
+ ERR("Hook needs a module\n");
+ EngSetLastError(ERROR_HOOK_NEEDS_HMOD);
+ goto SetEventExit;
+ }
+ if (puString == NULL)
+ {
+ ERR("Dll not found\n");
+ EngSetLastError(ERROR_DLL_NOT_FOUND);
+ goto SetEventExit;
+ }
+ }
+ else
+ {
+ TRACE("Out of Context\n");
+ hmodWinEventProc = 0;
}
if (idThread)
@@ -371,14 +384,18 @@
If WINEVENT_OUTOFCONTEXT just use proc..
Do this instead....
*/
- if (NULL != hmodWinEventProc)
+ if (hmodWinEventProc != NULL)
{
pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char
*)hmodWinEventProc);
pEH->ihmod = (INT)hmodWinEventProc;
pEH->Proc = lpfnWinEventProc;
}
else
+ {
pEH->Proc = lpfnWinEventProc;
+ pEH->offPfn = 0;
+ pEH->ihmod = (INT)hmodWinEventProc;
+ }
UserDereferenceObject(pEH);
Modified: trunk/reactos/win32ss/user/ntuser/hook.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/hook.c…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/hook.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/hook.c [iso-8859-1] Mon Feb 16 03:32:46 2015
@@ -1251,6 +1251,23 @@
TRACE("\nGlobal Hook posting to another Thread! %d\n",HookId
);
Result = co_IntCallLowLevelHook(Hook, Code, wParam, lParam);
}
+ else if (ptiHook->ppi == pti->ppi)
+ {
+ TRACE("\nGlobal Hook calling to another Thread! %d\n",HookId
);
+ ObReferenceObject(ptiHook->pEThread);
+ IntReferenceThreadInfo(ptiHook);
+ Result = co_IntCallHookProc( HookId,
+ Code,
+ wParam,
+ lParam,
+ Hook->Proc,
+ Hook->ihmod,
+ Hook->offPfn,
+ Hook->Ansi,
+ &Hook->ModuleName);
+ IntDereferenceThreadInfo(ptiHook);
+ ObDereferenceObject(ptiHook->pEThread);
+ }
}
else
{ /* Make the direct call. */
Modified: trunk/reactos/win32ss/user/ntuser/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/messag…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] Mon Feb 16 03:32:46 2015
@@ -652,6 +652,20 @@
return 0;
}
+static LRESULT handle_internal_events( PTHREADINFO pti, PWND pWnd, LONG_PTR ExtraInfo,
PMSG pMsg)
+{
+ LRESULT Result = 0;
+
+ switch(pMsg->lParam)
+ {
+ case POSTEVENT_NWE:
+ {
+ co_EVENT_CallEvents( pMsg->message, pMsg->hwnd, pMsg->wParam,
ExtraInfo);
+ }
+ }
+ return Result;
+}
+
LRESULT FASTCALL
IntDispatchMessage(PMSG pMsg)
{
@@ -845,7 +859,7 @@
ExtraInfo,
Msg ))
{
- return TRUE;
+ return TRUE;
}
/* Only check for quit messages if not posted messages pending. */
@@ -878,6 +892,24 @@
Msg))
{
return TRUE;
+ }
+
+ /* Now check for System Event messages. */
+ {
+ LONG_PTR eExtraInfo;
+ MSG eMsg;
+ if (MsqPeekMessage( pti,
+ TRUE,
+ Window,
+ 0,
+ 0,
+ QS_EVENT,
+ &eExtraInfo,
+ &eMsg ))
+ {
+ handle_internal_events( pti, Window, eExtraInfo, &eMsg);
+ continue;
+ }
}
/* Check for sent messages again. */
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgque…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] Mon Feb 16 03:32:46 2015
@@ -800,13 +800,6 @@
Message->Msg.wParam,
Message->Msg.lParam);
}
- else if (Message->HookMessage == MSQ_ISEVENT)
- { // Direct Event Call processor
- Result = co_EVENT_CallEvents( Message->Msg.message,
- Message->Msg.hwnd,
- Message->Msg.wParam,
- Message->Msg.lParam);
- }
else if(Message->HookMessage == MSQ_INJECTMODULE)
{
Result = IntLoadHookModule(Message->Msg.message,
@@ -2076,6 +2069,13 @@
{
CurrentEntry = RemoveHeadList(&pti->PostedMessagesListHead);
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
+ if (CurrentMessage->dwQEvent)
+ {
+ if (CurrentMessage->dwQEvent == POSTEVENT_NWE)
+ {
+ ExFreePoolWithTag( (PVOID)CurrentMessage->ExtraInfo, TAG_HOOK);
+ }
+ }
MsqDestroyMessage(CurrentMessage);
}
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgque…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] Mon Feb 16 03:32:46 2015
@@ -3,8 +3,7 @@
#define MSQ_HUNG 5000
#define MSQ_NORMAL 0
#define MSQ_ISHOOK 1
-#define MSQ_ISEVENT 2
-#define MSQ_INJECTMODULE 3
+#define MSQ_INJECTMODULE 2
typedef struct _USER_MESSAGE
{
@@ -115,6 +114,8 @@
WM_ASYNC_SETACTIVEWINDOW,
WM_ASYNC_DESTROYWINDOW
};
+
+#define POSTEVENT_NWE 14
BOOL FASTCALL MsqIsHung(PTHREADINFO pti);
VOID CALLBACK HungAppSysTimerProc(HWND,UINT,UINT_PTR,DWORD);
Modified: trunk/reactos/win32ss/user/user32/windows/hook.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/window…
==============================================================================
--- trunk/reactos/win32ss/user/user32/windows/hook.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/windows/hook.c [iso-8859-1] Mon Feb 16 03:32:46
2015
@@ -357,6 +357,9 @@
{
WCHAR ModuleName[MAX_PATH];
UNICODE_STRING USModuleName;
+ PUNICODE_STRING pusmodName;
+
+ RtlInitUnicodeString(&USModuleName, NULL);
if ((hmodWinEventProc != NULL) && (dwFlags & WINEVENT_INCONTEXT))
{
@@ -365,16 +368,17 @@
return NULL;
}
RtlInitUnicodeString(&USModuleName, ModuleName);
+ pusmodName = &USModuleName;
}
else
{
- RtlInitUnicodeString(&USModuleName, NULL);
+ pusmodName = NULL;
}
return NtUserSetWinEventHook(eventMin,
eventMax,
hmodWinEventProc,
- &USModuleName,
+ pusmodName,
pfnWinEventProc,
idProcess,
idThread,
@@ -779,16 +783,53 @@
User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
{
PEVENTPROC_CALLBACK_ARGUMENTS Common;
+ WINEVENTPROC Proc;
+ WCHAR module[MAX_PATH];
+ DWORD len;
+ HMODULE mod = NULL;
+ BOOL Loaded = FALSE;
Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Arguments;
- Common->Proc(Common->hook,
- Common->event,
- Common->hwnd,
- Common->idObject,
- Common->idChild,
- Common->dwEventThread,
- Common->dwmsEventTime);
+ Proc = Common->Proc;
+
+ if (Common->offPfn && Common->Mod)
+ { // Validate the module again.
+ if (!(len = GetModuleFileNameW((HINSTANCE)Common->Mod, module, MAX_PATH)) || len
>= MAX_PATH)
+ {
+ ERR("Error check for module!\n");
+ Common->Mod = 0;
+ }
+
+ if (Common->Mod && !(mod = GetModuleHandleW(module)))
+ {
+ TRACE("Reloading Event Module.\n");
+ if (!(mod = LoadLibraryExW(module, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)))
+ {
+ ERR("Failed to load Event Module.\n");
+ }
+ else
+ {
+ Loaded = TRUE; // Free it only when loaded.
+ }
+ }
+
+ if (mod)
+ {
+ TRACE("Loading Event Module. %S\n",module);
+ Proc = (WINEVENTPROC)((char *)mod + Common->offPfn);
+ }
+ }
+
+ Proc(Common->hook,
+ Common->event,
+ Common->hwnd,
+ Common->idObject,
+ Common->idChild,
+ Common->dwEventThread,
+ Common->dwmsEventTime);
+
+ if (Loaded) FreeLibrary(mod);
return ZwCallbackReturn(NULL, 0, STATUS_SUCCESS);
}