KiCheckForTimerExpiration
VOID __stdcall KiCheckForTimerExpiration(_KPRCB *Prcb){
char v1;
char *v2;
_KPRCB *v4;
_KTIMER_TABLE *p_TimerTable;
bool v6;
bool v7;
unsigned int v8;
__int64 v9;
__int64 v10;
int v11;
unsigned int *LastTimerHand;
int v13;
unsigned int v14;
unsigned int v15;
unsigned __int64 QuadPart;
UINT64 v17;
char *v18;
UINT64 v19;
unsigned __int8 CurrentIrql;
unsigned int ClockIntervalOneShot;
unsigned __int16 v22;
UINT64 v23;
bool v24;
unsigned int v25;
__int128 v26;
v26 = 0i64;
v1 = 0;
v2 = *(char **)&KUSER_SHARED_DATA.InterruptTime.LowPart;
if( (Prcb->DpcRequestSummary & 8) == 0 )
{
if( KiSerializeTimerExpiration )
{
if( !Prcb->ClockOwner )
goto LABEL_4;
v4 = KiProcessorBlock;
}
else
{
v4 = Prcb;
}
p_TimerTable = &v4->TimerTable;
if( v4 != (_KPRCB *)-14656i64 )
{
v6 = v4->TimerTable.TableState.LastTimerExpiration[0] != KiLastPseudoHrTimerExpiration;
v7 = v6;
if( (KiVelocityFlags & 0x2000) != 0 )
v7 = v4->TimerTable.TableState.LastTimerExpiration[1] != (_QWORD)KiLastNonHrTimerExpiration;
v24 = v4->TimerTable.TableState.LastTimerExpiration[0] != KiLastPseudoHrTimerExpiration;
if( v7 || v4->TimerTable.TableState.LastTimerExpiration[0] != KiLastPseudoHrTimerExpiration )
{
v8 = 0;
v9 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart >> 18;
v10 = 0i64;
v11 = -1;
LastTimerHand = v4->TimerTable.TableState.LastTimerHand;
while( 1 )
{
v13 = *LastTimerHand + 255;
if( (unsigned int)v9 - *LastTimerHand < 0x100 )
v13 = v9;
v14 = *LastTimerHand - 1;
while( 1 )
{
++v14;
v15 = v11;
QuadPart = p_TimerTable->TimerEntries[v10][(unsigned __int8)v14].Time.QuadPart;
if( v8 != 1 || v7 )
break;
if( (unsigned __int64)v2 >= QuadPart )
{
v11 = v14;
if( v15 < v14 )
v11 = v15;
if( (unsigned __int64)&v2[KePseudoHrTimeIncrement] > (unsigned int)KeNonHrTimeIncrement + QuadPart )
{
v1 = 1;
KiLastNonHrTimerExpiration = v2;
v7 = 1;
v14 = v11;
goto LABEL_22;
}
}
LABEL_19:
if( v14 == v13 )
goto LABEL_20;
}
if( (unsigned __int64)v2 < QuadPart )
goto LABEL_19;
v1 = 1;
LABEL_20:
if( !v8 || v7 )
LABEL_22:
p_TimerTable->TableState.LastTimerHand[v8] = v14;
++v8;
++LastTimerHand;
++v10;
LODWORD(v9) = v13;
if( v8 >= 2 )
{
v6 = v24;
break;
}
}
}
if( !Prcb->ClockOwner )
goto LABEL_5;
if( !v7
&& v6
&& (unsigned __int64)v2 >= qword_140C31A98
&& (unsigned __int64)&v2[KePseudoHrTimeIncrement] > (unsigned __int64)(unsigned int)KeNonHrTimeIncrement
+ qword_140C31A98 )
{
KiLastNonHrTimerExpiration = v2;
LABEL_59:
v1 = 1;
goto LABEL_4;
}
if( v1 )
goto LABEL_4;
if( v7 )
{
if( KiNextTimer2DueTime <= (unsigned __int64)v2 )
v1 = 1;
}
else if( v6 && qword_140C31A80 <= (unsigned __int64)v2 || DueTime <= (unsigned __int64)v2 )
{
goto LABEL_59;
}
}
}
LABEL_4:
if( !Prcb->ClockOwner )
goto LABEL_5;
v17 = DueTime;
v18 = &v2[(unsigned int)KeMaximumIncrement];
if( DueTime > (unsigned __int64)v2 )
{
v19 = KiClockOwnerOneShotRequest;
if( !KiClockOwnerOneShotRequest )
v19 = -1i64;
if( v19 != DueTime )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(0xFui64);
if( (unsigned __int64)v18 <= v17 )
{
if( KiClockOwnerOneShotRequest )
{
PoTraceSystemTimerResolutionKernel(0i64, 0x534F5248ui64);
KiClockOwnerOneShotRequest = 0i64;
KiSetClockIntervalToMinimumRequested();
}
}
else
{
KiClockOwnerOneShotRequest = v17;
KiSetClockIntervalToMinimumRequested();
ClockIntervalOneShot = KiGetClockIntervalOneShot(v17, (INT64)v2);
PoTraceSystemTimerResolutionKernel(ClockIntervalOneShot, 0x534F5248ui64);
}
__writecr8(CurrentIrql);
}
LABEL_5:
if( !v1 )
return;
}
v25 = 0;
_m_prefetchw(&Prcb->12588);
v22 = Prcb->DpcRequestSlot[0];
v23 = v22;
for( BYTE1(v23) = HIBYTE(v22);
v22 != _InterlockedCompareExchange16((volatile signed __int16 *)&Prcb->12588, v22 | 8, v22);
BYTE1(v23) = HIBYTE(v22) )
{
RtlBackoff(&v25);
_m_prefetchw(&Prcb->12588);
v22 = Prcb->DpcRequestSlot[0];
v23 = v22;
}
if( (v22 & 0x29) == 0 )
{
if( Prcb->NestingLevel )
{
Prcb->InterruptRequest = 1;
}
else
{
LOBYTE(v23) = 2;
HalRequestSoftwareInterrupt(v23);
}
}
}Referenced by:
KeAccumulateTicks