KiCheckForTimerExpiration
VOID __stdcall KiCheckForTimerExpiration(_KPRCB *Prcb){
__int64 v1;
INT64 v2;
char v3;
char *v4;
_KPRCB *v6;
char *v7;
unsigned __int8 v8;
__int64 v9;
__int64 v10;
int v11;
_DWORD *v12;
int v13;
unsigned int v14;
unsigned int v15;
unsigned __int64 v16;
UINT64 v17;
char *v18;
UINT64 v19;
unsigned __int8 CurrentIrql;
unsigned int ClockIntervalOneShot;
INT64 v22;
unsigned __int64 v23;
__int16 v24;
__int16 v25;
INT64 Flag;
INT64 v27;
INT64 v28;
__int128 v29;
EVENT_DATA_DESCRIPTOR EventData;
v29 = 0i64;
v3 = 0;
v4 = *(char **)&KUSER_SHARED_DATA.InterruptTime.LowPart;
if( (*((_BYTE *)Prcb + 12588) & 8) == 0 )
{
if( KiSerializeTimerExpiration )
{
if( !*((_BYTE *)Prcb + 33) )
goto LABEL_4;
v6 = KiProcessorBlock;
}
else
{
v6 = Prcb;
}
v7 = (char *)v6 + 14656;
if( v6 != (_KPRCB *)-14656i64 )
{
v8 = *((_QWORD *)v6 + 3944) != KiLastPseudoHrTimerExpiration;
v1 = v8;
if( (KiVelocityFlags & 0x2000) != 0 )
v1 = *((_QWORD *)v6 + 3945) != (_QWORD)KiLastNonHrTimerExpiration;
LOBYTE(v28) = *((_QWORD *)v6 + 3944) != KiLastPseudoHrTimerExpiration;
if( (_BYTE)v1 || v8 )
{
LODWORD(v2) = 0;
v9 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart >> 18;
v10 = 0i64;
v11 = -1;
v12 = (_DWORD *)((char *)v6 + 31568);
while( 1 )
{
v13 = *v12 + 255;
if( (unsigned int)(v9 - *v12) < 0x100 )
v13 = v9;
v14 = *v12 - 1;
while( 1 )
{
++v14;
v15 = v11;
v16 = *(_QWORD *)&v7[32 * v10 + 536 + 32 * (unsigned __int8)v14];
if( (_DWORD)v2 != 1 || (_BYTE)v1 )
break;
if( (unsigned __int64)v4 >= v16 )
{
v11 = v14;
if( v15 < v14 )
v11 = v15;
if( (unsigned __int64)&v4[KePseudoHrTimeIncrement] > (unsigned int)KeNonHrTimeIncrement + v16 )
{
v3 = 1;
KiLastNonHrTimerExpiration = v4;
v1 = 1i64;
v14 = v11;
goto LABEL_22;
}
}
LABEL_19:
if( v14 == v13 )
goto LABEL_20;
}
if( (unsigned __int64)v4 < v16 )
goto LABEL_19;
v3 = 1;
LABEL_20:
if( !(_DWORD)v2 || (_BYTE)v1 )
LABEL_22:
*(_DWORD *)&v7[4 * (unsigned int)v2 + 16912] = v14;
v2 = (unsigned int)(v2 + 1);
++v12;
v10 += 256i64;
LODWORD(v9) = v13;
if( (unsigned int)v2 >= 2 )
{
v8 = v28;
break;
}
}
}
if( !*((_BYTE *)Prcb + 33) )
goto LABEL_5;
if( !(_BYTE)v1
&& v8
&& (unsigned __int64)v4 >= qword_140C31A98
&& (unsigned __int64)&v4[KePseudoHrTimeIncrement] > (unsigned __int64)(unsigned int)KeNonHrTimeIncrement
+ qword_140C31A98 )
{
KiLastNonHrTimerExpiration = v4;
LABEL_59:
v3 = 1;
goto LABEL_4;
}
if( v3 )
goto LABEL_4;
if( (_BYTE)v1 )
{
if( KiNextTimer2DueTime <= (unsigned __int64)v4 )
v3 = 1;
}
else if( v8 && qword_140C31A80 <= (unsigned __int64)v4 || DueTime <= (unsigned __int64)v4 )
{
goto LABEL_59;
}
}
}
LABEL_4:
if( !*((_BYTE *)Prcb + 33) )
goto LABEL_5;
v17 = DueTime;
v18 = &v4[KeMaximumIncrement];
if( DueTime > (unsigned __int64)v4 )
{
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)v4);
PoTraceSystemTimerResolutionKernel(ClockIntervalOneShot, 0x534F5248ui64);
}
__writecr8(CurrentIrql);
}
LABEL_5:
if( !v3 )
return;
}
HIDWORD(v28) = 0;
_m_prefetchw((char *)Prcb + 12588);
v22 = *((unsigned __int16 *)Prcb + 6294);
v23 = (unsigned __int16)v22;
BYTE1(v23) = HIBYTE(*((_WORD *)Prcb + 6294));
v24 = *((_WORD *)Prcb + 6294);
if( v24 != _InterlockedCompareExchange16((volatile signed __int16 *)Prcb + 6294, v22 | 8, v22) )
{
do
{
RtlBackoff((UINT64 *)((char *)&v28 + 4));
_m_prefetchw((char *)Prcb + 12588);
v22 = *((unsigned __int16 *)Prcb + 6294);
v23 = (unsigned __int16)v22;
BYTE1(v23) = HIBYTE(*((_WORD *)Prcb + 6294));
v25 = *((_WORD *)Prcb + 6294);
}
while( v25 != _InterlockedCompareExchange16((volatile signed __int16 *)Prcb + 6294, v22 | 8, v22) );
}
if( (v22 & 0x29) == 0 )
{
if( *((_BYTE *)Prcb + 32) )
{
*((_BYTE *)Prcb + 6) = 1;
}
else
{
LOBYTE(v23) = 2;
HalRequestSoftwareInterrupt(
(VOID *)v23,
v22,
(INT64 *)v1,
v2,
Flag,
v27,
v28,
v29,
*((INT64 *)&v29 + 1),
EventData.Ptr,
*(INT64 *)&EventData.Size);
}
}
}Referenced by:
KeAccumulateTicks