MiCheckProcessorPteCache
_MMPTE *__stdcall MiCheckProcessorPteCache(UINT64 NumberOfBits){
unsigned __int8 CurrentIrql;
struct _KPRCB *CurrentPrcb;
_MMPTE *v4;
signed __int64 *p_PteBitCache;
signed __int64 *v6;
signed __int64 v7;
UINT64 v8;
signed __int64 *v9;
signed __int64 *v10;
unsigned __int64 v11;
unsigned __int64 v12;
unsigned __int64 v13;
_BYTE *v14;
char v15;
unsigned __int64 v17;
unsigned __int64 v18;
unsigned __int64 *v19;
unsigned __int64 v20;
unsigned __int64 v21;
unsigned __int64 v22;
unsigned __int64 v23;
__int64 *v24;
__int64 v25;
unsigned __int64 v26;
unsigned __int64 v27;
unsigned __int64 v28;
volatile signed __int64 *v29;
signed __int64 v30;
unsigned __int8 v31;
unsigned __int64 v32;
__int64 v33;
bool v34;
__int64 v35;
unsigned int v36;
unsigned __int64 v37;
unsigned __int64 v38;
__int64 v39;
__int64 v40;
unsigned __int64 v41;
int v42;
__int64 v43;
unsigned int v44;
UINT64 v45;
unsigned __int64 v46;
__int128 v47;
_KLOCK_QUEUE_HANDLE LockHandle;
v47 = 0i64;
memset(&LockHandle, 0, sizeof(LockHandle));
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
v4 = 0i64;
p_PteBitCache = (signed __int64 *)&CurrentPrcb->PteBitCache;
if( CurrentPrcb->PteBitCache != -1i64 )
{
LABEL_2:
*((_QWORD *)&v47 + 1) = p_PteBitCache;
*(_QWORD *)&v47 = 64i64;
v6 = p_PteBitCache;
if( !NumberOfBits )
{
v12 = 0i64;
goto LABEL_12;
}
if( NumberOfBits > 0x40 )
goto LABEL_54;
v7 = *p_PteBitCache;
v8 = 63 - NumberOfBits + 1;
v9 = &p_PteBitCache[v8 >> 6];
v10 = p_PteBitCache;
if( NumberOfBits < 0x40 )
{
if( NumberOfBits > 1 )
{
v33 = 0i64;
while( 1 )
{
if( v7 == -1 )
{
while( 1 )
{
if( ++v10 > v9 )
goto LABEL_53;
v7 = *v10;
if( *v10 != -1 )
{
v33 = 0i64;
break;
}
}
}
v34 = !_BitScanForward64((unsigned __int64 *)&v35, v7);
if( v34 )
LODWORD(v35) = 64;
if( (unsigned int)(v33 + v35) >= NumberOfBits )
break;
v36 = NumberOfBits;
v37 = ~v7;
while( 1 )
{
v37 &= v37 >> (v36 >> 1);
if( !v37 )
break;
v36 -= v36 >> 1;
if( v36 <= 1 )
{
_BitScanForward64(&v38, v37);
v39 = (unsigned int)v38;
goto LABEL_52;
}
}
if( v10 == p_PteBitCache )
goto LABEL_53;
v34 = !_BitScanReverse64((unsigned __int64 *)&v40, v7);
if( v34 )
v33 = 64i64;
else
v33 = (unsigned int)(63 - v40);
v7 = v10[1];
++v10;
}
v39 = -v33;
LABEL_52:
v12 = ((v10 - p_PteBitCache) << 6) + v39;
if( v12 > v8 )
LABEL_53:
v12 = -1i64;
}
else
{
if( v7 == -1 )
{
do
{
if( ++v10 > v9 )
goto LABEL_54;
v7 = *v10;
}
while( *v10 == -1 );
}
_BitScanForward64(&v11, ~v7);
v12 = (unsigned int)v11 + ((v10 - p_PteBitCache) << 6);
if( v12 > v8 )
goto LABEL_54;
}
LABEL_8:
if( v12 == -1i64 )
goto LABEL_13;
v13 = v12 & 7;
v14 = (char *)v6 + (v12 >> 3);
if( v13 + NumberOfBits > 8 )
{
if( (v12 & 7) != 0 )
{
*v14++ |= byte_14001A768[v13];
NumberOfBits -= (unsigned int)(8 - v13);
}
if( NumberOfBits > 8 )
{
memset(v14, 255i64, NumberOfBits >> 3);
v14 += NumberOfBits >> 3;
NumberOfBits &= 7u;
}
if( !NumberOfBits )
goto LABEL_12;
v15 = byte_14001DA00[NumberOfBits];
}
else
{
v15 = byte_14001DA00[NumberOfBits] << v13;
}
*v14 |= v15;
LABEL_12:
v4 = (_MMPTE *)(*(&stru_140C4DB30 + 556) + 8 * (v12 + CurrentPrcb->PteBitOffset));
LABEL_13:
__writecr8(CurrentIrql);
return v4;
}
while( 1 )
{
while( 1 )
{
if( v7 < 0 )
{
while( ++v10 <= v9 )
{
v7 = *v10;
if( *v10 >= 0 )
goto LABEL_72;
}
LABEL_54:
v12 = -1i64;
goto LABEL_8;
}
LABEL_72:
v34 = !_BitScanReverse64((unsigned __int64 *)&v43, v7);
if( v34 )
v44 = 64;
else
v44 = 63 - v43;
v12 = ((v10 - v6 + 1) << 6) - v44;
if( v12 > v8 )
goto LABEL_54;
v45 = NumberOfBits - v44;
if( NumberOfBits == v44 )
goto LABEL_8;
v7 = v10[1];
++v10;
if( v45 >= 0x40 )
break;
LABEL_80:
v34 = !_BitScanForward64(&v46, v7);
if( v34 )
v46 = 64i64;
if( v46 >= v45 )
goto LABEL_8;
}
if( !v7 )
{
v45 -= 64i64;
if( !v45 )
goto LABEL_8;
v7 = v10[1];
++v10;
goto LABEL_80;
}
}
}
__writecr8(CurrentIrql);
v17 = *(&stru_140C4DB30 + 562);
LABEL_18:
while( 2 )
{
v18 = *(&stru_140C4DB30 + 563);
v19 = (unsigned __int64 *)((char *)&stru_140C4DB30 + 4432);
if( *(&stru_140C4DB30 + 563) )
{
while( *(&stru_140C4DB30 + 554) < v18 )
{
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)&stru_140C4DB30 + 560, &LockHandle);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v18 = *(&stru_140C4DB30 + 563);
if( !*(&stru_140C4DB30 + 563) )
goto LABEL_22;
}
v19 = (unsigned __int64 *)&v47;
*(_QWORD *)&v47 = *(&stru_140C4DB30 + 554) - v18;
*((_QWORD *)&v47 + 1) = *(&stru_140C4DB30 + 555) + 8 * (v18 >> 6);
if( v17 )
v17 -= v18;
}
LABEL_22:
v20 = *v19;
v21 = v17;
v22 = v19[1];
if( v17 >= v20 )
v21 = 0i64;
v23 = v20 - 1;
while( 1 )
{
if( v23 - v21 != -1i64 )
{
v24 = (__int64 *)(v22 + 8 * (v21 >> 6));
v25 = ((1i64 << (v21 & 0x3F)) - 1) | *v24;
if( v25 == -1 )
{
while( (unsigned __int64)++v24 <= v22 + 8 * (v23 >> 6) )
{
v25 = *v24;
if( *v24 != -1 )
goto LABEL_27;
}
}
else
{
LABEL_27:
_BitScanForward64((unsigned __int64 *)&v25, ~v25);
v26 = v25 + ((__int64)((__int64)v24 - v22) >> 3 << 6);
if( v26 <= v23 && v26 != -1i64 )
{
v27 = (v26 + v18) & 0xFFFFFFFFFFFFFFC0ui64;
v28 = *(_QWORD *)(*(&stru_140C4DB30 + 555) + 8 * (v27 >> 6));
v29 = (volatile signed __int64 *)(*(&stru_140C4DB30 + 555) + 8 * (v27 >> 6));
if( v28 != -1i64 )
{
while( 1 )
{
v30 = _InterlockedCompareExchange64(v29, -1i64, v28);
if( v28 == v30 )
break;
v28 = v30;
if( v30 == -1 )
goto LABEL_87;
}
if( v28 != -1i64 )
{
v31 = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
CurrentIrql = v31;
p_PteBitCache = (signed __int64 *)&CurrentPrcb->PteBitCache;
if( CurrentPrcb->PteBitCache == -1i64 )
{
*p_PteBitCache = v28;
CurrentPrcb->PteBitOffset = v27;
v32 = ~v28 - ((~v28 >> 1) & 0x5555555555555555i64);
_InterlockedExchangeAdd64(
(_QWORD *)&stru_140C4DB30 + 565,
-(__int64)((0x101010101010101i64
* (((v32 & 0x3333333333333333i64)
+ ((v32 >> 2) & 0x3333333333333333i64)
+ (((v32 & 0x3333333333333333i64) + ((v32 >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56));
*(&stru_140C4DB30 + 562) = v27 + 64;
}
else
{
_InterlockedAnd64(v29, v28);
}
goto LABEL_2;
}
}
LABEL_87:
v17 = v27 + 64;
goto LABEL_18;
}
}
}
if( !v21 )
break;
v41 = v17 + 1;
if( v17 + 1 > v20 )
v41 = v20;
v23 = v41 - 1;
v21 = 0i64;
}
MiEmptyPteBins((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), 0i64);
if( v42 )
{
v17 = 0i64;
continue;
}
return 0i64;
}
}Referenced by:
MiReservePtes