MiObtainDynamicVa

NTSTATUS __stdcall MiObtainDynamicVa(
        _MI_DYNAMIC_BITMAP *DynamicBitmap,
        UINT64 NumberOfRegions,
        _MI_SYSTEM_VA_TYPE VaType,
        UINT64 RegionAlignment){
  _MI_SYSTEM_VA_TYPE v4; 
  unsigned int v5; 
  _MI_DYNAMIC_BITMAP *v6; 
  __int64 v7; 
  unsigned __int64 Hint; 
  _RTL_BITMAP_EX *p_Bitmap; 
  unsigned __int64 v10; 
  unsigned __int64 SizeOfBitMap; 
  unsigned __int64 *Buffer; 
  unsigned __int64 v13; 
  unsigned __int64 v14; 
  unsigned __int64 v15; 
  unsigned __int64 *v16; 
  __int64 v17; 
  unsigned __int64 v18; 
  unsigned __int64 v19; 
  unsigned __int64 NextAlignedForwardRunClear; 
  unsigned __int64 v21; 
  unsigned __int64 v22; 
  unsigned __int64 *v23; 
  unsigned __int64 v24; 
  unsigned __int64 v25; 
  unsigned __int64 v26; 
  unsigned __int64 *v27; 
  __int64 v28; 
  unsigned __int64 v29; 
  unsigned __int64 v30; 
  unsigned __int64 v31; 
  unsigned __int64 v32; 
  _MI_SYSTEM_VA_TYPE v33; 
  __int64 v34; 
  __int64 v35; 
  unsigned __int64 v36; 
  __int64 v37; 
  __int64 v38; 
  unsigned __int64 *v39; 
  bool v40; 
  __int64 v41; 
  unsigned int v42; 
  unsigned __int64 v43; 
  unsigned __int64 v44; 
  __int64 v45; 
  __int64 v46; 
  unsigned __int64 *v47; 
  __int64 v48; 
  unsigned int v49; 
  unsigned __int64 v50; 
  unsigned __int64 v51; 
  __int64 v52; 
  __int64 v53; 
  __int64 v54; 
  unsigned __int64 v55; 
  __int64 v56; 
  unsigned int v57; 
  unsigned __int64 v58; 
  __int64 v59; 
  unsigned int v60; 
  unsigned int v61; 
  __int64 v62; 
  __int64 v63; 
  unsigned __int64 *v64; 
  __int64 v65; 
  unsigned __int64 *v66; 
  unsigned int v67; 
  __int64 v68; 
  bool v69; 
  __int64 v70; 
  unsigned int v71; 
  unsigned __int64 v72; 
  unsigned __int64 v73; 
  bool v74; 
  __int64 v75; 
  unsigned int v76; 
  unsigned __int64 v77; 
  unsigned __int64 v78; 
  unsigned __int64 v79; 
  unsigned __int64 v80; 
  UINT32 v82; 
  unsigned __int64 v83; 
  unsigned __int64 v84; 
  _RTL_BITMAP_EX *BitMapHeader; 
  __int64 v86; 
  _KLOCK_QUEUE_HANDLE LockHandle; 
  __int128 v88[5]; 
  unsigned int v90; 

  v90 = NumberOfRegions;
  v4 = VaType;
  v5 = NumberOfRegions;
  v6 = DynamicBitmap;
  memset(&LockHandle, 0, sizeof(LockHandle));
  v7 = 1i64;
  v86 = 1i64;
  v88[0] = 0i64;
  while( 1 )
  {
    Hint = v6->Hint;
    BitMapHeader = &v6->Bitmap;
    p_Bitmap = &v6->Bitmap;
    if( v4 == MiVaSystemPtesLarge )
    {
      p_Bitmap = (_RTL_BITMAP_EX *)v88;
      BitMapHeader = (_RTL_BITMAP_EX *)v88;
      v35 = (__int64)&v6->Bitmap.Buffer[v6->MaximumSize >> 6];
      Hint = v6->HintTopDown;
      v36 = -(v6->SizeTopDown >> 6);
      *(_QWORD *)&v88[0] = v6->SizeTopDown;
      *((_QWORD *)&v88[0] + 1) = v35 + 8 * v36;
      if( v5 >= 0x200 )
      {
        if( (MiFlags & 0x20000000) != 0 )
          v7 = 512i64;
        v86 = v7;
      }
    }
    if( !p_Bitmap->SizeOfBitMap )
      goto LABEL_85;
    v10 = v5;
    if( v7 == 1 )
    {
      SizeOfBitMap = p_Bitmap->SizeOfBitMap;
      Buffer = p_Bitmap->Buffer;
      v13 = Hint & -(__int64)(Hint < p_Bitmap->SizeOfBitMap);
      v14 = p_Bitmap->SizeOfBitMap - 1;
      v83 = v13;
      if( v5 )
      {
        while( 1 )
        {
          if( v14 - v13 + 1 < v10 )
            goto LABEL_66;
          v15 = v14 - v10 + 1;
          v16 = &Buffer[v13 >> 6];
          v17 = ((1i64 << (v13 & 0x3F)) - 1) | *v16;
          v18 = (unsigned __int64)&Buffer[v15 >> 6];
          if( v10 > 0x7F )
          {
            v55 = v18 + 8;
            if( (v15 & 0x3F) == 0 )
              v55 = (unsigned __int64)&Buffer[v15 >> 6];
            if( v17 )
            {
              if( *++v16 )
                goto LABEL_103;
              v40 = !_BitScanReverse64((unsigned __int64 *)&v56, v17);
              if( v40 )
                v57 = 64;
              else
                v57 = 63 - v56;
            }
            else
            {
              v57 = 0;
            }
LABEL_107:
            NextAlignedForwardRunClear = ((v16 - Buffer) << 6) - v57;
            if( NextAlignedForwardRunClear > v15 )
              goto LABEL_66;
            v64 = &v16[(v10 - v57) >> 6];
            while( ++v16 != v64 )
            {
              if( *v16 )
                goto LABEL_103;
            }
            v61 = ((_BYTE)v5 - (_BYTE)v57) & 0x3F;
            if( (((_BYTE)v5 - (_BYTE)v57) & 0x3F) != 0 )
            {
              v40 = !_BitScanForward64((unsigned __int64 *)&v62, *v16);
              if( v40 )
                LODWORD(v62) = 64;
              if( (unsigned int)v62 < v61 )
              {
LABEL_103:
                while( (unsigned __int64)v16 <= v55 )
                {
                  if( !*++v16 )
                  {
                    v40 = !_BitScanReverse64((unsigned __int64 *)&v63, *(v16 - 1));
                    if( v40 )
                      v57 = 64;
                    else
                      v57 = 63 - v63;
                    goto LABEL_107;
                  }
                }
                goto LABEL_66;
              }
            }
          }
          else if( v10 >= 0x40 )
          {
            do
            {
LABEL_132:
              v69 = v17 < 0;
              do
              {
                if( v69 )
                {
                  if( (unsigned __int64)++v16 > v18 )
                    goto LABEL_66;
                  v17 = *v16;
                  goto LABEL_132;
                }
                v40 = !_BitScanReverse64((unsigned __int64 *)&v70, v17);
                if( v40 )
                  v71 = 64;
                else
                  v71 = 63 - v70;
                NextAlignedForwardRunClear = ((v16 - Buffer + 1) << 6) - v71;
                if( NextAlignedForwardRunClear > v15 )
                  goto LABEL_66;
                v72 = v10 - v71;
                if( v10 == v71 )
                  goto LABEL_15;
                v17 = *++v16;
                if( v72 < 0x40 )
                  goto LABEL_141;
                v69 = v17 < 0;
              }
              while( v17 );
              v72 -= 64i64;
              if( !v72 )
                break;
              v17 = *++v16;
LABEL_141:
              v40 = !_BitScanForward64(&v73, v17);
              if( v40 )
                v73 = 64i64;
            }
            while( v73 < v72 );
          }
          else
          {
            if( v10 > 1 )
            {
              v38 = 0i64;
              v39 = &Buffer[v14 >> 6];
              while( v17 != -1 )
              {
LABEL_48:
                v40 = !_BitScanForward64((unsigned __int64 *)&v41, v17);
                if( v40 )
                  LODWORD(v41) = 64;
                if( (unsigned int)(v38 + v41) >= v10 )
                {
                  v45 = -v38;
LABEL_55:
                  NextAlignedForwardRunClear = ((v16 - Buffer) << 6) + v45;
                  goto LABEL_14;
                }
                v42 = v90;
                v43 = ~v17;
                while( 1 )
                {
                  v43 &= v43 >> (v42 >> 1);
                  if( !v43 )
                    break;
                  v42 -= v42 >> 1;
                  if( v42 <= 1 )
                  {
                    _BitScanForward64(&v44, v43);
                    v45 = (unsigned int)v44;
                    goto LABEL_55;
                  }
                }
                if( v16 == v39 )
                  goto LABEL_66;
                v40 = !_BitScanReverse64((unsigned __int64 *)&v53, v17);
                if( v40 )
                  v38 = 64i64;
                else
                  v38 = (unsigned int)(63 - v53);
                v17 = *++v16;
              }
              while( (unsigned __int64)++v16 <= v18 )
              {
                v17 = *v16;
                if( *v16 != -1i64 )
                {
                  v38 = 0i64;
                  goto LABEL_48;
                }
              }
LABEL_66:
              NextAlignedForwardRunClear = -1i64;
              goto LABEL_169;
            }
            while( v17 == -1 )
            {
              if( (unsigned __int64)++v16 > v18 )
                goto LABEL_66;
              v17 = *v16;
            }
            _BitScanForward64(&v19, ~v17);
            NextAlignedForwardRunClear = v19 + ((v16 - Buffer) << 6);
LABEL_14:
            if( NextAlignedForwardRunClear > v15 )
              goto LABEL_66;
          }
LABEL_15:
          if( NextAlignedForwardRunClear != -1i64 )
            goto LABEL_16;
LABEL_169:
          if( !v83 )
          {
LABEL_16:
            p_Bitmap = BitMapHeader;
            v7 = v86;
            goto LABEL_17;
          }
          LOBYTE(v5) = v90;
          v79 = v10 + Hint;
          if( v10 + Hint > SizeOfBitMap )
            v79 = SizeOfBitMap;
          v14 = v79 - 1;
          v13 = 0i64;
          v83 = 0i64;
        }
      }
      NextAlignedForwardRunClear = v13 & 0xFFFFFFFFFFFFFFF8ui64;
LABEL_17:
      v6 = DynamicBitmap;
      v4 = VaType;
      v84 = NextAlignedForwardRunClear;
    }
    else
    {
      NextAlignedForwardRunClear = MiFindNextAlignedForwardRunClearEx(p_Bitmap, v5, v7);
      v84 = NextAlignedForwardRunClear;
    }
    if( NextAlignedForwardRunClear == -1i64 )
    {
LABEL_85:
      if( !MiExtendDynamicBitMap((PHANDLE)v6, (_ACCESS_MASK)p_Bitmap, 0i64, (PUNICODE_STRING)(unsigned int)v4, 0, v82) )
        goto LABEL_184;
      goto LABEL_86;
    }
    KeAcquireInStackQueuedSpinLock(&v6->SpinLock, &LockHandle);
    if( v7 == 1 )
    {
      v21 = p_Bitmap->SizeOfBitMap;
      v22 = v84;
      v23 = p_Bitmap->Buffer;
      v24 = p_Bitmap->SizeOfBitMap - 1;
      v25 = v84 & -(__int64)(v84 < p_Bitmap->SizeOfBitMap);
      if( v10 )
      {
        while( v24 - v25 + 1 < v10 )
        {
          v31 = -1i64;
LABEL_175:
          if( !v25 )
          {
LABEL_31:
            v6 = DynamicBitmap;
            v32 = v31;
            p_Bitmap = BitMapHeader;
            goto LABEL_32;
          }
          v80 = v10 + v22;
          if( v10 + v22 > v21 )
            v80 = v21;
          v24 = v80 - 1;
          v25 = 0i64;
        }
        v26 = v24 - v10 + 1;
        v27 = &v23[v25 >> 6];
        v28 = ((1i64 << (v25 & 0x3F)) - 1) | *v27;
        v29 = (unsigned __int64)&v23[v26 >> 6];
        if( v10 > 0x7F )
        {
          v58 = v29 + 8;
          if( (v26 & 0x3F) == 0 )
            v58 = (unsigned __int64)&v23[v26 >> 6];
          if( v28 )
          {
            if( *++v27 )
              goto LABEL_112;
            v40 = !_BitScanReverse64((unsigned __int64 *)&v59, v28);
            if( v40 )
              v60 = 64;
            else
              v60 = 63 - v59;
          }
          else
          {
            v60 = 0;
          }
LABEL_117:
          v31 = ((v27 - v23) << 6) - v60;
          if( v31 > v26 )
            goto LABEL_67;
          v66 = &v27[(v10 - v60) >> 6];
          while( ++v27 != v66 )
          {
            if( *v27 )
              goto LABEL_112;
          }
          v67 = ((_BYTE)v90 - (_BYTE)v60) & 0x3F;
          if( (((_BYTE)v90 - (_BYTE)v60) & 0x3F) != 0 )
          {
            v40 = !_BitScanForward64((unsigned __int64 *)&v68, *v27);
            if( v40 )
              LODWORD(v68) = 64;
            if( (unsigned int)v68 < v67 )
            {
LABEL_112:
              while( (unsigned __int64)v27 <= v58 )
              {
                if( !*++v27 )
                {
                  v40 = !_BitScanReverse64((unsigned __int64 *)&v65, *(v27 - 1));
                  if( v40 )
                    v60 = 64;
                  else
                    v60 = 63 - v65;
                  goto LABEL_117;
                }
              }
              goto LABEL_67;
            }
          }
        }
        else
        {
          if( v10 < 0x40 )
          {
            if( v10 > 1 )
            {
              v46 = 0i64;
              v47 = &v23[v24 >> 6];
              while( v28 != -1 )
              {
LABEL_58:
                v40 = !_BitScanForward64((unsigned __int64 *)&v48, v28);
                if( v40 )
                  LODWORD(v48) = 64;
                if( (unsigned int)(v46 + v48) >= v10 )
                {
                  v52 = -v46;
LABEL_65:
                  v31 = ((v27 - v23) << 6) + v52;
                  goto LABEL_29;
                }
                v49 = v90;
                v50 = ~v28;
                while( 1 )
                {
                  v50 &= v50 >> (v49 >> 1);
                  if( !v50 )
                    break;
                  v49 -= v49 >> 1;
                  if( v49 <= 1 )
                  {
                    _BitScanForward64(&v51, v50);
                    v52 = (unsigned int)v51;
                    goto LABEL_65;
                  }
                }
                if( v27 == v47 )
                  goto LABEL_67;
                v40 = !_BitScanReverse64((unsigned __int64 *)&v54, v28);
                if( v40 )
                  v46 = 64i64;
                else
                  v46 = (unsigned int)(63 - v54);
                v28 = *++v27;
              }
              while( (unsigned __int64)++v27 <= v29 )
              {
                v28 = *v27;
                if( *v27 != -1i64 )
                {
                  v46 = 0i64;
                  goto LABEL_58;
                }
              }
            }
            else
            {
              while( v28 == -1 )
              {
                if( (unsigned __int64)++v27 > v29 )
                  goto LABEL_67;
                v28 = *v27;
              }
              _BitScanForward64(&v30, ~v28);
              v31 = v30 + ((v27 - v23) << 6);
LABEL_29:
              if( v31 <= v26 )
                goto LABEL_30;
            }
LABEL_67:
            v31 = -1i64;
LABEL_68:
            v22 = v84;
            goto LABEL_175;
          }
          do
          {
LABEL_148:
            v74 = v28 < 0;
            do
            {
              if( v74 )
              {
                if( (unsigned __int64)++v27 > v29 )
                  goto LABEL_67;
                v28 = *v27;
                goto LABEL_148;
              }
              v40 = !_BitScanReverse64((unsigned __int64 *)&v75, v28);
              if( v40 )
                v76 = 64;
              else
                v76 = 63 - v75;
              v31 = ((v27 - v23 + 1) << 6) - v76;
              if( v31 > v26 )
                goto LABEL_67;
              v77 = v10 - v76;
              if( v10 == v76 )
                goto LABEL_30;
              v28 = *++v27;
              if( v77 < 0x40 )
                goto LABEL_157;
              v74 = v28 < 0;
            }
            while( v28 );
            v77 -= 64i64;
            if( !v77 )
              break;
            v28 = *++v27;
LABEL_157:
            v40 = !_BitScanForward64(&v78, v28);
            if( v40 )
              v78 = 64i64;
          }
          while( v78 < v77 );
        }
LABEL_30:
        if( v31 != -1i64 )
          goto LABEL_31;
        goto LABEL_68;
      }
      v32 = v25 & 0xFFFFFFFFFFFFFFF8ui64;
    }
    else
    {
      v32 = MiFindNextAlignedForwardRunClearEx(p_Bitmap, v10, v7);
    }
LABEL_32:
    if( v32 != -1i64 )
      break;
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
    __writecr8(LockHandle.OldIrql);
    v4 = VaType;
    if( !MiExtendDynamicBitMap(
            (PHANDLE)v6,
            (_ACCESS_MASK)p_Bitmap,
            0i64,
            (PUNICODE_STRING)(unsigned int)VaType,
            0,
            v82) )
    {
LABEL_184:
      LODWORD(v34) = 0;
      return v34;
    }
    v7 = v86;
LABEL_86:
    v5 = v90;
  }
  RtlSetBitsEx(p_Bitmap, v32, v10);
  v33 = VaType;
  if( VaType == MiVaSystemPtesLarge )
  {
    v37 = 8 * ((char *)p_Bitmap->Buffer - (char *)v6->Bitmap.Buffer);
    if( v90 == 1 )
      v6->HintTopDown = v32 + 1;
    v32 += v37;
    v33 = MiVaSystemPtes;
  }
  else if( v90 == 1 )
  {
    v6->Hint = v32 + 1;
  }
  if( v6 == (_MI_DYNAMIC_BITMAP *)((char *)&stru_140C4DB30 + 968) )
  {
    *(&stru_140C4DB30 + 75) -= v10 << 21;
    MiReclaimSystemVa(0i64);
  }
  _InterlockedExchangeAdd64((volatile signed __int64 *)&stru_140C4DB30 + v33 + 875, v10);
  KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
  __writecr8(LockHandle.OldIrql);
  return(NTSTATUS)v6->BaseVa + 0x200000 * v32;
}

Referenced by:

MiObtainSystemVa
MiReservePoolMemory