MiInsertPartitionPages
__int64 __fastcall MiInsertPartitionPages(
unsigned __int64 a1,
unsigned __int64 a2,
__int64 a3,
unsigned __int64 a4,
__int64 a5){
_RTL_AVL_TREE *v5;
_ETHREAD *CurrentThread;
unsigned __int64 v9;
int v11;
_RTL_BALANCED_NODE *Root;
_QWORD *Children;
_QWORD *v14;
__int64 v15;
_QWORD *v16;
int v17;
unsigned int v18;
__m128i v19;
unsigned __int64 v20;
int v21;
_RTL_BALANCED_NODE *v22;
_RTL_BITMAP_EX *v23;
_RTL_BITMAP_EX *Buffer;
_RTL_BITMAP_EX *v25;
_RTL_BITMAP_EX *v26;
UINT64 v27;
_RTL_BALANCED_NODE *v28;
_RTL_BITMAP_EX *v29;
volatile LONG *v30;
__int64 *v31;
UINT64 v32;
_RTL_BITMAP_EX *v33;
UINT64 v34;
_RTL_BITMAP_EX *v35;
unsigned __int64 v36;
int v37;
int v38;
int v39;
_QWORD *v40;
bool v41;
_QWORD *v42;
__int64 *v43;
__int64 *v44;
__int64 *v45;
__int64 *v46;
__int64 *v47;
unsigned __int64 *v49;
struct _KLOCK_QUEUE_HANDLE LockHandle;
unsigned __int128 v51;
__int128 v52;
__int128 v53;
__int64 v54;
__int128 v55;
__int128 v56;
__int128 v57;
__int64 v58;
int v59;
__int64 v60;
_QWORD *v61;
v5 = *(_RTL_AVL_TREE **)a3;
v59 = 0;
v61 = 0i64;
v51 = 0i64;
v54 = 0i64;
memset(&LockHandle, 0, sizeof(LockHandle));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v9 = a2;
v58 = 0i64;
v11 = *(_DWORD *)(a3 + 24);
v60 = (__int64)CurrentThread;
v51 = __PAIR128__(a1, a2);
v49 = (unsigned __int64 *)v5;
v52 = 0i64;
v53 = 0i64;
v55 = 0i64;
v56 = 0i64;
v57 = 0i64;
if( (v11 & 2) != 0 )
{
Root = v5->Root;
Children = 0i64;
while( Root )
{
Children = Root->Children;
Root = Root->Children[0];
}
while( Children )
{
v14 = (_QWORD *)Children[1];
v15 = (__int64)Children;
v16 = Children;
if( v14 )
{
do
{
Children = v14;
v14 = (_QWORD *)*v14;
}
while( v14 );
}
else
{
while( 1 )
{
Children = (_QWORD *)(Children[2] & 0xFFFFFFFFFFFFFFFCui64);
if( !Children || (_QWORD *)*Children == v16 )
break;
v16 = Children;
}
}
MiActOnPartitionNodePages(v15, 8u, (__int16 **)&v51);
}
CurrentThread = (_ETHREAD *)v60;
}
if( (*(_DWORD *)(a3 + 24) & 0x10) == 0 )
{
if( (ULONG_PTR *)a1 == &MiSystemPartition )
{
_InterlockedExchangeAdd64(&qword_140C4E390, a4);
}
else
{
MiClearPartitionPageBitMap((_MI_PARTITION *)a1, v5);
MiReduceCommitLimits((_MI_PARTITION *)a1, a4, a4);
MiReturnCommit((_MI_PARTITION *)a1, a4);
--*((_WORD *)CurrentThread + 243);
ExAcquirePushLockExclusiveEx(a1 + 192, 0i64);
MiMakePartitionMemoryBlock((_MI_PARTITION *)a1);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 192), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(a1 + 192));
KeAbPostRelease((PVOID)(a1 + 192));
CurrentThread = (_ETHREAD *)v60;
KiLeaveGuardedRegionUnsafe(v60);
}
}
if( (ULONG_PTR *)v9 == &MiSystemPartition )
{
v17 = *(_DWORD *)(a3 + 24);
if( (v17 & 0x10) == 0 )
_InterlockedExchangeAdd64(&qword_140C4E390, -(__int64)a4);
v59 = MiFreePartitionTree(v9, (unsigned __int64 *)v5, v17, 1);
v18 = v59;
if( v59 >= 0 )
goto LABEL_77;
v19 = (__m128i)v51;
*(_DWORD *)(a3 + 24) &= ~4u;
v20 = 0i64;
v21 = *(_DWORD *)(a3 + 24);
v9 = a1;
v22 = v5->Root;
v23 = 0i64;
*((_QWORD *)&v55 + 1) = v19.m128i_i64[0];
v56 = v52;
*(_QWORD *)&v55 = _mm_srli_si128(v19, 8).m128i_u64[0];
v57 = v53;
v58 = v54;
while( v22 )
{
v23 = (_RTL_BITMAP_EX *)v22;
v22 = v22->Children[0];
}
while( v23 )
{
Buffer = (_RTL_BITMAP_EX *)v23->Buffer;
v25 = v23;
v26 = v23;
if( Buffer )
{
do
{
v23 = Buffer;
Buffer = (_RTL_BITMAP_EX *)Buffer->SizeOfBitMap;
}
while( Buffer );
}
else
{
while( 1 )
{
v23 = (_RTL_BITMAP_EX *)(v23[1].SizeOfBitMap & 0xFFFFFFFFFFFFFFFCui64);
if( !v23 || (_RTL_BITMAP_EX *)v23->SizeOfBitMap == v26 )
break;
v26 = v23;
}
}
v27 = RtlNumberOfSetBitsEx(v25 + 2);
v21 = *(_DWORD *)(a3 + 24);
v20 += v27;
if( (v21 & 2) != 0 )
{
MiActOnPartitionNodePages((__int64)v25, 8u, (__int16 **)&v55);
v21 = *(_DWORD *)(a3 + 24);
}
}
CurrentThread = (_ETHREAD *)v60;
if( (v21 & 0x10) == 0 )
_InterlockedExchangeAdd64(&qword_140C4E390, v20);
}
if( !v9 )
goto LABEL_76;
if( !a5 )
{
--*((_WORD *)CurrentThread + 243);
ExAcquirePushLockExclusiveEx(v9 + 192, 0i64);
}
v28 = v5->Root;
v29 = 0i64;
while( v28 )
{
v29 = (_RTL_BITMAP_EX *)v28;
v28 = v28->Children[0];
}
if( !v29 )
goto LABEL_68;
v30 = (volatile LONG *)(v9 + 200);
do
{
v31 = (__int64 *)v29;
v32 = RtlNumberOfSetBitsEx(v29 + 2);
v33 = (_RTL_BITMAP_EX *)v29->Buffer;
v34 = v32;
v35 = v29;
if( v33 )
{
do
{
v29 = v33;
v33 = (_RTL_BITMAP_EX *)v33->SizeOfBitMap;
}
while( v33 );
}
else
{
while( 1 )
{
v29 = (_RTL_BITMAP_EX *)(v29[1].SizeOfBitMap & 0xFFFFFFFFFFFFFFFCui64);
if( !v29 || (_RTL_BITMAP_EX *)v29->SizeOfBitMap == v35 )
break;
v35 = v29;
}
}
v36 = ExAcquireSpinLockExclusive(v30);
RtlAvlRemoveNode(v49, v31);
if( (*(_DWORD *)(a3 + 24) & 0x10) != 0 )
{
v37 = 1;
}
else
{
v38 = MiMergePageNodes(v9, (INT64)v31);
*(_QWORD *)(v9 + 6928) += v34;
v37 = v38;
*(_BYTE *)(v9 + 12) = 1;
}
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v9 + 200));
__writecr8(v36);
v39 = *(_DWORD *)(a3 + 24);
if( (v39 & 0x10) == 0 )
{
MiIncreaseCommitLimits((_MI_PARTITION *)v9, v34, v34, 1ui64, 0i64);
v39 = *(_DWORD *)(a3 + 24);
}
MiFreePartitionNodePages(v9, (INT64)v31, v39);
if( v37 != 1 )
goto LABEL_67;
v40 = v61;
v41 = 0;
if( !v61 )
goto LABEL_66;
while( (v31[3] & 0x7FFFFFFFFFFFFFFFui64) >= (v40[3] & 0x7FFFFFFFFFFFFFFFui64) )
{
v42 = (_QWORD *)v40[1];
if( !v42 )
{
v41 = 1;
goto LABEL_66;
}
LABEL_64:
v40 = v42;
}
v42 = (_QWORD *)*v40;
if( *v40 )
goto LABEL_64;
v41 = 0;
LABEL_66:
RtlAvlInsertNodeEx((unsigned __int64 *)&v61, (__int64)v40, v41, v31);
LABEL_67:
v30 = (volatile LONG *)(v9 + 200);
}
while( v29 );
LABEL_68:
if( (*(_DWORD *)(a3 + 24) & 0x10) == 0 )
MiMakePartitionMemoryBlock((_MI_PARTITION *)v9);
if( !a5 )
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v9 + 192), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v9 + 192));
KeAbPostRelease((PVOID)(v9 + 192));
KiLeaveGuardedRegionUnsafe(v60);
}
if( (*(_DWORD *)(a3 + 24) & 0x10) == 0 )
{
KeAcquireInStackQueuedSpinLock((UINT64 *)(v9 + 6248), &LockHandle);
MiComputeCommitThresholds((_MI_PARTITION *)v9);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
LABEL_76:
v18 = v59;
LABEL_77:
v43 = v61;
v44 = 0i64;
while( v43 )
{
v44 = v43;
v43 = (__int64 *)*v43;
}
while( v44 )
{
v45 = (__int64 *)v44[1];
v46 = v44;
v47 = v44;
if( v45 )
{
do
{
v44 = v45;
v45 = (__int64 *)*v45;
}
while( v45 );
}
else
{
while( 1 )
{
v44 = (__int64 *)(v44[2] & 0xFFFFFFFFFFFFFFFCui64);
if( !v44 || (__int64 *)*v44 == v47 )
break;
v47 = v44;
}
}
RtlAvlRemoveNode((unsigned __int64 *)&v61, v46);
ExFreePoolWithTag((PVOID)v46[5], 0);
ExFreePoolWithTag(v46, 0);
}
return v18;
}Referenced by:
MiAllocatePartitionPhysicalPages
MiHotAddPartitionMemory