KiExpireTimer2
VOID __stdcall KiExpireTimer2(_KTIMER2 *Timer, _KPRCB *Prcb, UINT64 CurrentTime, _KDPC_TRACKER_TABLE *DpcTracker){
_ETHREAD *CurrentThread;
UINT64 v6;
_KPRCB *v7;
int v8;
__int64 Period;
_KTIMER2 *v10;
char v11;
_KTIMER2 *v12;
__int64 v13;
_KWAIT_BLOCK *v14;
_LIST_ENTRY *Blink;
unsigned __int8 TypeFlags;
unsigned __int64 v17;
char v18;
unsigned __int64 v19;
unsigned __int8 WaitType;
_ETHREAD *Thread;
_QWORD *v22;
struct _KPRCB *CurrentPrcb;
char v24;
bool v25;
void(__fastcall *v26)(_KTIMER2 *, unsigned __int64);
int v27;
int v28;
signed __int32 v29;
signed __int32 v30;
int v31;
_KWAIT_BLOCK **QuantumTarget;
unsigned __int64 v33;
_KDPC_TRACKER_TABLE *v34;
INT64 v35;
INT64 v36;
__int64 v37;
_KDPC_TRACKER_TABLE *v38;
signed __int32 v39;
signed __int32 v40;
unsigned __int64 v41;
unsigned __int64 v42;
_KTIMER2 *v43;
_KTIMER2 *v44;
bool v45;
_KTIMER2 *v46;
unsigned __int64 v47;
UINT64 v48;
unsigned __int8 v49;
unsigned __int64 v50;
__int64 v51;
unsigned __int64 v52;
unsigned __int64 v53;
unsigned __int64 v54;
_KWAIT_BLOCK *v55;
unsigned __int8 v56;
INT64 WaitKey;
_ETHREAD *v58;
_QWORD *v59;
_ETHREAD *v60;
_KPRCB *v61;
char v62;
int v63;
_KWAIT_BLOCK **v64;
signed __int32 v65;
UINT8 WasLate;
char v67;
_KPRCB *Prcba;
_ETHREAD *v69;
INT64 v70;
PVOID BugCheckParameter3;
INT64 CurrentQpc;
_KDPC_TRACKER_TABLE *v73;
__int64 Data;
__int64 v75;
__int64 v76;
__int64 v77;
__int64 v78;
__int64 v79;
__int64 v80;
_LARGE_INTEGER TimeStamp[2];
__int128 v82;
CurrentThread = Prcb->CurrentThread;
v73 = DpcTracker;
v70 = (INT64)Prcb;
v6 = CurrentTime;
Data = 0i64;
v7 = Prcb;
v75 = 0i64;
v8 = 0;
v77 = 0i64;
v78 = 0i64;
v79 = 0i64;
v80 = 0i64;
*(_OWORD *)&TimeStamp[0].anonymous_0.LowPart = 0i64;
CurrentQpc = 0i64;
v82 = 0i64;
LODWORD(BugCheckParameter3) = CurrentThread->Tcb.WaitBlock[3].SpareLong;
v76 = 0i64;
WasLate = 0;
v69 = CurrentThread;
Period = Timer->Period;
if( !Period || (Timer->gap0[1] & 0x20) != 0 )
goto LABEL_2;
TypeFlags = Timer->TypeFlags;
if( (TypeFlags & 4) != 0 )
{
LODWORD(v48) = RtlGetInterruptTimePrecise(&CurrentQpc);
Period = Timer->Period;
v6 = v48;
TypeFlags = Timer->TypeFlags;
}
v17 = Period + v6;
if( Period + v6 < v6 || v17 == -1i64 )
{
v17 = -2i64;
v18 = 1;
}
else
{
v18 = 0;
}
v67 = v18;
if( (TypeFlags & 0xE) == 0 )
{
if( (KiVelocityFlags & 0x2000) != 0 )
{
v43 = *(_KTIMER2 **)&Timer->gap0[8];
v44 = (_KTIMER2 *)&Timer->gap0[8];
if( v43 == (_KTIMER2 *)&Timer->gap0[8] )
{
LABEL_54:
if( (TypeFlags & 0x10) == 0 )
goto LABEL_13;
v49 = TypeFlags & 0xEF;
goto LABEL_69;
}
while( 1 )
{
v45 = v43->gap0[16] <= 1u;
v46 = v43;
v43 = *(_KTIMER2 **)v43->gap0;
if( v45 )
{
if( PsTimerResolutionActive(*(_QWORD *)(*(_QWORD *)&v46->gap0[24] + 544i64)) )
break;
}
if( v43 == v44 )
goto LABEL_54;
}
if( (TypeFlags & 0x10) != 0 )
goto LABEL_13;
}
else if( (TypeFlags & 0x10) != 0 )
{
goto LABEL_13;
}
v49 = TypeFlags | 0x10;
LABEL_69:
Timer->TypeFlags = v49;
KiUpdateTimer2Collections(Timer);
}
LABEL_13:
v19 = Timer->DueTime[1];
if( v19 != -1i64 )
{
v41 = v19 - Timer->DueTime[0];
if( v41 )
{
v47 = v41 + v6;
if( v41 + v6 < v6 || v47 == -1i64 )
v47 = -2i64;
v42 = v47 + Timer->Period;
if( v42 < v47 || v42 == -1i64 )
v42 = -2i64;
}
else
{
v42 = v17;
}
Timer->DueTime[1] = v42;
}
Timer->DueTime[0] = v17;
while( !KiInsertTimer2(Timer, 0, &WasLate) )
{
if( v18 )
goto LABEL_2;
v50 = Timer->DueTime[0];
v51 = Timer->Period;
v52 = v50 + v51;
if( v50 + v51 < v50 || v52 == -1i64 )
{
v52 = -2i64;
v18 = 1;
}
Timer->DueTime[0] = v52;
v53 = Timer->DueTime[1];
v67 = v18;
if( v53 != -1i64 )
{
v54 = v53 + v51;
if( v53 + v51 < v53 || v54 == -1i64 )
v54 = -2i64;
Timer->DueTime[1] = v54;
}
}
v8 = 1;
LABEL_2:
v10 = (_KTIMER2 *)&Timer->gap0[8];
v11 = Timer->gap0[0] & 0x7F;
v12 = *(_KTIMER2 **)&Timer->gap0[8];
*(_DWORD *)&Timer->gap0[4] = 1;
if( v11 == 25 )
{
if( v12 == v10 )
goto LABEL_26;
while( 1 )
{
v13 = *(_QWORD *)v12->gap0;
v14 = (_KWAIT_BLOCK *)v12;
v12 = (_KTIMER2 *)v13;
Blink = v14->WaitListEntry.Blink;
if( *(_KWAIT_BLOCK **)(v13 + 8) != v14 || (_KWAIT_BLOCK *)Blink->Flink != v14 )
goto LABEL_5;
Blink->Flink = (_LIST_ENTRY *)v13;
*(_QWORD *)(v13 + 8) = Blink;
WaitType = v14->WaitType;
if( WaitType == 1 )
{
if( KiTryUnwaitThread(v7, v14, v14->WaitKey, 0i64) )
{
v25 = (*(_DWORD *)&Timer->gap0[4])-- == 1;
if( v25 )
{
LABEL_25:
CurrentThread = v69;
goto LABEL_26;
}
}
}
else if( WaitType == 2 )
{
v14->BlockState = 5;
Thread = v14->Thread;
v14->WaitListEntry.Flink = 0i64;
v22 = &Thread->Tcb.gap0[8];
KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
Prcba = (_KPRCB *)CurrentPrcb->CurrentThread;
KiAcquireKobjectLockSafe(Thread);
if( (_QWORD *)*v22 == v22
|| LODWORD(Thread->Tcb.InitialStack) >= HIDWORD(Thread->Tcb.InitialStack)
|| *(_ETHREAD **)&Prcba->CFlushSize == Thread && BYTE3(Prcba->ProcessorState.ContextFrame._Rbx) == 15
|| (KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)Thread, (INT64)v14), !v24) )
{
v31 = *(_DWORD *)&Thread->Tcb.gap0[4];
*(_DWORD *)&Thread->Tcb.gap0[4] = v31 + 1;
QuantumTarget = (_KWAIT_BLOCK **)Thread->Tcb.QuantumTarget;
if( *QuantumTarget != (_KWAIT_BLOCK *)&Thread->Tcb.SListFaultAddress )
goto LABEL_5;
v14->WaitListEntry.Flink = (_LIST_ENTRY *)&Thread->Tcb.SListFaultAddress;
v14->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
*QuantumTarget = v14;
Thread->Tcb.QuantumTarget = (unsigned __int64)v14;
if( !v31 && (_QWORD *)*v22 != v22 )
KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)Thread);
}
_InterlockedAnd((volatile signed __int32 *)Thread, 0xFFFFFF7F);
v25 = (*(_DWORD *)&Timer->gap0[4])-- == 1;
v7 = (_KPRCB *)v70;
if( v25 )
goto LABEL_25;
}
else
{
KiTryUnwaitThread(v7, v14, 256i64, 0i64);
}
if( v12 == (_KTIMER2 *)&Timer->gap0[8] )
goto LABEL_25;
}
}
if( v12 != v10 )
{
while( 1 )
{
v55 = (_KWAIT_BLOCK *)v12;
v12 = *(_KTIMER2 **)v12->gap0;
v56 = v55->WaitType;
if( v56 == 1 )
{
WaitKey = v55->WaitKey;
LABEL_98:
KiTryUnwaitThread(v7, v55, WaitKey, 0i64);
goto LABEL_99;
}
if( v56 != 2 )
{
WaitKey = 256i64;
goto LABEL_98;
}
v55->BlockState = 5;
v58 = v55->Thread;
v55->WaitListEntry.Flink = 0i64;
v59 = &v58->Tcb.gap0[8];
KeGetCurrentIrql();
__writecr8(2ui64);
Prcba = KeGetCurrentPrcb();
v60 = Prcba->CurrentThread;
KiAcquireKobjectLockSafe(v58);
if( (_QWORD *)*v59 == v59
|| LODWORD(v58->Tcb.InitialStack) >= HIDWORD(v58->Tcb.InitialStack)
|| (_ETHREAD *)v60->Tcb.Queue == v58 && v60->Tcb.WaitReason == 15 )
{
break;
}
v61 = Prcba;
KiWakeQueueWaiter(Prcba, (_KQUEUE *)v58, (INT64)v55);
if( !v62 )
goto LABEL_92;
LABEL_96:
_InterlockedAnd((volatile signed __int32 *)v58, 0xFFFFFF7F);
v7 = (_KPRCB *)v70;
LABEL_99:
v10 = (_KTIMER2 *)&Timer->gap0[8];
if( v12 == (_KTIMER2 *)&Timer->gap0[8] )
{
CurrentThread = v69;
goto LABEL_62;
}
}
v61 = Prcba;
LABEL_92:
v63 = *(_DWORD *)&v58->Tcb.gap0[4];
*(_DWORD *)&v58->Tcb.gap0[4] = v63 + 1;
v64 = (_KWAIT_BLOCK **)v58->Tcb.QuantumTarget;
if( *v64 != (_KWAIT_BLOCK *)&v58->Tcb.SListFaultAddress )
LABEL_5:
__fastfail(3u);
v55->WaitListEntry.Flink = (_LIST_ENTRY *)&v58->Tcb.SListFaultAddress;
v55->WaitListEntry.Blink = (_LIST_ENTRY *)v64;
*v64 = v55;
v58->Tcb.QuantumTarget = (unsigned __int64)v55;
if( !v63 && (_QWORD *)*v59 != v59 )
KiWakeOtherQueueWaiters(v61, (_KQUEUE *)v58);
goto LABEL_96;
}
LABEL_62:
*(_QWORD *)&v10->gap0[8] = v10;
*(_QWORD *)v10->gap0 = v10;
LABEL_26:
v26 = (void(__fastcall *)(_KTIMER2 *, unsigned __int64))(KiWaitAlways ^ _byteswap_uint64((unsigned __int64)Timer ^ __ROL8__(KiWaitNever ^ (__int64)Timer->Callback, KiWaitNever)));
if( v26 )
{
v33 = KiWaitAlways ^ _byteswap_uint64((unsigned __int64)Timer ^ __ROL8__(
KiWaitNever ^ (__int64)Timer->CallbackContext,
KiWaitNever));
KiUpdateTimer2Flags(Timer, v8 | 0x10u, 0i64);
if( v7->DeferredReadyListHead.Next )
KiProcessThreadWaitList(v7, AdjustUnwait, 0i64, 2ui64);
v34 = v73;
v35 = v70;
v36 = v70;
v37 = ((*v73)++ & 0xF) + 1i64;
v38 = &v34[4 * v37];
*(_QWORD *)v38 = v26;
v38[2] = KUSER_SHARED_DATA.TickCount.LowPart;
*(_DWORD *)(v36 + 32412) = 0;
KiResetGlobalDpcWatchdogProfiler(v36);
*(_BYTE *)(v35 + 12586) = 1;
v26(Timer, v33);
*(_BYTE *)(v35 + 12586) = 0;
v38[3] = KUSER_SHARED_DATA.TickCount.LowPart;
_m_prefetchw(Timer);
v39 = *(_DWORD *)Timer->gap0;
do
{
v40 = v39;
v39 = _InterlockedCompareExchange((volatile signed __int32 *)Timer, v39 & 0xFFFFEFFF, v39);
}
while( v40 != v39 );
if( (v39 & 0x2F00) == 0x2000 )
goto LABEL_29;
}
else
{
v27 = *(_DWORD *)Timer->gap0;
v28 = v8 << 8;
v29 = v28 | *(_DWORD *)Timer->gap0 & 0xFFFFF07F;
v30 = _InterlockedCompareExchange((volatile signed __int32 *)Timer, v29, *(_DWORD *)Timer->gap0);
if( v27 != v30 )
{
do
{
v65 = v30;
v29 = v28 | v30 & 0xFFFFF07F;
v30 = _InterlockedCompareExchange((volatile signed __int32 *)Timer, v29, v30);
}
while( v65 != v30 );
}
if( (v29 & 0x3F00) == 0x2000 )
LABEL_29:
KiFinalizeTimer2Disablement(Timer);
}
if( (_DWORD)BugCheckParameter3 != CurrentThread->Tcb.WaitBlock[3].SpareLong )
KeBugCheckEx(
0xC7u,
(PVOID)5,
v26,
(PVOID)(unsigned int)BugCheckParameter3,
(PVOID)CurrentThread->Tcb.CombinedApcDisable);
}Referenced by:
KiTimer2Expiration