KiUpdateTimeAssist
VOID __stdcall KiUpdateTimeAssist(UINT64 *InputQpcTicks, UINT64 *NewInterruptTime, UINT64 *CurrentTick){
LARGE_INTEGER *v5;
LARGE_INTEGER PerformanceCounter;
unsigned __int128 v7;
unsigned __int64 v8;
__int64 v9;
unsigned __int64 v10;
unsigned __int64 v11;
volatile unsigned __int64 TickCountQuad;
__int64 v13;
volatile CCHAR v14;
RtlWriteAcquireTickLock((INT64 *)&KUSER_SHARED_DATA.TimeUpdateLock);
if( v5 )
PerformanceCounter = *v5;
else
PerformanceCounter = KeQueryPerformanceCounter(0i64);
v7 = KiComputeNewSystemTime(PerformanceCounter.QuadPart);
v9 = v7;
v10 = 1i64;
if( v8 > KUSER_SHARED_DATA.BaselineInterruptTimeQpc )
{
v11 = v8 - KUSER_SHARED_DATA.BaselineInterruptTimeQpc;
if( KUSER_SHARED_DATA.QpcInterruptTimeIncrementShift )
v11 <<= KUSER_SHARED_DATA.QpcInterruptTimeIncrementShift;
v7 = v11 * (unsigned __int128)KUSER_SHARED_DATA.QpcInterruptTimeIncrement;
KiInterruptTimeErrorAccumulator += v7;
if( KiInterruptTimeErrorAccumulator < (unsigned __int64)v7 )
++*((_QWORD *)&v7 + 1);
}
*NewInterruptTime = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart + *((_QWORD *)&v7 + 1);
KUSER_SHARED_DATA.SystemTime.High2Time = HIDWORD(v9);
*(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart = v9;
KUSER_SHARED_DATA.InterruptTime.High2Time = *((_DWORD *)NewInterruptTime + 1);
*(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart = *NewInterruptTime;
KUSER_SHARED_DATA.BaselineSystemTimeQpc = v8;
KUSER_SHARED_DATA.BaselineInterruptTimeQpc = v8;
TickCountQuad = KUSER_SHARED_DATA.TickCountQuad;
v13 = (unsigned int)KiTickOffset - *((_QWORD *)&v7 + 1);
*CurrentTick = KUSER_SHARED_DATA.TickCountQuad;
if( v13 <= 0 )
{
v13 += KeMaximumIncrement;
if( v13 <= 0 )
{
v14 = KeNumberProcessorsGroup0[2];
v10 = ((unsigned __int64)(((unsigned __int64)-v13
* (unsigned __int128)(unsigned __int64)KiMaximumIncrementReciprocal) >> 64) >> v14)
+ 2;
LODWORD(v13) = (((unsigned __int64)(((unsigned __int64)-v13
* (unsigned __int128)(unsigned __int64)KiMaximumIncrementReciprocal) >> 64) >> v14)
+ 1)
* KeMaximumIncrement
+ v13;
}
*CurrentTick = TickCountQuad + v10;
KUSER_SHARED_DATA.TickCount.High2Time = *((_DWORD *)CurrentTick + 1);
KUSER_SHARED_DATA.TickCountQuad = *CurrentTick;
}
++KUSER_SHARED_DATA.TimeUpdateLock;
KiTickOffset = v13;
}Referenced by:
KeResumeClockTimerFromIdle
KeSynchronizeTimeToQpc