[WIN32K:NTUSER]

- Use UserRefObjectCo in IntNotifyWinEvent to avoid a reference leak in case the call-out does not return
- Sanitize list walk

svn path=/trunk/; revision=67907
This commit is contained in:
Thomas Faber 2015-05-25 15:28:06 +00:00
parent 950f55d8b7
commit 596e134bad

View file

@ -184,8 +184,9 @@ IntNotifyWinEvent(
DWORD flags) DWORD flags)
{ {
PEVENTHOOK pEH; PEVENTHOOK pEH;
PLIST_ENTRY pLE; PLIST_ENTRY ListEntry;
PTHREADINFO pti, ptiCurrent; PTHREADINFO pti, ptiCurrent;
USER_REFERENCE_ENTRY Ref;
TRACE("IntNotifyWinEvent GlobalEvents = %p pWnd %p\n", GlobalEvents, pWnd); TRACE("IntNotifyWinEvent GlobalEvents = %p pWnd %p\n", GlobalEvents, pWnd);
@ -200,12 +201,13 @@ IntNotifyWinEvent(
else else
pti = ptiCurrent; pti = ptiCurrent;
pLE = GlobalEvents->Events.Flink; ListEntry = GlobalEvents->Events.Flink;
pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain); ASSERT(ListEntry != &GlobalEvents->Events);
do while (ListEntry != &GlobalEvents->Events)
{ {
if (!pEH) break; pEH = CONTAINING_RECORD(ListEntry, EVENTHOOK, Chain);
UserReferenceObject(pEH); ListEntry = ListEntry->Flink;
// Must be inside the event window. // Must be inside the event window.
if ( Event >= pEH->eventMin && Event <= pEH->eventMax ) if ( Event >= pEH->eventMin && Event <= pEH->eventMax )
{ {
@ -217,6 +219,7 @@ IntNotifyWinEvent(
(pEH->Flags & WINEVENT_SKIPOWNTHREAD && pEH->head.pti == pti) || (pEH->Flags & WINEVENT_SKIPOWNTHREAD && pEH->head.pti == pti) ||
pEH->head.pti->rpdesk != ptiCurrent->rpdesk ) ) // Same as hooks. pEH->head.pti->rpdesk != ptiCurrent->rpdesk ) ) // Same as hooks.
{ {
UserRefObjectCo(pEH, &Ref);
if (pEH->Flags & WINEVENT_INCONTEXT) if (pEH->Flags & WINEVENT_INCONTEXT)
{ {
TRACE("In Event 0x%x, idObject %d hwnd %p\n", Event, idObject, pWnd ? UserHMGetHandle(pWnd) : NULL); TRACE("In Event 0x%x, idObject %d hwnd %p\n", Event, idObject, pWnd ? UserHMGetHandle(pWnd) : NULL);
@ -241,12 +244,10 @@ IntNotifyWinEvent(
idChild, idChild,
PtrToUint(NtCurrentTeb()->ClientId.UniqueThread)); PtrToUint(NtCurrentTeb()->ClientId.UniqueThread));
} }
UserDerefObjectCo(pEH);
}
} }
} }
UserDereferenceObject(pEH);
pLE = pEH->Chain.Flink;
pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
} while (pLE != &GlobalEvents->Events);
} }
VOID VOID