KeRegisterObjectNotification
UINT8 __stdcall KeRegisterObjectNotification(PVOID Object, _KQUEUE *NotificationQueue, _KWAIT_BLOCK *WaitBlock){
UINT8 OldIrql;
_LIST_ENTRY *v7;
_LIST_ENTRY *p_WaitListHead;
struct _KPRCB *CurrentPrcb;
__int64 v11;
int SignalState;
_LIST_ENTRY *Blink;
*(_WORD *)&WaitBlock->WaitType = 1026;
WaitBlock->Thread = (_ETHREAD *)NotificationQueue;
WaitBlock->Object = Object;
OldIrql = KeGetCurrentIrql();
__writecr8(2ui64);
KiAcquireKobjectLockSafe(Object);
if( *((int *)Object + 1) <= 0 )
{
v7 = (_LIST_ENTRY *)*((_QWORD *)Object + 2);
if( (char *)v7->Flink == (char *)Object + 8 )
{
WaitBlock->WaitListEntry.Blink = v7;
WaitBlock->WaitListEntry.Flink = (_LIST_ENTRY *)((char *)Object + 8);
v7->Flink = &WaitBlock->WaitListEntry;
*((_QWORD *)Object + 2) = WaitBlock;
_InterlockedAnd((volatile signed __int32 *)Object, 0xFFFFFF7F);
__writecr8(OldIrql);
return 0;
}
LABEL_13:
__fastfail(3u);
}
KiWaitSatisfyOther((KMUTANT *)Object);
WaitBlock->BlockState = 5;
p_WaitListHead = &NotificationQueue->Header.WaitListHead;
WaitBlock->WaitListEntry.Flink = 0i64;
KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
v11 = *((_QWORD *)CurrentPrcb + 1);
KiAcquireKobjectLockSafe(NotificationQueue);
if( p_WaitListHead->Flink == p_WaitListHead
|| NotificationQueue->CurrentCount >= NotificationQueue->MaximumCount
|| *(_KQUEUE **)(v11 + 232) == NotificationQueue && *(_BYTE *)(v11 + 643) == 15
|| !KiWakeQueueWaiter(CurrentPrcb, NotificationQueue, (INT64)WaitBlock) )
{
SignalState = NotificationQueue->Header.SignalState;
NotificationQueue->Header.SignalState = SignalState + 1;
Blink = NotificationQueue->EntryListHead.Blink;
if( Blink->Flink != &NotificationQueue->EntryListHead )
goto LABEL_13;
WaitBlock->WaitListEntry.Flink = &NotificationQueue->EntryListHead;
WaitBlock->WaitListEntry.Blink = Blink;
Blink->Flink = &WaitBlock->WaitListEntry;
NotificationQueue->EntryListHead.Blink = &WaitBlock->WaitListEntry;
if( !SignalState && p_WaitListHead->Flink != p_WaitListHead )
KiWakeOtherQueueWaiters(CurrentPrcb, NotificationQueue);
}
_InterlockedAnd(&NotificationQueue->Header.Lock, 0xFFFFFF7F);
_InterlockedAnd((volatile signed __int32 *)Object, 0xFFFFFF7F);
KiExitDispatcher(KeGetCurrentPrcb(), 0i64, AdjustUnwait, 0i64, OldIrql);
return 1;
}Referenced by:
ExpTryEnterWorkerFactoryAwayMode
ExpWorkerFactoryInitialization
ExpWorkerFactoryManagerThread
NtCreateWorkerFactory
NtWaitForWorkViaWorkerFactory