KeRegisterObjectNotification
VOID __fastcall KeRegisterObjectNotification(VOID *Object, _KQUEUE *NotificationQueue, _KWAIT_BLOCK *WaitBlock){
UINT8 OldIrql;
_LIST_ENTRY *v7;
_QWORD *v8;
struct _KPRCB *CurrentPrcb;
_ETHREAD *CurrentThread;
char v11;
int v12;
_LIST_ENTRY *v13;
*(_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;
}
LABEL_13:
__fastfail(3u);
}
KiWaitSatisfyOther((_KMUTANT *)Object);
WaitBlock->BlockState = 5;
v8 = (_QWORD *)((char *)NotificationQueue + 8);
WaitBlock->WaitListEntry.Flink = 0i64;
KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
CurrentThread = CurrentPrcb->CurrentThread;
KiAcquireKobjectLockSafe(NotificationQueue);
if( (_QWORD *)*v8 == v8
|| *((_DWORD *)NotificationQueue + 10) >= *((_DWORD *)NotificationQueue + 11)
|| (_KQUEUE *)CurrentThread->Tcb.Queue == NotificationQueue && CurrentThread->Tcb.WaitReason == 15
|| (KiWakeQueueWaiter(CurrentPrcb, NotificationQueue, (INT64)WaitBlock), !v11) )
{
v12 = *((_DWORD *)NotificationQueue + 1);
*((_DWORD *)NotificationQueue + 1) = v12 + 1;
v13 = (_LIST_ENTRY *)*((_QWORD *)NotificationQueue + 4);
if( v13->Flink != (_LIST_ENTRY *)((char *)NotificationQueue + 24) )
goto LABEL_13;
WaitBlock->WaitListEntry.Flink = (_LIST_ENTRY *)((char *)NotificationQueue + 24);
WaitBlock->WaitListEntry.Blink = v13;
v13->Flink = &WaitBlock->WaitListEntry;
*((_QWORD *)NotificationQueue + 4) = WaitBlock;
if( !v12 && (_QWORD *)*v8 != v8 )
KiWakeOtherQueueWaiters(CurrentPrcb, NotificationQueue);
}
_InterlockedAnd((volatile signed __int32 *)NotificationQueue, 0xFFFFFF7F);
_InterlockedAnd((volatile signed __int32 *)Object, 0xFFFFFF7F);
KiExitDispatcher(KeGetCurrentPrcb(), 0i64, AdjustUnwait, 0i64, OldIrql);
}Referenced by:
ExpTryEnterWorkerFactoryAwayMode
ExpWorkerFactoryInitialization
ExpWorkerFactoryManagerThread
NtCreateWorkerFactory
NtWaitForWorkViaWorkerFactory