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/callbac... ============================================================================== --- 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/callbac... ============================================================================== --- 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.c... ============================================================================== --- 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/message... ============================================================================== --- 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/msgqueu... ============================================================================== --- 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/msgqueu... ============================================================================== --- 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/windows... ============================================================================== --- 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); }