MiActOnPartitionNodePages
void __fastcall MiActOnPartitionNodePages(__int64 a1, unsigned int a2, _RTL_AVL_TREE **a3){
unsigned int v4;
__int64 v5;
_RTL_BITMAP_EX *v6;
unsigned __int64 v7;
const signed __int64 *Buffer;
unsigned __int64 v9;
unsigned __int64 v10;
UINT64 v11;
const signed __int64 *v12;
__int64 i;
unsigned __int64 SizeOfBitMap;
unsigned __int64 v15;
__int64 v16;
unsigned __int64 v17;
_DWORD *v18;
_DWORD *v19;
_DWORD *v20;
unsigned __int64 j;
UINT64 v22;
int v23;
UINT64 v24;
_RTL_AVL_TREE *v25;
UINT64 v26;
NTSTATUS v27;
unsigned __int64 v28;
unsigned __int64 v29;
_MI_PARTITION *v30;
__int16 Root;
_MMPFN *v32;
_MMPFN *v33;
unsigned __int8 CurrentIrql;
_MIPFNBLINK *p_u2;
unsigned __int64 v36;
int v37;
_LARGE_INTEGER v38;
__int64 v39;
unsigned __int64 v40;
unsigned __int64 v41;
_RTL_BITMAP_EX *v42;
unsigned __int64 v43;
unsigned __int64 v44;
unsigned __int64 v45;
unsigned __int64 *v46;
unsigned __int64 v47;
unsigned __int64 *v48;
bool v49;
bool k;
_RTL_AVL_TREE *v51;
BOOL v52;
_RTL_BALANCED_NODE *v53;
UINT64 OldIrql;
__int64 SpinCount[2];
_LARGE_INTEGER NumberOfBytes;
_LARGE_INTEGER StartAddress;
_RTL_BITMAP_EX *v58;
unsigned int EntireRangeIsZeroed;
StartAddress.QuadPart = 0i64;
NumberOfBytes.QuadPart = 0i64;
v4 = a2;
*((_DWORD *)a3 + 5) = 0;
EntireRangeIsZeroed = 0;
if( a2 <= 1 )
{
v5 = *(_QWORD *)(a1 + 24);
if( v5 < 0 )
{
EntireRangeIsZeroed = 1;
*(_QWORD *)(a1 + 24) = v5 & 0x7FFFFFFFFFFFFFFFi64;
}
}
v6 = (_RTL_BITMAP_EX *)(a1 + 32);
v7 = 0i64;
v58 = (_RTL_BITMAP_EX *)(a1 + 32);
while( 1 )
{
Buffer = (const signed __int64 *)v6->Buffer;
v9 = v7 & -(__int64)(v7 < v6->SizeOfBitMap);
v10 = v6->SizeOfBitMap - 1;
while( 1 )
{
if( v10 - v9 == -1i64 )
goto LABEL_7;
v12 = &Buffer[v9 >> 6];
for( i = ((1i64 << (v9 & 0x3F)) - 1) | ~*v12; i == -1; i = ~*v12 )
{
if( ++v12 > &Buffer[v10 >> 6] )
goto LABEL_7;
}
_BitScanForward64((unsigned __int64 *)&i, ~i);
v11 = i + ((v12 - Buffer) << 6);
if( v11 > v10 )
{
LABEL_7:
v11 = -1i64;
}
else if( v11 != -1i64 )
{
break;
}
if( !v9 )
break;
SizeOfBitMap = v7 + 1;
if( v7 + 1 > v6->SizeOfBitMap )
SizeOfBitMap = v6->SizeOfBitMap;
v10 = SizeOfBitMap - 1;
v9 = 0i64;
}
if( v11 < v7 || v11 == -1i64 )
return;
v15 = v6->SizeOfBitMap;
if( v6->SizeOfBitMap <= v11 )
{
v16 = 0i64;
LABEL_44:
v17 = v6->SizeOfBitMap;
goto LABEL_45;
}
v17 = v11;
v18 = (_DWORD *)Buffer + ((v15 - 1) >> 5);
v19 = (_DWORD *)Buffer + (v11 >> 5);
if( v19 != v18 && (*v19 | *((_DWORD *)qword_140011CE0 + (v11 & 0x1F))) == -1 )
{
v17 = (v11 & 0xFFFFFFFFFFFFFFE0ui64) + 32;
for( ++v19; v19 < v18 && *v19 == -1; ++v19 )
v17 += 32i64;
}
while( v17 < v15 && _bittest64(Buffer, v17) )
++v17;
v16 = 0i64;
if( v19 != v18 && (*v19 & ~*((_DWORD *)qword_140011CE0 + (v17 & 0x1F))) == 0 )
{
v16 = 32 - (v17 & 0x1F);
if( v16 == -1 )
goto LABEL_43;
v20 = v19 + 1;
while( v20 < v18 && !*v20 )
{
++v20;
v16 += 32i64;
if( v16 == -1 )
goto LABEL_43;
}
}
for( j = v16 + v17; j < v6->SizeOfBitMap; ++v16 )
{
if( _bittest64((const signed __int64 *)v6->Buffer, j) )
break;
if( v16 == -1 )
break;
++j;
}
LABEL_43:
if( !v16 )
goto LABEL_44;
LABEL_45:
v22 = v17 - v11;
v7 = v22 + v16 + v11;
v23 = 0;
v24 = v11 + (*(_QWORD *)(a1 + 24) & 0x7FFFFFFFFFFFFFFFi64);
if( v4 != 9 && (v24 > 0xFFFFFFFFFi64 || (MmGetPfnDb()[v24].u4._bf_0 & 0x4000000000000i64) == 0) )
v23 = 1;
switch( v4 )
{
case 5u:
goto LABEL_124;
case 6u:
v25 = &a3[6][2 * ((_QWORD)&a3[4]->Root + 1)];
v25->Root = (_RTL_BALANCED_NODE *)v24;
v25[1].Root = (_RTL_BALANCED_NODE *)v22;
goto LABEL_124;
case 0u:
MiFreePartitionPageRun(
(_MI_PARTITION *)*a3,
v11 + (*(_QWORD *)(a1 + 24) & 0x7FFFFFFFFFFFFFFFi64),
v22,
EntireRangeIsZeroed);
goto LABEL_124;
}
if( v4 == 1 )
break;
switch( v4 )
{
case 2u:
if( !v23 )
{
v28 = (v24 + 511) & 0xFFFFFFFFFFFFFE00ui64;
v29 = (v28 + v22) & 0xFFFFFFFFFFFFFE00ui64;
if( v28 < v29 )
{
LODWORD(OldIrql) = 0;
MiUpdateLargePageBitMap((UINT64)*a3, v28, v29 - v28, 1ui64, OldIrql);
}
}
goto LABEL_124;
case 3u:
if( !MiSplitPfnBitMaps((UINT64 *)*a3, v11 + (*(_QWORD *)(a1 + 24) & 0x7FFFFFFFFFFFFFFFi64), v22) )
*((_DWORD *)a3 + 5) = -1073741670;
goto LABEL_124;
case 4u:
if( !v23 && *a3 == (_RTL_AVL_TREE *)&Irp )
{
LODWORD(OldIrql) = 0;
MiUpdateLargePageBitMap((UINT64)*a3, v24, v22, 0i64, OldIrql);
}
LOBYTE(OldIrql) = *((_BYTE *)a3 + 16);
MiTransferPartitionPageRun((_MI_PARTITION *)a3[1], (_MI_PARTITION *)*a3, v24, v22, OldIrql);
goto LABEL_124;
case 8u:
if( v23 )
{
MiSetHugeRangePartitionId(
(UINT64 *)*a3,
(UINT64)a3[1],
v11 + (*(_QWORD *)(a1 + 24) & 0x7FFFFFFFFFFFFFFFi64),
v22);
}
else
{
v30 = (_MI_PARTITION *)a3[1];
if( v30 != &Irp )
{
LODWORD(OldIrql) = 0;
MiUpdateLargePageBitMap((UINT64)v30, v24, v22, 0i64, OldIrql);
}
Root = (__int16)(*a3)->Root;
v32 = &MmGetPfnDb()[v24];
v33 = &v32[v22];
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
p_u2 = &v32->u2;
v36 = (unsigned __int64)(Root & 0x3FF) << 39;
do
{
LODWORD(SpinCount[0]) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)p_u2, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)SpinCount);
while( p_u2->_bf_0 < 0 );
}
if( (p_u2[1].EntireField & 0x40000000) != 0 )
MiMoveBadPageCrossPartition((INT64)v32, (INT64)a3[1], (UINT64 *)*a3);
p_u2[2]._bf_0 = v36 | p_u2[2]._bf_0 & 0xFFFE007FFFFFFFFFui64;
_InterlockedAnd64(&p_u2->Lock, 0x7FFFFFFFFFFFFFFFui64);
++v32;
p_u2 += 6;
}
while( v32 != v33 );
__writecr8(CurrentIrql);
v6 = v58;
v4 = a2;
}
goto LABEL_124;
case 9u:
v37 = *((unsigned __int8 *)a3 + 17);
v38.QuadPart = v22 << 12;
v49 = *((_BYTE *)a3 + 18) == 0;
NumberOfBytes.QuadPart = v22 << 12;
if( v49 )
{
StartAddress.QuadPart = v24 << 12;
MiAddPhysicalMemoryChunks((_MI_PARTITION *)*a3, &StartAddress, &NumberOfBytes);
v38 = NumberOfBytes;
}
else
{
MiHotAddHugeRange(*a3, v24, v22, v37, *((unsigned __int8 *)a3 + 19));
}
v39 = v38.QuadPart / 4096;
if( !*((_BYTE *)a3 + 18) && *a3 != (_RTL_AVL_TREE *)&Irp )
{
v40 = (v24 + 511) & 0xFFFFFFFFFFFFFE00ui64;
v41 = (v40 + v39) & 0xFFFFFFFFFFFFFE00ui64;
if( v40 < v41 )
{
LODWORD(OldIrql) = 0;
MiUpdateLargePageBitMap((UINT64)&Irp, v40, v41 - v40, 1ui64, OldIrql);
}
}
if( v39 == v22 )
goto LABEL_124;
*((_DWORD *)a3 + 5) = -1073741823;
RtlClearBitsEx(v6, v11 + v39, v6->SizeOfBitMap - v11 - v39);
if( v39 )
a3[4] = (_RTL_AVL_TREE *)((char *)a3[4] + 1);
a3[5] = (_RTL_AVL_TREE *)((char *)a3[5] + v39);
return;
}
(*a3)[866].Root = (_RTL_BALANCED_NODE *)((char *)(*a3)[866].Root - v22);
BYTE4((*a3)[1].Root) = 1;
v42 = (_RTL_BITMAP_EX *)(*a3)[3].Root;
if( v42 )
{
v43 = *(_QWORD *)(a1 + 24) & 0x7FFFFFFFFFFFFFFFi64;
do
{
v44 = (__int64)v42[1].Buffer & 0x7FFFFFFFFFFFFFFFi64;
if( v43 < v44 )
{
v42 = (_RTL_BITMAP_EX *)v42->SizeOfBitMap;
}
else
{
if( v43 <= v44 )
break;
v42 = (_RTL_BITMAP_EX *)v42->Buffer;
}
}
while( v42 );
}
RtlClearBitsEx(v42 + 2, v11, v22);
v45 = v42[2].SizeOfBitMap;
if( !v45 )
goto LABEL_124;
if( v45 <= 1 )
{
if( _bittest64((const signed __int64 *)v42[2].Buffer, 0) )
goto LABEL_124;
LABEL_116:
RtlAvlRemoveNode((UINT64 *)&(*a3)[3], (INT64 *)v42);
v51 = a3[3];
v52 = 0;
if( !v51 )
goto LABEL_123;
while( 1 )
{
if( ((unsigned __int64)v42[1].Buffer & 0x7FFFFFFFFFFFFFFFi64) < ((unsigned __int64)v51[3].Root & 0x7FFFFFFFFFFFFFFFi64) )
{
v53 = v51->Root;
if( !v51->Root )
{
v52 = 0;
LABEL_123:
RtlAvlInsertNodeEx((_RTL_BALANCED_NODE **)a3 + 3, (UINT64)v51, v52, (_RTL_BALANCED_NODE *)v42);
goto LABEL_124;
}
}
else
{
v53 = v51[1].Root;
if( !v53 )
{
v52 = 1;
goto LABEL_123;
}
}
v51 = (_RTL_AVL_TREE *)v53;
}
}
v46 = v42[2].Buffer;
v47 = *v46;
v48 = &v46[(v45 - 1) >> 6];
if( v46 == v48 )
{
v49 = (v47 & (0xFFFFFFFFFFFFFFFFui64 >> (64 - (unsigned __int8)v42[2].SizeOfBitMap))) == 0;
}
else
{
for( k = v47 == 0; ; k = *v46 == 0 )
{
if( !k )
goto LABEL_124;
if( ++v46 == v48 )
break;
}
v49 = ((0xFFFFFFFFFFFFFFFFui64 >> ~((unsigned __int8)v45 - 1)) & *v46) == 0;
}
if( v49 )
goto LABEL_116;
LABEL_124:
a3[4] = (_RTL_AVL_TREE *)((char *)a3[4] + 1);
a3[5] = (_RTL_AVL_TREE *)((char *)a3[5] + v22);
if( v7 >= v6->SizeOfBitMap )
return;
}
v49 = v23 == 0;
v26 = v11 + (*(_QWORD *)(a1 + 24) & 0x7FFFFFFFFFFFFFFFi64);
if( !v49 )
{
MiHotRemoveHugeRange(v26, v22);
*((_DWORD *)a3 + 5) = 0;
LABEL_58:
RtlClearBitsEx(v6, v11, v22);
goto LABEL_124;
}
v27 = MiHotRemovePartitionPageRun(v26, v22);
*((_DWORD *)a3 + 5) = v27;
if( v27 >= 0 )
goto LABEL_58;
}Referenced by:
MiClearPartitionPageBitMap
MiFreePartitionNodePages
MiHotAddPartitionMemory
MiInsertPartitionPages
MiMakePartitionMemoryBlock
MiReturnPartitionPagesToParent
MiUpdatePartitionLargePfnBitMap