KiTimerWaitTest
_KDPC *__stdcall KiTimerWaitTest(_KPRCB *Prcb, _KTIMER *Timer, _ULARGE_INTEGER *SystemTime){
char v3;
unsigned __int16 v4;
__int64 Period;
char v7;
_ULARGE_INTEGER *v9;
unsigned __int64 v10;
UINT8 v11;
__int64 v12;
unsigned __int64 v13;
_KTIMER *v14;
_KTIMER *v15;
UINT64 v16;
_KWAIT_BLOCK *Flink;
_KWAIT_BLOCK *v18;
_KWAIT_BLOCK *v20;
unsigned __int8 WaitType;
INT64 WaitKey;
_KWAIT_BLOCK *v23;
_KWAIT_BLOCK *v24;
_KWAIT_BLOCK **Blink;
unsigned __int8 v26;
bool v27;
_QWORD *v28;
_ETHREAD *v29;
char v30;
bool v31;
_KTIMER *v32;
int v33;
_KWAIT_BLOCK **QuantumTarget;
_QWORD *v35;
_ETHREAD *v36;
int v37;
_ETHREAD **v38;
char v39;
unsigned int PeriodicBias;
_QWORD *v41;
_KPRCB *Prcba;
_KPRCB *Prcbb;
__int64 v44;
_ETHREAD *CurrentThread;
__int128 v46;
__int64 v47;
_ETHREAD *Object;
_ETHREAD *Objecta;
_KWAIT_BLOCK *Entry;
INT64 Entrya;
v3 = Timer->gap0[0];
v4 = 0;
v47 = 0i64;
Period = (int)Timer->Period;
v7 = v3 & 0x7F;
v44 = 0i64;
v9 = SystemTime;
v10 = KiWaitAlways ^ _byteswap_uint64((unsigned __int64)Timer ^ __ROL8__(
(__int64)Timer->Dpc ^ KiWaitNever,
KiWaitNever));
v11 = -1;
v46 = 0i64;
if( (_DWORD)Period )
{
v12 = -10000 * Period;
v11 = 0;
if( Prcb->DpcRoutineActive )
{
if( ++Prcb->PeriodicCount >= 0xBB8 )
{
PeriodicBias = Prcb->PeriodicBias;
Prcb->PeriodicCount = 0;
if( PeriodicBias < 0x5F5E100 )
Prcb->PeriodicBias = KeTimeIncrement + PeriodicBias;
}
v12 -= Prcb->PeriodicBias;
}
if( (signed __int64)(v12 + *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart - Timer->DueTime.QuadPart) >= 0 )
Timer->DueTime.QuadPart = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
v13 = 0i64;
LODWORD(v46) = *(_DWORD *)Timer->gap0;
if( BYTE1(v46) >= 4u )
v13 = (unsigned __int64)(BYTE1(v46) & 0xFC) << 16;
if( (KiVelocityFlags & 0x2000) != 0 )
{
v14 = *(_KTIMER **)&Timer->gap0[8];
Timer->TimerType = 1;
v15 = (_KTIMER *)&Timer->gap0[8];
if( v14 == (_KTIMER *)&Timer->gap0[8] )
goto LABEL_9;
while( 1 )
{
v31 = v14->gap0[16] <= 1u;
v32 = v14;
v14 = *(_KTIMER **)v14->gap0;
if( v31 )
{
if( PsTimerResolutionActive(*(_QWORD *)(v32->DueTime.QuadPart + 544)) )
break;
}
if( v14 == v15 )
goto LABEL_9;
}
}
Timer->TimerType = v4;
LABEL_9:
BYTE1(v46) &= ~1u;
BYTE3(v46) = 64;
do
{
Timer->DueTime.QuadPart -= v12;
BYTE2(v46) = (v13 + Timer->DueTime.QuadPart) >> 18;
v16 = BYTE2(v46);
*(_DWORD *)Timer->gap0 = v46;
}
while( !KiInsertTimerTable(Prcb, Timer, (_KDPC *)v10, v16, 0i64) );
v9 = SystemTime;
}
Flink = *(_KWAIT_BLOCK **)&Timer->gap0[8];
v18 = (_KWAIT_BLOCK *)&Timer->gap0[8];
*(_DWORD *)&Timer->gap0[4] = 1;
if( v7 == 8 )
{
if( Flink == v18 )
{
LABEL_14:
*(_QWORD *)&Timer->gap0[16] = &Timer->gap0[8];
v18->WaitListEntry.Flink = &v18->WaitListEntry;
goto LABEL_15;
}
while( 1 )
{
v20 = Flink;
Flink = (_KWAIT_BLOCK *)Flink->WaitListEntry.Flink;
WaitType = v20->WaitType;
if( WaitType == 1 )
{
WaitKey = v20->WaitKey;
}
else
{
if( WaitType == 2 )
{
v20->BlockState = 5;
Object = v20->Thread;
Entrya = (INT64)&Object->Tcb.gap0[8];
v20->WaitListEntry.Flink = 0i64;
KeGetCurrentIrql();
__writecr8(2ui64);
Prcba = KeGetCurrentPrcb();
CurrentThread = Prcba->CurrentThread;
KiAcquireKobjectLockSafe(Object);
v28 = (_QWORD *)Entrya;
v29 = Object;
if( (_QWORD *)*v28 == v28
|| LODWORD(Object->Tcb.InitialStack) >= HIDWORD(Object->Tcb.InitialStack)
|| (_ETHREAD *)CurrentThread->Tcb.Queue == Object && CurrentThread->Tcb.WaitReason == 15 )
{
LABEL_52:
v33 = *(_DWORD *)&v29->Tcb.gap0[4];
*(_DWORD *)&v29->Tcb.gap0[4] = v33 + 1;
QuantumTarget = (_KWAIT_BLOCK **)v29->Tcb.QuantumTarget;
if( *QuantumTarget != (_KWAIT_BLOCK *)&v29->Tcb.SListFaultAddress )
goto LABEL_32;
v20->WaitListEntry.Flink = (_LIST_ENTRY *)&v29->Tcb.SListFaultAddress;
v20->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
*QuantumTarget = v20;
v29->Tcb.QuantumTarget = (unsigned __int64)v20;
if( !v33 && (_QWORD *)*v28 != v28 )
{
KiWakeOtherQueueWaiters(Prcba, (_KQUEUE *)v29);
v29 = Object;
}
}
else
{
KiWakeQueueWaiter(Prcba, (_KQUEUE *)Object, (INT64)v20);
v29 = Object;
if( !v30 )
{
v28 = &Object->Tcb.gap0[8];
goto LABEL_52;
}
}
_InterlockedAnd((volatile signed __int32 *)v29, 0xFFFFFF7F);
goto LABEL_26;
}
WaitKey = 256i64;
}
KiTryUnwaitThread(Prcb, v20, WaitKey, 0i64);
LABEL_26:
if( Flink == v18 )
goto LABEL_14;
}
}
if( Flink != v18 )
{
while( 1 )
{
v23 = (_KWAIT_BLOCK *)Flink->WaitListEntry.Flink;
v24 = Flink;
Entry = Flink;
Flink = v23;
Blink = (_KWAIT_BLOCK **)Entry->WaitListEntry.Blink;
if( (_KWAIT_BLOCK *)v23->WaitListEntry.Blink != Entry || *Blink != v24 )
LABEL_32:
__fastfail(3u);
*Blink = v23;
v23->WaitListEntry.Blink = (_LIST_ENTRY *)Blink;
v26 = v24->WaitType;
if( v26 != 1 )
break;
if( KiTryUnwaitThread(Prcb, v24, v24->WaitKey, 0i64) )
{
v27 = (*(_DWORD *)&Timer->gap0[4])-- == 1;
if( v27 )
goto LABEL_15;
}
LABEL_39:
if( Flink == v18 )
goto LABEL_15;
}
if( v26 != 2 )
{
KiTryUnwaitThread(Prcb, v24, 256i64, 0i64);
goto LABEL_39;
}
v24->BlockState = 5;
Objecta = v24->Thread;
v41 = &Objecta->Tcb.gap0[8];
v24->WaitListEntry.Flink = 0i64;
KeGetCurrentIrql();
__writecr8(2ui64);
Prcbb = KeGetCurrentPrcb();
CurrentThread = Prcbb->CurrentThread;
KiAcquireKobjectLockSafe(Objecta);
v35 = v41;
v36 = Objecta;
if( (_QWORD *)*v35 != v35
&& LODWORD(Objecta->Tcb.InitialStack) < HIDWORD(Objecta->Tcb.InitialStack)
&& ((_ETHREAD *)CurrentThread->Tcb.Queue != Objecta || CurrentThread->Tcb.WaitReason != 15) )
{
KiWakeQueueWaiter(Prcbb, (_KQUEUE *)Objecta, (INT64)Entry);
v36 = Objecta;
if( v39 )
goto LABEL_67;
v35 = &Objecta->Tcb.gap0[8];
}
v37 = *(_DWORD *)&v36->Tcb.gap0[4];
*(_DWORD *)&v36->Tcb.gap0[4] = v37 + 1;
v38 = (_ETHREAD **)v36->Tcb.QuantumTarget;
if( *v38 != (_ETHREAD *)&v36->Tcb.SListFaultAddress )
goto LABEL_32;
Entry->WaitListEntry.Flink = (_LIST_ENTRY *)&v36->Tcb.SListFaultAddress;
Entry->WaitListEntry.Blink = (_LIST_ENTRY *)v38;
*v38 = (_ETHREAD *)Entry;
v36->Tcb.QuantumTarget = (unsigned __int64)Entry;
if( !v37 && (_QWORD *)*v35 != v35 )
{
KiWakeOtherQueueWaiters(Prcbb, (_KQUEUE *)v36);
v36 = Objecta;
}
LABEL_67:
_InterlockedAnd((volatile signed __int32 *)v36, 0xFFFFFF7F);
v27 = (*(_DWORD *)&Timer->gap0[4])-- == 1;
if( v27 )
goto LABEL_15;
goto LABEL_39;
}
LABEL_15:
if( v10 )
{
if( v9 )
{
if( (!KiSerializeTimerExpiration || *(_WORD *)(v10 + 2) < 0x500u)
&& (*(_BYTE *)v10 != 26 || !Prcb->ThreadDpcEnable) )
{
Prcb->DpcData[0].ActiveDpc = (_KDPC *volatile)v10;
if( (Prcb->GroupSetMember & *(_QWORD *)(v10 + 16)) == 0 )
_interlockedbittestandset64((volatile signed __int32 *)(v10 + 16), Prcb->GroupIndex);
goto LABEL_21;
}
}
else
{
v9 = (_ULARGE_INTEGER *)&v44;
v44 = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
}
KiInsertQueueDpc((_KDPC *)v10, (VOID *)v9->LowPart, (VOID *)v9->HighPart, Timer, v11);
return 0i64;
}
LABEL_21:
_InterlockedAnd((volatile signed __int32 *)Timer, ~((v11 << 24) | 0x80));
return(_KDPC *)v10;
}Referenced by:
ExpSetTimerObject
KeSetTimerEx
KiAdjustTimerDueTimes
KiCommitThreadWait
KiProcessExpiredTimerList
KiResumeThread
KiSetTimerEx