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