MiFindContiguousPages

INT64 __fastcall MiFindContiguousPages(
        _MI_PARTITION *Partition,
        UINT64 LowestPfn,
        UINT64 HighestPfn,
        UINT64 BoundaryPfn,
        UINT64 SizeInPages,
        _MI_PFN_CACHE_ATTRIBUTE CacheAttribute,
        UINT64 PreferredNode,
        UINT64 PreferredChannel,
        UINT64 Flags,
        UINT64 *StartingPfn){
  UINT64 v11; 
  _MI_PARTITION *v13; 
  UINT64 v14; 
  unsigned __int8 CurrentIrql; 
  int v17; 
  int v18; 
  bool v19; 
  UINT64 v20; 
  unsigned int v21; 
  unsigned int v22; 
  unsigned int v23; 
  _MMPFN *LargeNodePage; 
  unsigned int v25; 
  __int64 v26; 
  unsigned int v27; 
  UINT64 *v28; 
  UINT64 v29; 
  int v30; 
  int v31; 
  PHYSICAL_MEMORY_DESCRIPTOR *v32; 
  __int64 v33; 
  int *v34; 
  unsigned int v35; 
  __int64 v36; 
  UINT64 v37; 
  unsigned int v38; 
  unsigned int v39; 
  unsigned __int8 *v40; 
  int v41; 
  void *v42; 
  __int64 v43; 
  __int64 v44; 
  unsigned int v45; 
  unsigned __int64 v46; 
  int v47; 
  __int64 v48; 
  __int64 v49; 
  int v50; 
  __int64 v51; 
  __int64 v52; 
  __int64 v53; 
  __int64 v54; 
  unsigned __int64 v55; 
  char v56; 
  __int64 v57; 
  _MMPFN *v58; 
  unsigned __int64 v59; 
  int v60; 
  INT64 v61; 
  _MMPFN *v62; 
  UINT8 v63; 
  int v64; 
  int v65; 
  unsigned int *v66; 
  unsigned __int64 v67; 
  UINT64 v68; 
  _MI_PFN_CACHE_ATTRIBUTE v69; 
  char *v70; 
  struct _KPRCB *CurrentPrcb; 
  __int64 v72; 
  signed __int32 v73; 
  UINT64 PfnState; 
  UINT64 PfnStatea; 
  UINT64 *ZeroFreeCount; 
  int v77; 
  int v78; 
  int v79; 
  INT64 v81; 
  unsigned __int8 *v82; 
  int v83; 
  UINT64 LargePageIndex; 
  int v85; 
  int v86; 
  __int64 v87; 
  int v88; 
  int v89; 
  unsigned __int8 *v90; 
  unsigned int *v91; 
  __int64 v92; 
  __int64 v93; 
  __int64 v94; 
  UINT64 v95; 
  __int64 v96; 
  UINT64 v97; 
  UINT64 v98; 
  bool v99; 
  int v100; 
  __int16 v101; 
  char v102; 
  ULONG_PTR BugCheckParameter2; 
  UINT64 *v104; 
  unsigned int *v105; 
  __int64 *v106; 
  INT64 v107[2]; 
  __int64 v108; 
  __int64 v109; 
  __int64 *v110; 
  v11 = SizeInPages;
  v13 = Partition;
  v106 = v110;
  v14 = 0i64;
  BugCheckParameter2 = HighestPfn;
  v93 = 0i64;
  v94 = 0i64;
  v100 = 0;
  v101 = 0;
  v104 = StartingPfn;
  *(_OWORD *)v107 = 0i64;
  v108 = 0i64;
  v102 = 0;
  CurrentIrql = KeGetCurrentIrql();
  if( CurrentIrql > 2u )
    return 3221225659i64;
  if( (unsigned int)PreferredNode < (unsigned __int16)KeNumberNodes
    && !*(_QWORD *)(4544i64 * (unsigned int)PreferredNode + *((_QWORD *)Partition + 2) + 4176)
    && *(_DWORD *)InitializationPhase )
  {
    return 3221225495i64;
  }
  v17 = Flags | 8;
  if( CurrentIrql != 2 )
    v17 = Flags;
  v77 = v17;
  if( (v17 & 0x20000000) == 0 )
  {
    if( (MiAcquireNonPagedResources(v13, SizeInPages) & 0x80000000) != 0i64 )
      return 3221225626i64;
    v17 = v77;
    v11 = SizeInPages;
  }
  if( StartingPfn )
    v85 = v11 + (*((_DWORD *)StartingPfn + 10) >> 12);
  else
    v85 = 0;
  if( (v17 & 0x40) != 0 )
  {
    v18 = v17 | 0x8000;
    v19 = LowestPfn == 0x100000;
    v20 = SizeInPages;
    if( !v19 )
      v18 = v17;
    v21 = (KeFeatureBits & 0x2000000000i64) == 0;
    LODWORD(LargePageIndex) = v21;
    v22 = v21;
    do
    {
      v23 = v22;
      if( SizeInPages == MiLargePageSizes[v22] )
        break;
      ++v22;
      LODWORD(LargePageIndex) = v23 + 1;
      v21 = v23 + 1;
    }
    while( v23 + 1 < 3 );
    LODWORD(PfnState) = v18;
    LargeNodePage = MiFindLargeNodePage(v13, (unsigned int)PreferredNode, &LargePageIndex, v21, PfnState);
    if( LargeNodePage )
    {
      v26 = (LargeNodePage - MmGetPfnDb()) / 48;
      *v106 = v26;
      if( StartingPfn )
      {
        v27 = *((_DWORD *)StartingPfn + 10);
        v28 = &StartingPfn[((unsigned __int64)v27 >> 12) + 6];
        if( (*((_DWORD *)LargeNodePage + 4) & 0x3E0i64) != 0 )
          StartingPfn[3] = 1i64;
        if( SizeInPages )
        {
          do
          {
            v29 = v26 + v14++;
            *v28++ = v29;
          }
          while( v14 < SizeInPages );
          v27 = *((_DWORD *)StartingPfn + 10);
        }
        *((_DWORD *)StartingPfn + 10) = v27 + ((_DWORD)SizeInPages << 12);
      }
      return 0i64;
    }
    v25 = -1073741801;
    goto LABEL_129;
  }
  if( (*((_DWORD *)v13 + 1) & 0x20) == 0 )
  {
    if( !(unsigned int)MiSufficientAvailablePages((INT64)v13, v11 + 160) )
    {
      v25 = -1073741670;
      goto LABEL_128;
    }
    v17 = v77;
  }
  v88 = v17 & 0x10000000;
  if( (v17 & 0x10000000) == 0 )
  {
    MiCreatePteCopyList(SizeInPages, 0x40ui64, (__int64)v107);
    if( !HIDWORD(v107[0]) )
    {
      v25 = -1073741670;
      goto LABEL_128;
    }
    v17 = v77;
  }
  v30 = 0;
  v78 = 0;
  if( (v17 & 0xB000008) == 0x8000000 && *(_DWORD *)InitializationPhase )
  {
    if( CurrentIrql != 2 )
      v30 = 1;
    v78 = v30;
  }
  v31 = PreferredNode | 0x80000000;
  if( (unsigned int)PreferredNode < (unsigned __int16)KeNumberNodes )
    v31 = PreferredNode;
  v79 = v31;
  v32 = MiReferencePageRuns(v13, 1ui64);
  v33 = *((_QWORD *)v13 + 2);
  v34 = (int *)v32;
  v81 = (INT64)v32;
  v95 = LowestPfn;
  v35 = v77;
  v36 = (__int64)&v32->Run[v32->NumberOfRuns];
  v105 = 0i64;
  v98 = SizeInPages;
  v37 = 0i64;
  if( ((BoundaryPfn - 1) & BoundaryPfn) == 0 )
    v37 = BoundaryPfn;
  v87 = v36;
  v91 = 0i64;
  v97 = v37;
  v86 = v77 & 0x2000;
  v99 = v86 != 0;
  v83 = 0;
  v92 = v33;
  while( 2 )
  {
    v38 = -1;
    while( 2 )
    {
      v39 = MmNumberOfChannels;
      v40 = 0i64;
      v82 = 0i64;
      if( (unsigned int)MmNumberOfChannels <= 1 )
      {
        v41 = v79;
LABEL_66:
        v46 = (unsigned __int64)&v40[v39];
        v90 = (unsigned __int8 *)v46;
        goto LABEL_68;
      }
      v41 = v79;
      if( v79 >= 0 )
      {
        v44 = (unsigned int)v79;
      }
      else
      {
        if( v38 == -1 )
        {
          v42 = (void *)*((_QWORD *)v13 + 865);
          if( BugCheckParameter2 <= (unsigned __int64)v42 )
            v42 = (void *)BugCheckParameter2;
          LODWORD(v43) = MiSearchNumaNodeTable(v42);
          v40 = 0i64;
          v34 = (int *)v81;
          v38 = *(_DWORD *)(v43 + 8);
          v91 = (unsigned int *)(qword_140C4DBD8 + 4i64 * v38 * (unsigned __int16)KeNumberNodes);
          v36 = v87;
          v105 = &v91[(unsigned __int16)KeNumberNodes];
          v33 = v92;
        }
        v44 = v38;
      }
      if( (*(_DWORD *)(4544 * v44 + v33 + 4280) & 1) == 0 )
        goto LABEL_66;
      v40 = (unsigned __int8 *)(4544 * v44 + v33 + 4317);
      v82 = v40;
      if( (PreferredChannel & 0x80000000) != 0i64 )
        goto LABEL_66;
      v45 = 0;
      do
      {
        if( *v40 == (_DWORD)PreferredChannel )
          break;
        ++v40;
        ++v45;
      }
      while( v45 < v39 );
      v82 = v40;
      v46 = (unsigned __int64)(v40 + 1);
      v90 = v40 + 1;
      while( 1 )
      {
LABEL_68:
        v96 = BugCheckParameter2;
        v47 = *v34;
        if( *v34 )
        {
          while( 1 )
          {
            v48 = (unsigned int)(v47 - 1);
            v89 = v48;
            v49 = *(unsigned int *)(v36 + 8 * v48);
            v50 = *(_DWORD *)(v36 + 8 * v48 + 4);
            v48 *= 2i64;
            v51 = *(_QWORD *)&v34[2 * v48 + 4];
            v52 = *(_QWORD *)&v34[2 * v48 + 6];
            v93 = v51;
            v94 = v52 + v51;
            if( v95 >= v52 + v51 )
              break;
            if( (v41 < 0 || (_DWORD)v49 == v41) && (!v40 || v50 == *v40) )
            {
              if( (unsigned int)MiCollapseRunTopDown((__int64)&v93) )
              {
                v53 = 4544 * v49;
                v109 = 4544 * v49;
                while( 1 )
                {
                  if( !*(_QWORD *)(v53 + *((_QWORD *)v13 + 2) + 4176) && *(_DWORD *)InitializationPhase )
                  {
LABEL_102:
                    v41 = v79;
                    break;
                  }
                  v54 = v94;
                  v55 = v98;
                  HIDWORD(LargePageIndex) = 0;
                  v56 = v99;
                  if( v99 && v98 > v94 - v93 )
                    v55 = v94 - v93;
                  v57 = v94 - v55;
                  v58 = (_MMPFN *)((char *)MmGetPfnDb() + 48 * (v94 - v55));
                  if( !v99 )
                  {
                    v59 = MiPfnsWorthTrying(
                            Partition,
                            v58,
                            v98,
                            v35,
                            (UINT64 *)((char *)&LargePageIndex + 4),
                            ZeroFreeCount);
                    if( v59 )
                      goto LABEL_97;
                    if( HIDWORD(LargePageIndex) == 1 )
                      MiEmptyKernelStackCache();
                  }
                  v59 = MiClaimPhysicalRun(
                          (__int64)Partition,
                          v54 - v55,
                          v55,
                          v96,
                          (__int64)v107,
                          v77,
                          -1,
                          (__int64)v104,
                          CacheAttribute,
                          0i64);
                  if( v104 )
                  {
                    v60 = *((_DWORD *)v104 + 10) >> 12;
                    if( v60 == v85 )
                      goto LABEL_118;
                    v98 = (unsigned int)(v85 - v60);
                  }
                  else if( !v59 )
                  {
LABEL_118:
                    MiDereferencePageRunsEx(v81, 1i64);
                    MiReleasePteCopyList((INT64)v107);
                    if( v86 )
                    {
                      v69 = CacheAttribute;
                    }
                    else
                    {
                      v67 = (v57 + 511) & 0xFFFFFFFFFFFFFE00ui64;
                      v68 = (SizeInPages + v57) & 0xFFFFFFFFFFFFFE00ui64;
                      if( v67 < v68 )
                      {
                        LODWORD(PfnStatea) = 1;
                        MiUpdateLargePageBitMap((UINT64)Partition, v67, v68 - v67, 1ui64, PfnStatea);
                      }
                      v69 = CacheAttribute;
                      MiConvertContiguousPages((UINT64 *)v58, SizeInPages, (unsigned int)CacheAttribute);
                    }
                    if( (v77 & 0x40000000) == 0 )
                    {
                      v70 = (char *)v58 + 48 * SizeInPages;
                      do
                      {
                        LODWORD(PfnStatea) = ((v77 & 0x100000) != 0) + 1;
                        MiSetPfnOwnedAndActive((INT64)v58, 0, -8i64, (unsigned int)v69, PfnStatea);
                        v58 = (_MMPFN *)((char *)v58 + 48);
                      }
                      while( v58 != (_MMPFN *)v70 );
                    }
                    *v106 = v57;
                    return 0i64;
                  }
                  if( *(_MI_PARTITION **)(qword_140C4E388 + 8 * ((*((_QWORD *)v58 + 5) >> 39) & 0x3FFi64)) == Partition )
                  {
                    if( MiIsPageOnBadList((INT64)v58) )
                    {
                      MiLockPage(v61);
                      if( MiIsPageOnBadList((INT64)v58) )
                      {
                        if( v88 )
                        {
                          MiUnlockPage(v62, v63);
                          v40 = v82;
                          v46 = (unsigned __int64)v90;
                          v64 = 0;
                          v78 = 0;
                          goto LABEL_108;
                        }
                      }
                      else
                      {
                        v83 = 1;
                      }
                      MiUnlockPage(v62, v63);
                    }
                    else
                    {
                      v83 = 1;
                    }
                  }
LABEL_97:
                  if( v59 >= v54 - v93 || !v56 && v54 - v93 - v59 < v55 )
                    v96 = v54 - v59 - 1;
                  v94 = v54 - v59;
                  v65 = MiCollapseRunTopDown((__int64)&v93);
                  v13 = Partition;
                  v53 = v109;
                  v35 = v77;
                  if( !v65 )
                    goto LABEL_102;
                }
              }
              v40 = v82;
              v34 = (int *)v81;
            }
            v47 = v89;
            if( !v89 )
              break;
            v36 = v87;
          }
          v46 = (unsigned __int64)v90;
        }
        v64 = v78;
LABEL_108:
        if( !v40 )
          goto LABEL_113;
        v13 = Partition;
        ++v40;
        v41 = v79;
        v34 = (int *)v81;
        v36 = v87;
        v82 = v40;
        if( (unsigned __int64)v40 >= v46 )
          break;
        v35 = v77;
      }
      if( v38 != -1 )
      {
        v66 = v91 + 1;
        v91 = v66;
        if( v66 != v105 )
        {
          v38 = *v66;
          v33 = v92;
          v35 = v77;
          continue;
        }
      }
      break;
    }
LABEL_113:
    if( v64 && v83 == 1 )
    {
      v13 = Partition;
      if( byte_140C4EC1C )
        MiQueueWorkingSetRequest(Partition, 0x20ui64);
      v35 = v77;
      v34 = (int *)v81;
      v36 = v87;
      v33 = v92;
      v78 = 0;
      continue;
    }
    break;
  }
  v25 = -1073741801;
  MiDereferencePageRunsEx(v81, 1i64);
  v13 = Partition;
LABEL_128:
  v18 = v77;
  v20 = SizeInPages;
LABEL_129:
  MiReleasePteCopyList((INT64)v107);
  if( (v18 & 0x20000000) == 0 )
  {
    MiReturnCommit(v13, v20);
    if( v13 == (_MI_PARTITION *)&MiSystemPartition )
    {
      CurrentPrcb = KeGetCurrentPrcb();
      v72 = *((int *)CurrentPrcb + 8391);
      if( (_DWORD)v72 != -1 )
      {
        if( v20 + v72 <= 0x100 )
        {
          do
          {
            if( v20 >= 0x80000 )
              break;
            v73 = _InterlockedCompareExchange((volatile signed __int32 *)CurrentPrcb + 8391, v20 + v72, v72);
            v19 = (_DWORD)v72 == v73;
            LODWORD(v72) = v73;
            if( v19 )
              return v25;
          }
          while( v73 != -1 && v20 + v73 <= 0x100 );
        }
        if( (int)v72 > 192
          && (_DWORD)v72 != -1
          && (_DWORD)v72 == _InterlockedCompareExchange((volatile signed __int32 *)CurrentPrcb + 8391, 192, v72) )
        {
          v20 += (int)v72 - 192;
        }
      }
    }
    if( v20 )
      _InterlockedExchangeAdd64((volatile signed __int64 *)v13 + 896, v20);
  }
  return v25;
}

Referenced by:

MiAllocateContiguousMemory
MiAllocateDriverPage
MiAllocateMostlyContiguousPagesForMdl
MiAllocateSkipPagesForMdl
MiAllocateSlabEntry
MiFindLargePageMemory
MiIdealClusterPage
MiMapSystemImageWithLargePage
MiRebuildLargePage
MiWaitForInPageComplete
MmMarkPhysicalMemoryAsBad
MmRemovePhysicalMemory