HalpTimerPerformanceCounterPowerChange
VOID **__fastcall HalpTimerPerformanceCounterPowerChange(INT64 BugCheckParameter3, VOID *a2, UINT64 a3, VOID *a4){
VOID **result;
__int64(__fastcall **v5)(_QWORD);
__int64 v6;
int v7;
void *v8;
void *v9;
unsigned __int64 v10;
INT64 v11;
__int64 v12;
__int64 v13;
__int64 v14;
signed __int64 v15;
int v16;
unsigned __int64 v17;
__int64 v18;
__int64 v19;
unsigned __int64 v20;
signed __int64 v21;
__int64 v22;
__int64 v23;
__int64 v24;
PVOID v25;
UINT64 v26;
void *v27;
void *v28;
char *v29;
INT64 v30;
_QWORD *v31;
__int64 v32;
__int64 v33;
__int64 v34;
__int64 v35;
__int64 v36;
UINT64 v37;
signed __int64 v38;
void *v39;
UINT64 v40;
__int64 v41;
__int64 v42;
char *v43;
__int64 v44;
__int64 v45;
__int64 v46;
char *v47;
PVOID v48;
__int64 v49;
__int64 v50;
__int64 v51;
unsigned __int64 v52;
signed __int64 v53;
int v54;
unsigned __int64 v55;
__int64 v56;
__int64 v57;
unsigned __int64 v58;
signed __int64 v59;
__int64 v60;
__int64 v61;
__int64 v62;
INT64 v63;
UINT64 v64;
void *v65;
unsigned __int64 v66;
void *v67;
unsigned __int64 v68;
__int64 v69;
__int64 v70;
__int64 v71;
signed __int64 v72;
int v73;
unsigned __int64 v74;
unsigned __int64 v75;
signed __int64 v76;
__int64 v77;
__int64 v78;
__int64 v79;
PVOID v80;
char *v81;
void *v82;
void *v83;
int v84;
signed __int32 v85[8];
void *retaddr;
result = &retaddr;
v5 = (__int64(__fastcall **)(_QWORD))HalpTimerSavedPerformanceCounter;
if( HalpTimerSavedPerformanceCounter )
{
if( (PVOID)BugCheckParameter3 == HalpTimerSavedPerformanceCounter && (_BYTE)a2 )
{
HalpTimerGetInternalData((_KDPC *)HalpTimerSavedPerformanceCounter, a2, (PVOID)a3, a4);
v7 = v5[13](v6);
if( v7 < 0 )
KeBugCheckEx(0x5Cu, (PVOID)0x113, (PVOID)0xF, v5, (PVOID)v7);
if( HalpTimerDelayedQueryHardwareCount )
{
*(_QWORD *)(HalpPerformanceCounter + 112) = HalpTimerDelayedQueryHardwareCount;
HalpTimerDelayedQueryHardwareCount = 0i64;
}
v11 = HalpPerformanceCounter;
if( *(_DWORD *)(HalpPerformanceCounter + 220) == 64 )
{
HalpTimerGetInternalData((_KDPC *)HalpPerformanceCounter, v8, v9, (PVOID)v10);
v24 = (*(__int64(__fastcall **)(__int64))(v11 + 112))(v23);
v12 = *(_QWORD *)(v11 + 208);
v21 = v24;
}
else
{
do
{
v12 = *(_QWORD *)(v11 + 208);
do
{
v13 = *(_QWORD *)(v11 + 200);
HalpTimerGetInternalData((_KDPC *)v11, v8, v9, (PVOID)v10);
v10 = (*(__int64(__fastcall **)(__int64))(v11 + 112))(v14);
_InterlockedOr(v85, 0);
v15 = *(_QWORD *)(v11 + 200);
}
while( v13 != v15 );
}
while( v12 != *(_QWORD *)(v11 + 208) );
v16 = *(_DWORD *)(v11 + 220);
v17 = v13 ^ v10;
if( _bittest64((const __int64 *)&v17, (unsigned __int8)(v16 - 1)) )
{
v18 = 1i64;
if( v16 == 64 )
v19 = -1i64;
else
v19 = (1i64 << v16) - 1;
if( v16 != 64 )
v18 = 1i64 << v16;
v20 = v13 & v19;
v21 = v10 | v13 ^ v20;
if( v10 < v20 )
v21 += v18;
_InterlockedCompareExchange64((volatile signed __int64 *)(v11 + 200), v21, v15);
}
else
{
if( v16 == 64 )
v22 = -1i64;
else
v22 = (1i64 << v16) - 1;
v21 = v10 | v13 & ~v22;
}
}
v25 = HalpTimerSavedPerformanceCounter;
v26 = HalpTimerScaleCounter(
v12 + v21,
*(_QWORD *)(HalpPerformanceCounter + 192),
*((_QWORD *)HalpTimerSavedPerformanceCounter + 24));
v29 = (char *)*((_QWORD *)v25 + 2);
if( v26 >= (unsigned __int64)v29 )
v29 = (char *)v26;
result = (VOID **)HalpTimerCalibratePerformanceCounter((INT64)v5, v29, v27, v28);
if( (int)result < 0 )
KeBugCheckEx(0x5Cu, (PVOID)0x113, (PVOID)0x26, v5, (PVOID)(int)result);
HalpTimerSavedPerformanceCounter = 0i64;
HalpPerformanceCounter = (INT64)v5;
}
}
else
{
v30 = HalpPerformanceCounter;
if( BugCheckParameter3 == HalpPerformanceCounter && !(_BYTE)a2 )
{
v31 = HalpAlwaysOnCounter;
HalpTimerSavedPerformanceCounter = (PVOID)HalpPerformanceCounter;
if( !HalpAlwaysOnCounter )
KeBugCheckEx(
(_DWORD)HalpAlwaysOnCounter + 92,
(PVOID)0x113,
(PVOID)(unsigned int)((_DWORD)HalpAlwaysOnCounter + 34),
(PVOID)BugCheckParameter3,
0i64);
v32 = -1i64;
v33 = 1i64;
if( *(_DWORD *)(HalpPerformanceCounter + 220) == 64 )
{
HalpTimerGetInternalData((_KDPC *)HalpPerformanceCounter, a2, (PVOID)a3, a4);
v46 = (*(__int64(__fastcall **)(__int64))(v30 + 112))(v45);
v34 = *(_QWORD *)(v30 + 208);
v43 = (char *)v46;
}
else
{
do
{
v34 = *(_QWORD *)(v30 + 208);
do
{
v35 = *(_QWORD *)(v30 + 200);
HalpTimerGetInternalData((_KDPC *)v30, a2, (PVOID)a3, a4);
v37 = (*(__int64(__fastcall **)(__int64))(v30 + 112))(v36);
_InterlockedOr(v85, 0);
v38 = *(_QWORD *)(v30 + 200);
}
while( v35 != v38 );
}
while( v34 != *(_QWORD *)(v30 + 208) );
v39 = (void *)*(unsigned int *)(v30 + 220);
v40 = v35 ^ v37;
if( _bittest64((const __int64 *)&v40, (unsigned __int8)((_BYTE)v39 - 1)) )
{
if( (_DWORD)v39 == 64 )
v41 = -1i64;
else
v41 = (1i64 << (char)v39) - 1;
v42 = 1i64;
if( (_DWORD)v39 != 64 )
v42 = 1i64 << (char)v39;
a3 = v35 & v41;
v43 = (char *)(v37 | v35 ^ a3);
if( v37 < a3 )
v43 += v42;
_InterlockedCompareExchange64((volatile signed __int64 *)(v30 + 200), (signed __int64)v43, v38);
}
else
{
if( (_DWORD)v39 == 64 )
v44 = -1i64;
else
v44 = (1i64 << (char)v39) - 1;
v43 = (char *)(v37 | v35 & ~v44);
}
}
v47 = &v43[v34];
v48 = HalpAlwaysOnCounter;
*(_QWORD *)(HalpPerformanceCounter + 16) = v47;
if( *((_DWORD *)v48 + 55) == 64 )
{
HalpTimerGetInternalData((_KDPC *)v48, v43, (PVOID)a3, v39);
v62 = (*((__int64(__fastcall **)(__int64))v48 + 14))(v61);
v49 = *((_QWORD *)v48 + 26);
v59 = v62;
}
else
{
do
{
v49 = *((_QWORD *)v48 + 26);
do
{
v50 = *((_QWORD *)v48 + 25);
HalpTimerGetInternalData((_KDPC *)v48, v43, (PVOID)a3, v39);
v52 = (*((__int64(__fastcall **)(__int64))v48 + 14))(v51);
_InterlockedOr(v85, 0);
v53 = *((_QWORD *)v48 + 25);
}
while( v50 != v53 );
}
while( v49 != *((_QWORD *)v48 + 26) );
v54 = *((_DWORD *)v48 + 55);
v55 = v50 ^ v52;
if( _bittest64((const __int64 *)&v55, (unsigned __int8)(v54 - 1)) )
{
if( v54 == 64 )
v56 = -1i64;
else
v56 = (1i64 << v54) - 1;
v57 = 1i64;
if( v54 != 64 )
v57 = 1i64 << v54;
v58 = v50 & v56;
v59 = v52 | v50 ^ v58;
if( v52 < v58 )
v59 += v57;
_InterlockedCompareExchange64((volatile signed __int64 *)v48 + 25, v59, v53);
}
else
{
if( v54 == 64 )
v60 = -1i64;
else
v60 = (1i64 << v54) - 1;
v59 = v52 | v50 & ~v60;
}
}
v63 = HalpPerformanceCounter;
v64 = HalpTimerScaleCounter(
v49 + v59,
*((_QWORD *)HalpAlwaysOnCounter + 24),
*(_QWORD *)(HalpPerformanceCounter + 192));
v67 = (void *)(v64 - (_QWORD)v47);
v68 = (unsigned __int64)&v47[-v64];
if( (unsigned __int64)v47 <= v64 )
v68 = v64 - (_QWORD)v47;
if( v68 > HalpTimerMaximumAllowableDrift )
{
++HalpTimerDriftReadjustmentCount;
if( *(_DWORD *)(v63 + 220) == 64 )
{
HalpTimerGetInternalData((_KDPC *)v63, v67, v65, (PVOID)v66);
v79 = (*(__int64(__fastcall **)(__int64))(v63 + 112))(v78);
v69 = *(_QWORD *)(v63 + 208);
v76 = v79;
}
else
{
do
{
v69 = *(_QWORD *)(v63 + 208);
do
{
v70 = *(_QWORD *)(v63 + 200);
HalpTimerGetInternalData((_KDPC *)v63, v67, v65, (PVOID)v66);
v66 = (*(__int64(__fastcall **)(__int64))(v63 + 112))(v71);
_InterlockedOr(v85, 0);
v72 = *(_QWORD *)(v63 + 200);
}
while( v70 != v72 );
}
while( v69 != *(_QWORD *)(v63 + 208) );
v73 = *(_DWORD *)(v63 + 220);
v74 = v70 ^ v66;
if( _bittest64((const __int64 *)&v74, (unsigned __int8)(v73 - 1)) )
{
if( v73 != 64 )
v32 = (1i64 << v73) - 1;
if( v73 != 64 )
v33 = 1i64 << v73;
v75 = v70 & v32;
v76 = v66 | v70 ^ v75;
if( v66 < v75 )
v76 += v33;
_InterlockedCompareExchange64((volatile signed __int64 *)(v63 + 200), v76, v72);
}
else
{
if( v73 == 64 )
v77 = -1i64;
else
v77 = (1i64 << v73) - 1;
v76 = v66 | v70 & ~v77;
}
}
v80 = HalpAlwaysOnCounter;
v81 = (char *)HalpTimerScaleCounter(
v69 + v76,
*(_QWORD *)(HalpPerformanceCounter + 192),
*((_QWORD *)HalpAlwaysOnCounter + 24));
v84 = HalpTimerCalibratePerformanceCounter((INT64)v80, v81, v82, v83);
if( v84 < 0 )
KeBugCheckEx(0x5Cu, (PVOID)0x113, (PVOID)0x26, HalpAlwaysOnCounter, (PVOID)v84);
}
HalpTimerDelayedQueryHardwareCount = v31[14];
v31[14] = HalpTimerDelayedQueryCounter;
HalpTimerSavedPerformanceCounter = (PVOID)HalpPerformanceCounter;
result = (VOID **)HalpAlwaysOnCounter;
HalpPerformanceCounter = (INT64)HalpAlwaysOnCounter;
}
}
return result;
}Referenced by:
HalpTimerPowerChange