MiExpandPtes
_MMPTE *__stdcall MiExpandPtes(_MI_SYSTEM_PTE_TYPE *SystemPteInfo, UINT64 NumberOfPtes){
unsigned int Flags;
_MI_SYSTEM_VA_TYPE v4;
int v5;
unsigned __int64 v6;
UINT64 v7;
UINT64 v8;
_MI_SYSTEM_VA_TYPE v9;
unsigned __int64 v10;
__int64 v11;
INT64 v12;
unsigned __int64 v13;
unsigned __int64 v14;
_ETHREAD *CurrentThread;
$D42DE0CAA3463AB1F3EB029C46D418FB *v16;
unsigned __int64 v17;
char *v18;
NTSTATUS v19;
unsigned int v20;
unsigned __int64 v21;
unsigned __int64 v22;
UINT64 v23;
UINT64 v24;
char v25;
volatile signed __int32 *v26;
UINT64 v27;
int v29;
unsigned __int64 SpinLock;
_ETHREAD *v31;
unsigned int SessionId;
int v33;
bool v34;
__int64 v35;
_KLOCK_ENTRY *v36;
unsigned __int8 v37;
INT64 v38;
_MMPTE *PteBase;
_MI_SYSTEM_VA_TYPE v40;
VOID *v41;
char v42;
VOID *v43;
INT64 v44;
UINT64 a3;
NTSTATUS v46;
VOID *v47;
unsigned __int64 v48;
unsigned __int64 v49;
_KLOCK_QUEUE_HANDLE LockHandle;
unsigned __int64 v51;
_ETHREAD *v52;
unsigned __int8 v54;
_MI_SYSTEM_VA_TYPE VaType;
memset(&LockHandle, 0, sizeof(LockHandle));
if( NumberOfPtes + 511 <= NumberOfPtes )
return 0i64;
Flags = SystemPteInfo->Flags;
v4 = SystemPteInfo->VaType;
VaType = v4;
v5 = 0;
v6 = (Flags & 4) != 0 ? 16i64 : 1i64;
v51 = v6;
if( NumberOfPtes >= 0x200 && SystemPteInfo == (_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432) )
v5 = 1;
v7 = (NumberOfPtes + 511) & 0xFFFFFFFFFFFFFE00ui64;
v8 = v7 >> 9;
v48 = v7 / v6;
if( (Flags & 2) != 0 )
{
HIDWORD(a3) = 16;
v9 = v4;
if( v5 == 1 )
v9 = MiVaSystemPtesLarge;
v10 = (unsigned __int64)MiObtainSystemVa(v8, v9);
}
else
{
HIDWORD(a3) = 1;
v10 = (unsigned __int64)MiObtainSessionVa(v8);
}
v47 = (VOID *)v10;
v11 = v10;
if( !v10 )
return 0i64;
v12 = (INT64)MmGetPteBase() + ((v10 >> 9) & 0x7FFFFFFFF8i64);
v13 = (signed __int64)(v12 - (unsigned __int64)SystemPteInfo->BasePte) >> 3;
v49 = v13;
if( v5 )
goto LABEL_22;
v14 = v13 / v6;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v16 = &SystemPteInfo->48;
v52 = CurrentThread;
v17 = v14;
v18 = (char *)SystemPteInfo->Bitmap.Buffer + (v14 >> 3);
if( (SystemPteInfo->Flags & 2) != 0 )
{
KeAcquireInStackQueuedSpinLock(&SystemPteInfo->SpinLock, &LockHandle);
}
else
{
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx(v16->GlobalPushLock, 0i64);
}
v19 = MiSplitBitmapPages(VaType, v18, v48 + (v17 & 7));
v20 = SystemPteInfo->Flags;
v46 = v19;
if( (v20 & 2) != 0 )
{
if( v19 == 1 )
{
v21 = (v7 + v49) / v51;
if( v21 > SystemPteInfo->Bitmap.SizeOfBitMap )
SystemPteInfo->Bitmap.SizeOfBitMap = v21;
v22 = v17 & 0xFFFFFFFFFFFFFFC0ui64;
if( (v17 & 0x3F) == 0 )
v22 = v17;
if( v22 < SystemPteInfo->LowestBitEverAllocated || (v20 & 8) == 0 )
{
SystemPteInfo->LowestBitEverAllocated = v22;
SystemPteInfo->Flags = v20 | 8;
}
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
else
{
SpinLock = v16->SpinLock;
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)SpinLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)SpinLock);
LODWORD(a3) = 0;
v31 = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType(SpinLock) == 1 )
SessionId = MmGetSessionIdEx(v31->Tcb.ApcState.Process);
else
SessionId = -1;
--v31->Tcb.SpecialApcDisable;
v54 = ++v31->Tcb.AbAllocationRegionCount;
v33 = ((char)v31->Tcb.AbEntrySummary | (char)v31->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
while( 1 )
{
v34 = !_BitScanReverse((unsigned int *)&v35, v33);
if( v34 )
break;
v36 = &v31->Tcb.LockEntries[v35];
v33 &= ~(1 << v35);
if( (v36->AcquiredByte & 1) != 0
&& (v36->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v36->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (SpinLock & 0x7FFFFFFFFFFFFFFCi64)
&& v36->LockState.SessionId == SessionId )
{
v36->AcquiredByte &= ~1u;
if( v36->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
{
if( v36 )
{
v36->CrossThreadReleasableAndBusyByte |= 2u;
if( v36->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v36);
LODWORD(a3) = v36->BoostBitmap.AllFields & 0x1FFFF;
v36->BoostBitmap.AllFields &= 0xFFFE0000;
v36->ThreadLocalFlags &= ~1u;
v36->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v37 = 1 << (v36 - v31->Tcb.LockEntries);
if( v54 == 1 )
v31->Tcb.AbEntrySummary |= v37;
else
_InterlockedOr8((volatile signed __int8 *)&v31->Tcb.AbOrphanedEntrySummary, v37);
goto LABEL_56;
}
break;
}
}
}
if( (*(&v31->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, v31, (PVOID)SpinLock, (PVOID)SessionId, 0i64);
LABEL_56:
--v31->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v31->Tcb, (VOID *)SpinLock, &a3);
v34 = v31->Tcb.SpecialApcDisable++ == -1;
if( v34 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v31->Tcb.ApcState.ApcListHead[0].Flink != &v31->Tcb.152 )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)v52);
}
if( v46 )
{
v6 = v51;
v4 = VaType;
v11 = (__int64)v47;
LABEL_22:
LODWORD(v44) = 0;
if( MiMakeZeroedPageTablesEx(v12, v12 + 8 * (v7 - 1), HIDWORD(a3), (unsigned int)v4, v44) )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)&SystemPteInfo->TotalFreeSystemPtes, v48);
_InterlockedExchangeAdd64((volatile signed __int64 *)&SystemPteInfo->TotalSystemPtes, v48);
if( (dword_140CFA17C & 2) != 0 && SystemPteInfo == (_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432) )
{
v42 = 2 * v49;
v43 = (VOID *)(*(&stru_140C4DB30 + 414) + ((2 * v49) >> 3));
KeAcquireInStackQueuedSpinLock(&SystemPteInfo->SpinLock, &LockHandle);
if( !MiSplitBitmapPages(VaType, v43, (v42 & 7) + 2 * v48) )
dword_140CFA17C &= ~2u;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
if( v5 == 1 || NumberOfPtes == v7 )
return(_MMPTE *)v12;
v23 = (v7 - NumberOfPtes) / v6;
v24 = (NumberOfPtes + v49) / v6;
v25 = v24 & 0x1F;
v26 = (volatile signed __int32 *)SystemPteInfo->Bitmap.Buffer + (v24 >> 5);
if( (v24 & 0x1F) + v23 <= 0x20 )
{
if( v23 == 32 )
{
*v26 = 0;
return(_MMPTE *)v12;
}
v29 = ~(((1 << v23) - 1) << v25);
}
else
{
if( (v24 & 0x1F) != 0 )
{
_InterlockedAnd(v26, ~(((1 << (32 - (v24 & 0x1F))) - 1) << v25));
v23 -= 32 - (unsigned int)(v24 & 0x1F);
++v26;
}
if( v23 >= 0x20 )
{
v27 = v23 >> 5;
v23 += -32i64 * (v23 >> 5);
do
{
*v26++ = 0;
--v27;
}
while( v27 );
}
if( !v23 )
return(_MMPTE *)v12;
v29 = -1 << v23;
}
_InterlockedAnd(v26, v29);
return(_MMPTE *)v12;
}
if( v5 == 1 )
v4 = MiVaSystemPtesLarge;
v38 = v12 << 25;
PteBase = MmGetPteBase();
v40 = v4;
v41 = (VOID *)v11;
goto LABEL_71;
}
v38 = v12 << 25;
PteBase = MmGetPteBase();
v40 = VaType;
v41 = v47;
LABEL_71:
MiReturnSystemVa(v41, (VOID *)((__int64)((v7 << 28) + v38 - ((_QWORD)PteBase << 25)) >> 16), v40, 0i64);
return 0i64;
}Referenced by:
MiReservePtes