PEVENTHOOK pEH;
LONG idObject;
LONG idChild;
+ LONG idThread;
} EVENTPACK, *PEVENTPACK;
static PEVENTTABLE GlobalEvents = NULL;
DWORD event,
HWND hwnd,
LONG idObject,
- LONG idChild)
+ LONG idChild,
+ LONG idThread)
{
- NTSTATUS Status;
PEVENTPACK pEP;
- ULONG_PTR uResult = 0;
+ MSG Msg;
pEP = ExAllocatePoolWithTag(NonPagedPool, sizeof(EVENTPACK), TAG_HOOK);
if (!pEP) return 0;
pEP->pEH = pEH;
pEP->idObject = idObject;
pEP->idChild = idChild;
+ pEP->idThread = idThread;
- /* 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;
+ 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
LRESULT
APIENTRY
co_EVENT_CallEvents( DWORD event,
- HWND hwnd,
+ HWND hwnd,
UINT_PTR idObject,
LONG_PTR idChild)
{
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;
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,
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));
}
}
}
goto SetEventExit;
}
- if ((dwflags & WINEVENT_INCONTEXT) && !hmodWinEventProc)
+ if (dwflags & WINEVENT_INCONTEXT)
{
- EngSetLastError(ERROR_HOOK_NEEDS_HMOD);
- goto SetEventExit;
+ 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)
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);
{
WCHAR ModuleName[MAX_PATH];
UNICODE_STRING USModuleName;
+ PUNICODE_STRING pusmodName;
+
+ RtlInitUnicodeString(&USModuleName, NULL);
if ((hmodWinEventProc != NULL) && (dwFlags & WINEVENT_INCONTEXT))
{
return NULL;
}
RtlInitUnicodeString(&USModuleName, ModuleName);
+ pusmodName = &USModuleName;
}
else
{
- RtlInitUnicodeString(&USModuleName, NULL);
+ pusmodName = NULL;
}
return NtUserSetWinEventHook(eventMin,
eventMax,
hmodWinEventProc,
- &USModuleName,
+ pusmodName,
pfnWinEventProc,
idProcess,
idThread,
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);
}