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