KePulseEvent
NTSTATUS __stdcall KePulseEvent(PRKEVENT Event, KPRIORITY Increment, BOOL Wait){
char v4;
_KPRCB *CurrentPrcb;
_KWAIT_BLOCK *v6;
_KWAIT_BLOCK *Flink;
_KWAIT_BLOCK *v9;
unsigned __int8 WaitType;
INT64 WaitKey;
_LIST_ENTRY *v12;
_KWAIT_BLOCK *v13;
_LIST_ENTRY *Blink;
unsigned __int8 v15;
bool v16;
_ETHREAD *v17;
_QWORD *v18;
struct _KPRCB *v19;
_ETHREAD *v20;
char v21;
int v22;
_KWAIT_BLOCK **v23;
_ETHREAD *Thread;
_QWORD *v25;
struct _KPRCB *v26;
_ETHREAD *CurrentThread;
char v28;
int v29;
_KWAIT_BLOCK **QuantumTarget;
UINT8 OldIrql;
NTSTATUS v32;
_KPRCB *Prcb;
v4 = *(_BYTE *)Event & 0x7F;
OldIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
Prcb = CurrentPrcb;
KiAcquireKobjectLockSafe(Event);
v32 = *((_DWORD *)Event + 1);
if( !v32 )
{
*((_DWORD *)Event + 1) = 1;
v6 = (_KWAIT_BLOCK *)((char *)Event + 8);
Flink = (_KWAIT_BLOCK *)*((_QWORD *)Event + 1);
if( !v4 )
{
while( 1 )
{
if( Flink == v6 )
{
*((_QWORD *)Event + 2) = (char *)Event + 8;
v6->WaitListEntry.Flink = &v6->WaitListEntry;
goto LABEL_5;
}
v9 = Flink;
Flink = (_KWAIT_BLOCK *)Flink->WaitListEntry.Flink;
WaitType = v9->WaitType;
if( WaitType == 1 )
break;
if( WaitType == 2 )
{
v9->BlockState = 5;
Thread = v9->Thread;
v9->WaitListEntry.Flink = 0i64;
v25 = &Thread->Tcb.gap0[8];
KeGetCurrentIrql();
__writecr8(2ui64);
v26 = KeGetCurrentPrcb();
CurrentThread = v26->CurrentThread;
KiAcquireKobjectLockSafe(Thread);
if( (_QWORD *)*v25 == v25
|| LODWORD(Thread->Tcb.InitialStack) >= HIDWORD(Thread->Tcb.InitialStack)
|| (_ETHREAD *)CurrentThread->Tcb.Queue == Thread && CurrentThread->Tcb.WaitReason == 15
|| (KiWakeQueueWaiter(v26, (_KQUEUE *)Thread, (INT64)v9), !v28) )
{
v29 = *(_DWORD *)&Thread->Tcb.gap0[4];
*(_DWORD *)&Thread->Tcb.gap0[4] = v29 + 1;
QuantumTarget = (_KWAIT_BLOCK **)Thread->Tcb.QuantumTarget;
if( *QuantumTarget != (_KWAIT_BLOCK *)&Thread->Tcb.SListFaultAddress )
goto LABEL_42;
v9->WaitListEntry.Flink = (_LIST_ENTRY *)&Thread->Tcb.SListFaultAddress;
v9->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
*QuantumTarget = v9;
Thread->Tcb.QuantumTarget = (unsigned __int64)v9;
if( !v29 && (_QWORD *)*v25 != v25 )
KiWakeOtherQueueWaiters(v26, (_KQUEUE *)Thread);
}
_InterlockedAnd((volatile signed __int32 *)Thread, 0xFFFFFF7F);
CurrentPrcb = Prcb;
}
else
{
WaitKey = 256i64;
LABEL_8:
KiTryUnwaitThread(CurrentPrcb, v9, WaitKey, 0i64);
}
}
WaitKey = v9->WaitKey;
goto LABEL_8;
}
while( 1 )
{
while( 1 )
{
if( Flink == v6 )
goto LABEL_5;
v12 = Flink->WaitListEntry.Flink;
v13 = Flink;
Flink = (_KWAIT_BLOCK *)v12;
Blink = v13->WaitListEntry.Blink;
if( (_KWAIT_BLOCK *)v12->Blink != v13 || (_KWAIT_BLOCK *)Blink->Flink != v13 )
LABEL_42:
__fastfail(3u);
Blink->Flink = v12;
v12->Blink = Blink;
v15 = v13->WaitType;
if( v15 == 1 )
break;
if( v15 == 2 )
{
v13->BlockState = 5;
v17 = v13->Thread;
v13->WaitListEntry.Flink = 0i64;
v18 = &v17->Tcb.gap0[8];
KeGetCurrentIrql();
__writecr8(2ui64);
v19 = KeGetCurrentPrcb();
v20 = v19->CurrentThread;
KiAcquireKobjectLockSafe(v17);
if( (_QWORD *)*v18 == v18
|| LODWORD(v17->Tcb.InitialStack) >= HIDWORD(v17->Tcb.InitialStack)
|| (_ETHREAD *)v20->Tcb.Queue == v17 && v20->Tcb.WaitReason == 15
|| (KiWakeQueueWaiter(v19, (_KQUEUE *)v17, (INT64)v13), !v21) )
{
v22 = *(_DWORD *)&v17->Tcb.gap0[4];
*(_DWORD *)&v17->Tcb.gap0[4] = v22 + 1;
v23 = (_KWAIT_BLOCK **)v17->Tcb.QuantumTarget;
if( *v23 != (_KWAIT_BLOCK *)&v17->Tcb.SListFaultAddress )
goto LABEL_42;
v13->WaitListEntry.Flink = (_LIST_ENTRY *)&v17->Tcb.SListFaultAddress;
v13->WaitListEntry.Blink = (_LIST_ENTRY *)v23;
*v23 = v13;
v17->Tcb.QuantumTarget = (unsigned __int64)v13;
if( !v22 && (_QWORD *)*v18 != v18 )
KiWakeOtherQueueWaiters(v19, (_KQUEUE *)v17);
}
_InterlockedAnd((volatile signed __int32 *)v17, 0xFFFFFF7F);
v16 = (*((_DWORD *)Event + 1))-- == 1;
if( v16 )
goto LABEL_5;
CurrentPrcb = Prcb;
}
else
{
KiTryUnwaitThread(CurrentPrcb, v13, 256i64, 0i64);
}
}
if( KiTryUnwaitThread(CurrentPrcb, v13, v13->WaitKey, 0i64) )
{
v16 = (*((_DWORD *)Event + 1))-- == 1;
if( v16 )
break;
}
}
}
LABEL_5:
*((_DWORD *)Event + 1) = 0;
_InterlockedAnd((volatile signed __int32 *)Event, 0xFFFFFF7F);
KiExitDispatcher(Prcb, Wait ? 3 : 0, AdjustUnwait, (unsigned int)Increment, OldIrql);
return v32;
}Referenced by:
KeBalanceSetManager
MiAddPhysicalMemory
MiPulseCommitSignal
MiPulseLowAvailableEvent
MiRemovePhysicalMemory
MiWorkingSetManager
MmResourcesAvailable
NtPulseEvent