MiInsertPartitionPages
VOID __fastcall MiInsertPartitionPages(
_MI_PARTITION *FromPartition,
_MI_PARTITION *ToPartition,
_MI_INSERT_PAGES *InsertInfo){
unsigned __int64 v3;
_RTL_AVL_TREE *v4;
unsigned __int64 v5;
_ETHREAD *CurrentThread;
_MI_PARTITION *v8;
_MI_INSERT_PAGES v10;
_RTL_BALANCED_NODE *Root;
_QWORD *Children;
_QWORD *v13;
__int64 v14;
_QWORD *v15;
UINT64 v16;
int v17;
__m128i v18;
unsigned __int64 v19;
_MI_INSERT_PAGES v20;
_RTL_BALANCED_NODE *v21;
_RTL_BITMAP_EX *v22;
_RTL_BITMAP_EX *Buffer;
_RTL_BITMAP_EX *v24;
_RTL_BITMAP_EX *v25;
UINT64 v26;
_RTL_BALANCED_NODE *v27;
_RTL_BITMAP_EX *v28;
INT64 *p_DynamicMemoryLock;
_RTL_BALANCED_NODE *v30;
UINT64 v31;
_RTL_BITMAP_EX *v32;
UINT64 v33;
_RTL_BITMAP_EX *v34;
unsigned __int64 v35;
int v36;
int v37;
_MI_INSERT_PAGES v38;
_RTL_BALANCED_NODE *v39;
BOOL v40;
_RTL_BALANCED_NODE *v41;
_RTL_BALANCED_NODE *v42;
INT64 *v43;
INT64 *v44;
INT64 *v45;
INT64 *v46;
_RTL_AVL_TREE *Tree;
_KLOCK_QUEUE_HANDLE LockHandle;
unsigned __int128 v49;
__int128 v50;
__int128 v51;
__int64 v52;
__int128 v53;
__int128 v54;
__int128 v55;
__int64 v56;
__int64 v57;
_RTL_BALANCED_NODE *Parent;
__int64 v59;
v4 = *(_RTL_AVL_TREE **)InsertInfo;
Parent = 0i64;
v5 = v3;
v49 = 0i64;
v52 = 0i64;
memset(&LockHandle, 0, sizeof(LockHandle));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v8 = ToPartition;
v56 = 0i64;
v10 = InsertInfo[6];
v57 = (__int64)CurrentThread;
v49 = __PAIR128__((unsigned __int64)FromPartition, (unsigned __int64)ToPartition);
Tree = v4;
v50 = 0i64;
v51 = 0i64;
v53 = 0i64;
v54 = 0i64;
v55 = 0i64;
if( (v10 & 2) != 0 )
{
Root = v4->Root;
Children = 0i64;
while( Root )
{
Children = Root->Children;
Root = Root->Children[0];
}
while( Children )
{
v13 = (_QWORD *)Children[1];
v14 = (__int64)Children;
v15 = Children;
if( v13 )
{
do
{
Children = v13;
v13 = (_QWORD *)*v13;
}
while( v13 );
}
else
{
while( 1 )
{
Children = (_QWORD *)(Children[2] & 0xFFFFFFFFFFFFFFFCui64);
if( !Children || (_QWORD *)*Children == v15 )
break;
v15 = Children;
}
}
MiActOnPartitionNodePages(v14, 8u, (_RTL_AVL_TREE **)&v49);
}
CurrentThread = (_ETHREAD *)v57;
}
if( (InsertInfo[6] & 0x10) == 0 )
{
if( FromPartition == &Irp )
{
_InterlockedExchangeAdd64((_QWORD *)&stru_140C4DB30 + 268, v5);
}
else
{
MiClearPartitionPageBitMap(FromPartition, v4);
MiReduceCommitLimits(FromPartition, v5, v5);
MiReturnCommit(FromPartition, v5);
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx(&FromPartition->Core.DynamicMemoryPushLock, 0i64);
MiMakePartitionMemoryBlock(FromPartition);
if( (_InterlockedExchangeAdd64(&FromPartition->Core.DynamicMemoryPushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(&FromPartition->Core.DynamicMemoryPushLock);
KeAbPostRelease(&FromPartition->Core.DynamicMemoryPushLock);
CurrentThread = (_ETHREAD *)v57;
KiLeaveGuardedRegionUnsafe(v57);
}
}
if( v8 != &Irp )
goto LABEL_39;
v16 = (unsigned int)InsertInfo[6];
if( (v16 & 0x10) == 0 )
_InterlockedExchangeAdd64((_QWORD *)&stru_140C4DB30 + 268, -(__int64)v5);
MiFreePartitionTree(v8, v4, v16);
if( v17 < 0 )
{
v18 = (__m128i)v49;
InsertInfo[6] &= ~4u;
v19 = 0i64;
v20 = InsertInfo[6];
v8 = FromPartition;
v21 = v4->Root;
v22 = 0i64;
*((_QWORD *)&v53 + 1) = v18.m128i_i64[0];
v54 = v50;
*(_QWORD *)&v53 = _mm_srli_si128(v18, 8).m128i_u64[0];
v55 = v51;
v56 = v52;
while( v21 )
{
v22 = (_RTL_BITMAP_EX *)v21;
v21 = v21->Children[0];
}
while( v22 )
{
Buffer = (_RTL_BITMAP_EX *)v22->Buffer;
v24 = v22;
v25 = v22;
if( Buffer )
{
do
{
v22 = Buffer;
Buffer = (_RTL_BITMAP_EX *)Buffer->SizeOfBitMap;
}
while( Buffer );
}
else
{
while( 1 )
{
v22 = (_RTL_BITMAP_EX *)(v22[1].SizeOfBitMap & 0xFFFFFFFFFFFFFFFCui64);
if( !v22 || (_RTL_BITMAP_EX *)v22->SizeOfBitMap == v25 )
break;
v25 = v22;
}
}
v26 = RtlNumberOfSetBitsEx(v24 + 2);
v20 = InsertInfo[6];
v19 += v26;
if( (v20 & 2) != 0 )
{
MiActOnPartitionNodePages((__int64)v24, 8u, (_RTL_AVL_TREE **)&v53);
v20 = InsertInfo[6];
}
}
CurrentThread = (_ETHREAD *)v57;
if( (v20 & 0x10) == 0 )
_InterlockedExchangeAdd64((_QWORD *)&stru_140C4DB30 + 268, v19);
LABEL_39:
if( !v8 )
goto LABEL_76;
if( !v59 )
{
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx(&v8->Core.DynamicMemoryPushLock, 0i64);
}
v27 = v4->Root;
v28 = 0i64;
while( v27 )
{
v28 = (_RTL_BITMAP_EX *)v27;
v27 = v27->Children[0];
}
if( !v28 )
goto LABEL_68;
p_DynamicMemoryLock = (INT64 *)&v8->Core.DynamicMemoryLock;
while( 1 )
{
v30 = (_RTL_BALANCED_NODE *)v28;
v31 = RtlNumberOfSetBitsEx(v28 + 2);
v32 = (_RTL_BITMAP_EX *)v28->Buffer;
v33 = v31;
v34 = v28;
if( v32 )
{
do
{
v28 = v32;
v32 = (_RTL_BITMAP_EX *)v32->SizeOfBitMap;
}
while( v32 );
}
else
{
while( 1 )
{
v28 = (_RTL_BITMAP_EX *)(v28[1].SizeOfBitMap & 0xFFFFFFFFFFFFFFFCui64);
if( !v28 || (_RTL_BITMAP_EX *)v28->SizeOfBitMap == v34 )
break;
v34 = v28;
}
}
v35 = (unsigned __int8)ExAcquireSpinLockExclusive(p_DynamicMemoryLock);
RtlAvlRemoveNode((UINT64 *)Tree, (INT64 *)v30);
if( (InsertInfo[6] & 0x10) != 0 )
{
v36 = 1;
}
else
{
v37 = MiMergePageNodes((__int64)v8, (__int64)v30);
v8->Vp.NumberOfPhysicalPages += v33;
v36 = v37;
v8->Core.MemoryConfigurationChanged = 1;
}
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&v8->Core.DynamicMemoryLock);
__writecr8(v35);
v38 = InsertInfo[6];
if( (v38 & 0x10) == 0 )
{
MiIncreaseCommitLimits(v8, v33, v33, 1ui64, 0i64);
v38 = InsertInfo[6];
}
MiFreePartitionNodePages((UINT64)v8, (INT64)v30, v38);
if( v36 != 1 )
goto LABEL_67;
v39 = Parent;
v40 = 0;
if( !Parent )
goto LABEL_66;
while( ((unsigned __int64)v30[1].Children[0] & 0x7FFFFFFFFFFFFFFFi64) >= ((unsigned __int64)v39[1].Children[0] & 0x7FFFFFFFFFFFFFFFi64) )
{
v41 = v39->Children[1];
if( !v41 )
{
v40 = 1;
goto LABEL_66;
}
LABEL_64:
v39 = v41;
}
v41 = v39->Children[0];
if( v39->Children[0] )
goto LABEL_64;
v40 = 0;
LABEL_66:
RtlAvlInsertNodeEx(&Parent, (UINT64)v39, v40, v30);
LABEL_67:
p_DynamicMemoryLock = (INT64 *)&v8->Core.DynamicMemoryLock;
if( !v28 )
{
LABEL_68:
if( (InsertInfo[6] & 0x10) == 0 )
MiMakePartitionMemoryBlock(v8);
if( !v59 )
{
if( (_InterlockedExchangeAdd64(&v8->Core.DynamicMemoryPushLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(&v8->Core.DynamicMemoryPushLock);
KeAbPostRelease(&v8->Core.DynamicMemoryPushLock);
KiLeaveGuardedRegionUnsafe(v57);
}
if( (InsertInfo[6] & 0x10) == 0 )
{
KeAcquireInStackQueuedSpinLock(&v8->Commit.EventLock, &LockHandle);
MiComputeCommitThresholds(v8);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
break;
}
}
}
LABEL_76:
v42 = Parent;
v43 = 0i64;
while( v42 )
{
v43 = (INT64 *)v42;
v42 = v42->Children[0];
}
while( v43 )
{
v44 = (INT64 *)v43[1];
v45 = v43;
v46 = v43;
if( v44 )
{
do
{
v43 = v44;
v44 = (INT64 *)*v44;
}
while( v44 );
}
else
{
while( 1 )
{
v43 = (INT64 *)(v43[2] & 0xFFFFFFFFFFFFFFFCui64);
if( !v43 || (INT64 *)*v43 == v46 )
break;
v46 = v43;
}
}
RtlAvlRemoveNode((UINT64 *)&Parent, v45);
ExFreePoolWithTag((PVOID)v45[5], 0);
ExFreePoolWithTag(v45, 0);
}
}Referenced by:
MiAllocatePartitionPhysicalPages
MiHotAddPartitionMemory