MiFindContiguousPages
NTSTATUS __stdcall MiFindContiguousPages(
_MI_PARTITION *Partition,
UINT64 LowestPfn,
UINT64 HighestPfn,
UINT64 BoundaryPfn,
UINT64 SizeInPages,
_MI_PFN_CACHE_ATTRIBUTE CacheAttribute,
UINT64 PreferredNode,
UINT64 Flags,
UINT64 *StartingPfn){
UINT64 v10;
_MI_PARTITION *v12;
UINT64 v13;
unsigned __int8 CurrentIrql;
unsigned int v16;
int v17;
int v18;
bool v19;
UINT64 v20;
unsigned int v21;
unsigned int v22;
unsigned int v23;
_MMPFN *LargeNodePage;
NTSTATUS v25;
__int64 v26;
unsigned int v27;
UINT64 *v28;
UINT64 v29;
int v30;
int v31;
PHYSICAL_MEMORY_DESCRIPTOR *v32;
__int64 NodeInformation;
int *v34;
unsigned int v35;
__int64 v36;
UINT64 v37;
unsigned int v38;
unsigned int v39;
unsigned __int8 *v40;
int v41;
PVOID HighestPhysicalPage;
__int64 v43;
__int64 v44;
unsigned int v45;
unsigned __int64 v46;
int v47;
__int64 v48;
__int64 v49;
int v50;
__int64 v51;
__int64 v52;
int v53;
__int64 v54;
__int64 v55;
UINT64 v56;
char v57;
UINT64 v58;
_MMPFN *v59;
unsigned __int64 v60;
unsigned __int64 v61;
unsigned __int64 v62;
int v63;
int v64;
_MMPFN *v65;
int v66;
_MMPFN *v67;
UINT8 v68;
int v69;
int v70;
unsigned int *v71;
unsigned __int64 v72;
UINT64 v73;
_MI_PFN_CACHE_ATTRIBUTE v74;
_MMPFN *v75;
struct _KPRCB *CurrentPrcb;
__int64 CachedResidentAvailable;
signed __int32 v78;
UINT64 PfnState;
UINT64 PfnStatea;
UINT64 *ZeroFreeCount;
UINT64 *ReplacementPage;
unsigned int ReplacementColor;
int ReplacementColor_4;
int v85;
INT64 v87;
unsigned __int8 *v88;
int v89;
UINT64 LargePageIndex;
int v91;
unsigned int v92;
__int64 v93;
unsigned int v94;
int v95;
unsigned __int8 *v96;
unsigned int *v97;
__int64 v98;
_MI_PAGE_RANGE PageRange;
_MMPTE_COPY_LIST *v100;
UINT64 v101;
UINT64 v102;
bool v103;
int v104;
__int16 v105;
char v106;
PVOID BugCheckParameter2;
__int64 v108;
unsigned int *v109;
__int64 *v110;
_MMPTE_COPY_LIST PteCopyList[4];
__int64 v112;
__int64 v113;
__int64 v114;
__int64 *v115;
v10 = SizeInPages;
v12 = Partition;
v110 = v115;
v13 = 0i64;
BugCheckParameter2 = (PVOID)HighestPfn;
*(_QWORD *)&PageRange.BasePage = 0i64;
*(_QWORD *)&PageRange.LowestPageOkToUse = 0i64;
v104 = 0;
v105 = 0;
v108 = v114;
*(_OWORD *)PteCopyList = 0i64;
v112 = 0i64;
v106 = 0;
CurrentIrql = KeGetCurrentIrql();
if( CurrentIrql > 2u )
return -1073741637;
if( (unsigned int)PreferredNode < (unsigned __int16)KeNumberNodes
&& !Partition->Core.NodeInformation[(unsigned int)PreferredNode].TotalPagesEntireNode
&& (_DWORD)InitializationPhase )
{
return -1073741801;
}
v16 = (unsigned int)StartingPfn | 8;
if( CurrentIrql != 2 )
v16 = (unsigned int)StartingPfn;
ReplacementColor = v16;
if( (v16 & 0x20000000) == 0 )
{
MiAcquireNonPagedResources(v12, SizeInPages);
if( v17 < 0 )
return -1073741670;
v16 = ReplacementColor;
v10 = SizeInPages;
}
if( v114 )
v91 = v10 + (*(_DWORD *)(v114 + 40) >> 12);
else
v91 = 0;
if( (v16 & 0x40) != 0 )
{
v18 = v16 | 0x8000;
v19 = LowestPfn == 0x100000;
v20 = SizeInPages;
if( !v19 )
v18 = v16;
v21 = ((unsigned __int64)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(v12, (unsigned int)PreferredNode, &LargePageIndex, v21, PfnState);
if( LargeNodePage )
{
v26 = LargeNodePage - MmGetPfnDb();
*v110 = v26;
if( v114 )
{
v27 = *(_DWORD *)(v114 + 40);
v28 = (UINT64 *)(v114 + 8 * (((unsigned __int64)v27 >> 12) + 6));
if( (*(_DWORD *)(&LargeNodePage->3 + 1) & 0x3E0i64) != 0 )
*(_QWORD *)(v114 + 24) = 1i64;
if( SizeInPages )
{
do
{
v29 = v26 + v13++;
*v28++ = v29;
}
while( v13 < SizeInPages );
v27 = *(_DWORD *)(v114 + 40);
}
*(_DWORD *)(v114 + 40) = v27 + ((_DWORD)SizeInPages << 12);
}
return 0;
}
v25 = -1073741801;
goto LABEL_129;
}
if( (v12->Core.u.LongFlags & 0x20) == 0 )
{
if( !MiSufficientAvailablePages((INT64)v12, v10 + 160) )
{
v25 = -1073741670;
goto LABEL_128;
}
v16 = ReplacementColor;
}
v94 = v16 & 0x10000000;
if( (v16 & 0x10000000) == 0 )
{
MiCreatePteCopyList(SizeInPages, 0x40ui64, PteCopyList);
if( !PteCopyList[1] )
{
v25 = -1073741670;
goto LABEL_128;
}
v16 = ReplacementColor;
}
v30 = 0;
ReplacementColor_4 = 0;
if( (v16 & 0xB000008) == 0x8000000 && (_DWORD)InitializationPhase )
{
if( CurrentIrql != 2 )
v30 = 1;
ReplacementColor_4 = v30;
}
v31 = PreferredNode | 0x80000000;
if( (unsigned int)PreferredNode < (unsigned __int16)KeNumberNodes )
v31 = PreferredNode;
v85 = v31;
v32 = MiReferencePageRuns((ULONG_PTR *)&v12->Core.PartitionId, 1ui64);
NodeInformation = (__int64)v12->Core.NodeInformation;
v34 = (int *)v32;
v87 = (INT64)v32;
*(_QWORD *)&PageRange.BoundaryPage = LowestPfn;
v35 = ReplacementColor;
v36 = (__int64)&v32->Run[v32->NumberOfRuns];
v109 = 0i64;
v102 = SizeInPages;
v37 = 0i64;
if( ((BoundaryPfn - 1) & BoundaryPfn) == 0 )
v37 = BoundaryPfn;
v93 = v36;
v97 = 0i64;
v101 = v37;
v92 = ReplacementColor & 0x2000;
v103 = v92 != 0;
v89 = 0;
v98 = NodeInformation;
while( 2 )
{
v38 = -1;
while( 2 )
{
v39 = MmNumberOfChannels;
v40 = 0i64;
v88 = 0i64;
if( (unsigned int)MmNumberOfChannels <= 1 )
{
v41 = v85;
LABEL_66:
v46 = (unsigned __int64)&v40[v39];
v96 = (unsigned __int8 *)v46;
goto LABEL_68;
}
v41 = v85;
if( v85 >= 0 )
{
v44 = (unsigned int)v85;
}
else
{
if( v38 == -1 )
{
HighestPhysicalPage = (PVOID)v12->Vp.HighestPhysicalPage;
if( BugCheckParameter2 <= HighestPhysicalPage )
HighestPhysicalPage = BugCheckParameter2;
LODWORD(v43) = MiSearchNumaNodeTable(HighestPhysicalPage);
v40 = 0i64;
v34 = (int *)v87;
v38 = *(_DWORD *)(v43 + 8);
v97 = (unsigned int *)(*(&stru_140C4DB30 + 21) + 4i64 * v38 * (unsigned __int16)KeNumberNodes);
v36 = v93;
v109 = &v97[(unsigned __int16)KeNumberNodes];
NodeInformation = v98;
}
v44 = v38;
}
if( (*(_DWORD *)(4544 * v44 + NodeInformation + 4280) & 1) == 0 )
goto LABEL_66;
v40 = (unsigned __int8 *)(4544 * v44 + NodeInformation + 4317);
v88 = v40;
if( (Flags & 0x80000000) != 0i64 )
goto LABEL_66;
v45 = 0;
do
{
if( *v40 == (_DWORD)Flags )
break;
++v40;
++v45;
}
while( v45 < v39 );
v88 = v40;
v46 = (unsigned __int64)(v40 + 1);
v96 = v40 + 1;
while( 1 )
{
LABEL_68:
v100 = (_MMPTE_COPY_LIST *)BugCheckParameter2;
v47 = *v34;
if( *v34 )
{
while( 1 )
{
v48 = (unsigned int)(v47 - 1);
v95 = 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];
*(_QWORD *)&PageRange.BasePage = v51;
*(_QWORD *)&PageRange.LowestPageOkToUse = v52 + v51;
if( *(_QWORD *)&PageRange.BoundaryPage >= (unsigned __int64)(v52 + v51) )
break;
if( (v41 < 0 || (_DWORD)v49 == v41) && (!v40 || v50 == *v40) )
{
MiCollapseRunTopDown(&PageRange);
if( v53 )
{
v54 = 4544 * v49;
v113 = 4544 * v49;
while( 1 )
{
if( !*(unsigned __int64 *)((char *)&v12->Core.NodeInformation->TotalPages[4] + v54)
&& (_DWORD)InitializationPhase )
{
LABEL_102:
v41 = v85;
break;
}
v55 = *(_QWORD *)&PageRange.LowestPageOkToUse;
v56 = v102;
HIDWORD(LargePageIndex) = 0;
v57 = v103;
if( v103 && v102 > *(_QWORD *)&PageRange.LowestPageOkToUse - *(_QWORD *)&PageRange.BasePage )
v56 = *(_QWORD *)&PageRange.LowestPageOkToUse - *(_QWORD *)&PageRange.BasePage;
v58 = *(_QWORD *)&PageRange.LowestPageOkToUse - v56;
v59 = &MmGetPfnDb()[*(_QWORD *)&PageRange.LowestPageOkToUse - v56];
if( !v103 )
{
MiPfnsWorthTrying(Partition, v59, v102, v35, (UINT64 *)((char *)&LargePageIndex + 4), ZeroFreeCount);
v61 = v60;
if( v60 )
goto LABEL_97;
if( HIDWORD(LargePageIndex) == 1 )
MiEmptyKernelStackCache();
}
LODWORD(ReplacementPage) = -1;
LODWORD(ZeroFreeCount) = ReplacementColor;
LODWORD(v62) = MiClaimPhysicalRun(
Partition,
v55 - v56,
v56,
v100,
(UINT64)PteCopyList,
(UINT64)ZeroFreeCount,
ReplacementPage);
v61 = v62;
if( v108 )
{
v63 = *(_DWORD *)(v108 + 40) >> 12;
if( v63 == v91 )
goto LABEL_118;
v102 = (unsigned int)(v91 - v63);
}
else if( !v62 )
{
LABEL_118:
MiDereferencePageRunsEx(v87, 1i64);
MiReleasePteCopyList(PteCopyList);
if( v92 )
{
v74 = CacheAttribute;
}
else
{
v72 = (v58 + 511) & 0xFFFFFFFFFFFFFE00ui64;
v73 = (SizeInPages + v58) & 0xFFFFFFFFFFFFFE00ui64;
if( v72 < v73 )
{
LODWORD(PfnStatea) = 1;
MiUpdateLargePageBitMap((UINT64)Partition, v72, v73 - v72, 1ui64, PfnStatea);
}
v74 = CacheAttribute;
MiConvertContiguousPages(v59, SizeInPages, CacheAttribute);
}
if( (ReplacementColor & 0x40000000) == 0 )
{
v75 = &v59[SizeInPages];
do
{
LODWORD(PfnStatea) = ((ReplacementColor & 0x100000) != 0) + 1;
MiSetPfnOwnedAndActive(v59++, 0i64, (_MMPTE *)0xFFFFFFFFFFFFFFF8i64, v74, PfnStatea);
}
while( v59 != v75 );
}
*v110 = v58;
return 0;
}
if( *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267)
+ 8 * (((unsigned __int64)v59->u4._bf_0 >> 39) & 0x3FF)) == Partition )
{
LOBYTE(v64) = MiIsPageOnBadList((INT64)v59);
if( v64 )
{
MiLockPage(v65);
LOBYTE(v66) = MiIsPageOnBadList((INT64)v59);
if( v66 )
{
if( v94 )
{
MiUnlockPage(v67, v68);
v40 = v88;
v46 = (unsigned __int64)v96;
v69 = 0;
ReplacementColor_4 = 0;
goto LABEL_108;
}
}
else
{
v89 = 1;
}
MiUnlockPage(v67, v68);
}
else
{
v89 = 1;
}
}
LABEL_97:
if( v61 >= v55 - *(_QWORD *)&PageRange.BasePage
|| !v57 && v55 - *(_QWORD *)&PageRange.BasePage - v61 < v56 )
{
v100 = (_MMPTE_COPY_LIST *)(v55 - v61 - 1);
}
*(_QWORD *)&PageRange.LowestPageOkToUse = v55 - v61;
MiCollapseRunTopDown(&PageRange);
v12 = Partition;
v54 = v113;
v35 = ReplacementColor;
if( !v70 )
goto LABEL_102;
}
}
v40 = v88;
v34 = (int *)v87;
}
v47 = v95;
if( !v95 )
break;
v36 = v93;
}
v46 = (unsigned __int64)v96;
}
v69 = ReplacementColor_4;
LABEL_108:
if( !v40 )
goto LABEL_113;
v12 = Partition;
++v40;
v41 = v85;
v34 = (int *)v87;
v36 = v93;
v88 = v40;
if( (unsigned __int64)v40 >= v46 )
break;
v35 = ReplacementColor;
}
if( v38 != -1 )
{
v71 = v97 + 1;
v97 = v71;
if( v71 != v109 )
{
v38 = *v71;
NodeInformation = v98;
v35 = ReplacementColor;
continue;
}
}
break;
}
LABEL_113:
if( v69 && v89 == 1 )
{
v12 = Partition;
if( *(&stru_140C4DB30 + 4332) )
MiQueueWorkingSetRequest(Partition, 0x20ui64);
v35 = ReplacementColor;
v34 = (int *)v87;
v36 = v93;
NodeInformation = v98;
ReplacementColor_4 = 0;
continue;
}
break;
}
v25 = -1073741801;
MiDereferencePageRunsEx(v87, 1i64);
v12 = Partition;
LABEL_128:
v18 = ReplacementColor;
v20 = SizeInPages;
LABEL_129:
MiReleasePteCopyList(PteCopyList);
if( (v18 & 0x20000000) == 0 )
{
MiReturnCommit(v12, v20);
if( v12 == &Irp )
{
CurrentPrcb = KeGetCurrentPrcb();
CachedResidentAvailable = (int)CurrentPrcb->CachedResidentAvailable;
if( (_DWORD)CachedResidentAvailable != -1 )
{
if( v20 + CachedResidentAvailable <= 0x100 )
{
do
{
if( v20 >= 0x80000 )
break;
v78 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
v20 + CachedResidentAvailable,
CachedResidentAvailable);
v19 = (_DWORD)CachedResidentAvailable == v78;
LODWORD(CachedResidentAvailable) = v78;
if( v19 )
return v25;
}
while( v78 != -1 && v20 + v78 <= 0x100 );
}
if( (int)CachedResidentAvailable > 192
&& (_DWORD)CachedResidentAvailable != -1
&& (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
192,
CachedResidentAvailable) )
{
v20 += (int)CachedResidentAvailable - 192;
}
}
}
if( v20 )
_InterlockedExchangeAdd64((volatile signed __int64 *)&v12->Vp.ResidentAvailablePages, v20);
}
return v25;
}Referenced by:
MiAllocateContiguousMemory
MiAllocateDriverPage
MiAllocateMostlyContiguousPagesForMdl
MiAllocateSkipPagesForMdl
MiAllocateSlabEntry
MiFindLargePageMemory
MiIdealClusterPage
MiMapSystemImageWithLargePage
MiRebuildLargePage
MiWaitForInPageComplete
MmMarkPhysicalMemoryAsBad
MmRemovePhysicalMemory