KiRundownMutants
VOID __stdcall KiRundownMutants(_ETHREAD *Thread){
_LIST_ENTRY *p_MutantListHead;
unsigned int v3;
int v4;
UINT8 CurrentIrql;
_KPRCB *CurrentPrcb;
_LIST_ENTRY *Flink;
unsigned __int64 p_Blink;
__int64 v9;
_QWORD *v10;
_KWAIT_BLOCK *v11;
_LIST_ENTRY *v12;
_KWAIT_BLOCK *v13;
_LIST_ENTRY *Blink;
unsigned __int8 WaitType;
bool v16;
_ETHREAD *v17;
_QWORD *v18;
struct _KPRCB *v19;
_ETHREAD *CurrentThread;
char v21;
int v22;
_KWAIT_BLOCK **QuantumTarget;
__int64 v24;
VOID **v25;
__int64 v26;
VOID **v27;
__int64 v28;
int v29;
unsigned int v30;
UINT8 OldIrql;
_KPRCB *Prcb;
UINT64 SpinCount;
_KTHREAD *WakeThread;
__int64 v35[32];
memset(v35, 0i64, sizeof(v35));
WakeThread = 0i64;
p_MutantListHead = &Thread->Tcb.MutantListHead;
if( p_MutantListHead->Flink == p_MutantListHead )
return;
v3 = 0;
v4 = 0;
v30 = 0;
v29 = 0;
CurrentIrql = KeGetCurrentIrql();
OldIrql = CurrentIrql;
__writecr8(2ui64);
LABEL_4:
CurrentPrcb = KeGetCurrentPrcb();
Prcb = CurrentPrcb;
while( 1 )
{
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( Thread->Tcb.ThreadLock );
}
Flink = p_MutantListHead->Flink;
if( p_MutantListHead->Flink == p_MutantListHead )
break;
p_Blink = (unsigned __int64)&Flink[-2].Blink;
if( BYTE1(Flink[1].Blink) )
KeBugCheckEx(0x4000008Au, Thread, &Flink[-2].Blink, 0i64, 0i64);
if( !_interlockedbittestandset((volatile signed __int32 *)p_Blink, 7u) )
goto LABEL_10;
KiReleaseThreadLockSafe((INT64)Thread);
ExAcquireSpinLockSharedAtDpcLevel((PEX_SPIN_LOCK)&KiObjectRundownLocks + 16 * ((p_Blink >> 4) & 0x3F));
if( Flink != p_MutantListHead->Flink )
goto LABEL_24;
KiAcquireKobjectLockSafe(&Flink[-2].Blink);
if( *(_ETHREAD **)(p_Blink + 40) != Thread )
{
_InterlockedAnd((volatile signed __int32 *)p_Blink, 0xFFFFFF7F);
LABEL_24:
Flink = 0i64;
}
ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)&KiObjectRundownLocks + 16 * ((p_Blink >> 4) & 0x3F));
CurrentIrql = OldIrql;
if( Flink )
{
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( Thread->Tcb.ThreadLock );
}
LABEL_10:
v9 = *(_QWORD *)(p_Blink + 24);
v10 = *(_QWORD **)(p_Blink + 32);
if( *(_QWORD *)(v9 + 8) != p_Blink + 24 || *v10 != p_Blink + 24 )
LABEL_56:
__fastfail(3u);
*v10 = v9;
*(_QWORD *)(v9 + 8) = v10;
KiReleaseThreadLockSafe((INT64)Thread);
*(_BYTE *)(p_Blink + 48) |= 1u;
v11 = *(_KWAIT_BLOCK **)(p_Blink + 8);
*(_QWORD *)(p_Blink + 40) = 0i64;
*(_DWORD *)(p_Blink + 4) = 1;
if( v11 != (_KWAIT_BLOCK *)(p_Blink + 8) )
{
while( 1 )
{
v12 = v11->WaitListEntry.Flink;
v13 = v11;
v11 = (_KWAIT_BLOCK *)v12;
Blink = v13->WaitListEntry.Blink;
if( (_KWAIT_BLOCK *)v12->Blink != v13 || (_KWAIT_BLOCK *)Blink->Flink != v13 )
goto LABEL_56;
Blink->Flink = v12;
v12->Blink = Blink;
WaitType = v13->WaitType;
if( WaitType == 1 )
{
if( KiTryUnwaitThread(CurrentPrcb, v13, v13->WaitKey, (_KTHREAD **)&WakeThread) )
{
v16 = (*(_DWORD *)(p_Blink + 4))-- == 1;
if( v16 )
goto LABEL_50;
}
}
else if( WaitType == 2 )
{
v13->BlockState = 5;
v17 = v13->Thread;
v13->WaitListEntry.Flink = 0i64;
v18 = &v17->Tcb.gap0[8];
KeGetCurrentIrql();
__writecr8(2ui64);
v19 = KeGetCurrentPrcb();
CurrentThread = v19->CurrentThread;
KiAcquireKobjectLockSafe(v17);
if( (_QWORD *)*v18 == v18
|| LODWORD(v17->Tcb.InitialStack) >= HIDWORD(v17->Tcb.InitialStack)
|| (_ETHREAD *)CurrentThread->Tcb.Queue == v17 && CurrentThread->Tcb.WaitReason == 15
|| (KiWakeQueueWaiter(v19, (_KQUEUE *)v17, (INT64)v13), !v21) )
{
v22 = *(_DWORD *)&v17->Tcb.gap0[4];
*(_DWORD *)&v17->Tcb.gap0[4] = v22 + 1;
QuantumTarget = (_KWAIT_BLOCK **)v17->Tcb.QuantumTarget;
if( *QuantumTarget != (_KWAIT_BLOCK *)&v17->Tcb.SListFaultAddress )
goto LABEL_56;
v13->WaitListEntry.Flink = (_LIST_ENTRY *)&v17->Tcb.SListFaultAddress;
v13->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
*QuantumTarget = v13;
v17->Tcb.QuantumTarget = (unsigned __int64)v13;
if( !v22 && (_QWORD *)*v18 != v18 )
KiWakeOtherQueueWaiters(v19, (_KQUEUE *)v17);
}
_InterlockedAnd((volatile signed __int32 *)v17, 0xFFFFFF7F);
v16 = (*(_DWORD *)(p_Blink + 4))-- == 1;
if( v16 )
{
LABEL_50:
v3 = v30;
v4 = v29;
break;
}
CurrentPrcb = Prcb;
}
else
{
KiTryUnwaitThread(CurrentPrcb, v13, 256i64, 0i64);
}
if( v11 == (_KWAIT_BLOCK *)(p_Blink + 8) )
goto LABEL_50;
}
}
if( (*(_BYTE *)(p_Blink + 48) & 2) != 0 )
{
v24 = v3++;
v30 = v3;
v35[v24] = p_Blink;
}
_InterlockedAnd((volatile signed __int32 *)p_Blink, 0xFFFFFF7F);
CurrentPrcb = Prcb;
p_MutantListHead = &Thread->Tcb.MutantListHead;
CurrentIrql = OldIrql;
v29 = ++v4;
if( v4 == 32 )
{
CurrentIrql = OldIrql;
KiExitDispatcher(Prcb, 0i64, AdjustUnwait, 1i64, OldIrql);
if( v3 )
{
v25 = (VOID **)v35;
v26 = v3;
do
{
KeAbPostRelease(*v25++);
--v26;
}
while( v26 );
CurrentIrql = OldIrql;
}
v4 = 0;
v3 = 0;
v29 = 0;
v30 = 0;
KeGetCurrentIrql();
__writecr8(2ui64);
p_MutantListHead = &Thread->Tcb.MutantListHead;
goto LABEL_4;
}
}
}
KiReleaseThreadLockSafe((INT64)Thread);
KiExitDispatcher(CurrentPrcb, 0i64, AdjustUnwait, 1i64, CurrentIrql);
if( v3 )
{
v27 = (VOID **)v35;
v28 = v3;
do
{
KeAbPostRelease(*v27++);
--v28;
}
while( v28 );
}
}Referenced by:
PspExitThread