MiGetPageChain
_MMPFN *__fastcall MiGetPageChain(
_MI_PARTITION *Partition,
_MMSUPPORT_INSTANCE *Vm,
UINT64 PreferredNode,
UINT64 ProtectionCode,
UINT64 InputGetPageFlags,
UINT64 Alignment,
UINT64 *NumberOfPages){
_MI_PFN_CACHE_ATTRIBUTE v7;
_MI_PARTITION *v9;
__int64 CurrentIrql;
struct _KPRCB *CurrentPrcb;
int v12;
int v13;
_MMSUPPORT_INSTANCE *v14;
UINT64 v15;
UINT64 v16;
unsigned int v17;
UINT64 v18;
KQUEUE *v19;
unsigned __int64 v20;
int v21;
unsigned __int8 v22;
unsigned __int64 v23;
unsigned __int32 v24;
KQUEUE *LargePage;
unsigned __int8 v26;
_MMPFN *PfnDb;
__int64 v28;
signed __int32 v29;
unsigned int v30;
__int64 v31;
UINT64 v32;
UINT64 Page;
__int64 v34;
int v35;
int v36;
__int64 v37;
int v38;
char *v39;
unsigned int v40;
INT64 v41;
int ProtectionPfnCompatible;
struct _KPRCB *v43;
UINT64 *v44;
__int64 v45;
int v46;
int v47;
UINT64 ValidPte;
unsigned __int8 v49;
struct _KPRCB *v50;
__int64 v51;
unsigned __int64 UltraMapping;
UINT64 *v53;
unsigned __int64 Phase0Mapping;
signed __int64 v55;
UINT64 v56;
signed __int64 v57;
signed __int64 v58;
int v59;
signed __int64 v60;
signed __int64 v61;
signed __int64 v62;
signed __int64 Flink;
__int64 v64;
signed __int64 v65;
signed __int64 v66;
LONG *v67;
struct _KPRCB *v68;
int v69;
int v70;
char v71;
unsigned int v72;
__int64 v73;
_MI_PFN_CACHE_ATTRIBUTE v74;
signed __int32 v76[8];
ULONG_PTR BugCheckParameter4;
UINT8 v78;
_MI_PFN_CACHE_ATTRIBUTE v79;
unsigned int v80;
int v81;
UINT64 v82;
unsigned __int64 v83;
int v84;
_MI_PARTITION *Partitiona;
__int64 v86;
unsigned __int64 v87;
int v88;
unsigned int v89;
_MMSUPPORT_INSTANCE *v90;
UINT64 v91;
UINT64 v92;
_LIST_ENTRY *v93;
char *v94;
__int64 v95;
INT64 v96;
__int64 v97;
INT64 v98;
UINT64 *v99;
INT64 a6[2];
__int128 v101;
__int128 v102;
__int128 v103;
__int128 v104;
__int128 v105;
__int128 v106;
__int128 v107;
__int128 v108;
__int64 v109[16];
v99 = NumberOfPages;
v7 = (int)ProtectionCode;
*(_OWORD *)a6 = 0i64;
v79 = (int)ProtectionCode;
v101 = 0i64;
v96 = (INT64)Vm;
v9 = Partition;
v102 = 0i64;
Partitiona = Partition;
v103 = 0i64;
v104 = 0i64;
v105 = 0i64;
v106 = 0i64;
v107 = 0i64;
v108 = 0i64;
CurrentIrql = KeGetCurrentIrql();
v86 = CurrentIrql;
if( (_DWORD)PreferredNode )
{
CurrentPrcb = KeGetCurrentPrcb();
v12 = ((_DWORD)PreferredNode - 1) << byte_140C4DBCC;
}
else
{
CurrentPrcb = *(&KiProcessorBlock + *((unsigned int *)KeGetCurrentThread() + 147));
v12 = *((_DWORD *)CurrentPrcb + 8134);
}
v13 = (1 << byte_140C4DBCD) - 1;
v84 = v12;
v81 = v13;
if( !Vm || (v14 = Vm, (*(_BYTE *)&Vm->Flags.0 & 7u) >= 2) )
v14 = (_MMSUPPORT_INSTANCE *)((char *)CurrentPrcb + 32528);
v15 = *NumberOfPages;
v16 = Alignment;
v17 = InputGetPageFlags & 0xFFFFF0FF;
v90 = v14;
v18 = 0xFFFFFFFFFi64;
v80 = InputGetPageFlags & 0xFFFFF0FF;
v19 = 0i64;
v87 = v15;
v20 = 0i64;
v92 = 0xFFFFFFFFFi64;
v93 = 0i64;
LODWORD(v82) = 0;
v83 = 0i64;
if( Alignment != -1i64 )
{
v17 = InputGetPageFlags & 0xFFFFB0FF | 0x4000;
goto LABEL_33;
}
if( v15 < 0x10 )
{
LABEL_33:
if( v20 >= v15 )
goto LABEL_129;
v97 = v7;
while( 1 )
{
v29 = v13 & _InterlockedExchangeAdd((volatile signed __int32 *)v90, 1u);
v30 = v29 | v84;
if( v16 == -1i64 )
goto LABEL_137;
v31 = 15i64;
if( (unsigned int)dword_140C4DC38 < 0xFui64 )
v31 = (unsigned int)dword_140C4DC38;
v32 = v31 & v16;
v30 = v32 | v30 & 0xFFFFFFF0;
Page = MiGetPage(v9, v30, v17);
v91 = Page;
v34 = Page;
if( Page == -1i64 )
v17 &= ~0x4000u;
v16 = v31 & (v32 + 1);
v7 = v79;
Alignment = v16;
if( Page == -1i64 )
{
LABEL_137:
v91 = MiGetPage(Partitiona, v30, v17);
v34 = v91;
if( v91 == -1i64 )
goto LABEL_129;
}
v35 = v17 | 0x4000;
if( v16 == -1i64 )
v35 = v17;
v80 = v35;
v19 = (KQUEUE *)((char *)MmGetPfnDb() + 48 * v34);
v36 = 1;
v37 = BYTE2(v19->EntryListHead.Blink) >> 6;
v88 = v37;
if( (_DWORD)v37 == v7 || ((unsigned __int8)((1 << v37) | (1 << v7)) & (unsigned __int8)byte_140C4DD18) == 0 )
break;
v38 = v82;
v109[(unsigned int)v82] = v34;
LODWORD(v82) = v38 + 1;
if( v38 == 15 )
{
MiPerformFinalZeroing((UINT64 *)v109, 0x10ui64, (unsigned int)v7);
LODWORD(v82) = 0;
}
LABEL_94:
Flink = (signed __int64)v19->EntryListHead.Flink;
v64 = v92 & 0xFFFFFFFFFi64;
v65 = _InterlockedCompareExchange64(
(volatile signed __int64 *)&v19->EntryListHead,
v92 & 0xFFFFFFFFFi64 | Flink & 0xFFFFFFF000000000ui64,
Flink);
if( Flink != v65 )
{
do
{
v66 = v65;
v65 = _InterlockedCompareExchange64(
(volatile signed __int64 *)&v19->EntryListHead,
v64 | v65 & 0xFFFFFFF000000000ui64,
v65);
}
while( v66 != v65 );
}
++v20;
v92 = v34;
v83 = v20;
if( (unsigned __int8)v86 >= 2u )
{
v67 = &dword_140C4F4C0;
if( (*(_BYTE *)(v96 + 184) & 7) != 2 )
v67 = (LONG *)(v96 + 192);
if( (*v67 & 0x40000000) != 0 )
goto LABEL_129;
v68 = KeGetCurrentPrcb();
v69 = *((_DWORD *)v68 + 3147);
if( (v69 & 1) != 0 )
{
v70 = 1;
if( *((_DWORD *)v68 + 8103) > 7u )
{
if( *((_BYTE *)v68 + 12585) )
goto LABEL_124;
LABEL_119:
if( (v69 & 0x1E) != 0 )
{
v36 = 5;
goto LABEL_124;
}
if( *((_QWORD *)v68 + 1) != *((_QWORD *)v68 + 3) )
{
v36 = 6;
goto LABEL_124;
}
LABEL_123:
_disable();
*((_DWORD *)v68 + 7931) = 0;
*((_DWORD *)v68 + 8103) = 0;
KiResetGlobalDpcWatchdogProfiler((INT64)v68);
_enable();
v36 = 0;
goto LABEL_124;
}
LABEL_117:
if( *((_DWORD *)v68 + 7931) > 7u )
{
if( v70 )
goto LABEL_119;
goto LABEL_123;
}
}
else
{
v70 = 0;
if( (v69 & 0x1E) != 0 )
{
v36 = 2;
}
else if( *((_BYTE *)v68 + 12585) )
{
v36 = 3;
}
else
{
v73 = *((_QWORD *)v68 + 2);
if( !v73 || v73 == *((_QWORD *)v68 + 1) )
goto LABEL_117;
v36 = 4;
}
LABEL_124:
if( v36 )
goto LABEL_129;
}
v7 = v79;
}
if( v20 >= v87 )
goto LABEL_129;
v16 = Alignment;
v17 = v80;
v9 = Partitiona;
v13 = v81;
}
if( ((__int64)v19->Header.WaitListHead.Blink & 0x3E0i64) != 0 && (InputGetPageFlags & 0x100) != 0 )
{
v39 = (char *)&v19->EntryListHead.Blink + 2;
v94 = (char *)&v19->EntryListHead.Blink + 2;
v40 = dword_140C4DCD8[4 * v37 + v97];
v89 = v40;
if( v40 != (_DWORD)v37 )
MiChangePageAttribute((INT64)v19, v40, 0);
v41 = 0i64;
if( *((_QWORD *)KeGetCurrentPrcb() + 4160) || (v41 = MiReservePtes((INT64)&qword_140C4EC80, 1ui64)) == 0 )
{
v78 = 17;
v43 = KeGetCurrentPrcb();
if( *((_QWORD *)v43 + 4160) )
v41 = 1i64;
v44 = 0i64;
v98 = v41;
v45 = *((_QWORD *)v43 + 4160);
v95 = v45;
do
{
if( v45 )
{
v46 = 4;
v47 = (unsigned __int8)*v39 >> 6;
if( !v47 || v47 == 3 )
{
v46 = 12;
}
else if( v47 == 2 )
{
v46 = 28;
}
ValidPte = MiMakeValidPte(0i64, v34, v46 | 0xA0000000);
v49 = KeGetCurrentIrql();
__writecr8(2ui64);
v50 = KeGetCurrentPrcb();
v78 = v49;
v51 = *((_QWORD *)v50 + 4095);
if( !v51
|| (UltraMapping = MiGetUltraMapping((unsigned __int64 *)(v51 + 12448), 3u, 1i64, 0),
v53 = (UINT64 *)((char *)MmGetPteBase() + ((UltraMapping >> 9) & 0x7FFFFFFFF8i64)),
*(_QWORD *)(v51 + 12344) = v53,
!UltraMapping) )
{
UltraMapping = (*((_QWORD *)v50 + 4160) & 0xFFFFFFFFFFFFF000ui64)
+ ((*((_QWORD *)v50 + 4160) & 0xFFFi64) << 12);
v53 = (UINT64 *)((char *)MmGetPteBase() + ((UltraMapping >> 9) & 0x7FFFFFFFF8i64));
}
if( v53 >= (UINT64 *)MmGetPml4eBase()
&& v53 <= (UINT64 *)MmGetPxeUserLimit()
&& (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) != 0
&& (ValidPte & 1) != 0 )
{
ValidPte |= 0x8000000000000000ui64;
}
v39 = v94;
*v53 = ValidPte;
}
else
{
Phase0Mapping = (unsigned __int64)MxGetPhase0Mapping();
UltraMapping = Phase0Mapping;
if( !Phase0Mapping )
KeBugCheckEx(0x1Au, 0x3030305ui64, v34, 0i64, 0i64);
v44 = (UINT64 *)((char *)MmGetPteBase() + ((Phase0Mapping >> 9) & 0x7FFFFFFFF8i64));
*v44 = MiMakeValidPte((UINT64)v44, v34, 2684354564i64);
}
KeZeroPages((PVOID)UltraMapping, 0x1000ui64);
if( v95 )
{
MiUnmapPageInHyperSpaceWorker((PVOID)UltraMapping, v78, 0x80000000ui64);
}
else
{
*v44 = ZeroPte;
KeFlushSingleTb(UltraMapping, 0i64, 1i64);
}
++v34;
v39 += 48;
v94 = v39;
v45 = v95;
}
while( v34 == v91 );
v41 = v98;
LODWORD(v37) = v88;
v40 = v89;
v34 = v91;
}
else
{
ProtectionPfnCompatible = MiMakeProtectionPfnCompatible(4ui64, (_MMPFN *)v19);
*(_QWORD *)v41 = MiMakeValidPte(v41, v34, ProtectionPfnCompatible | 0xA0000000);
KeZeroPages((PVOID)(((v41 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16), 0x1000ui64);
MiReleasePtes((INT64)&qword_140C4EC80, v41, 1ui64);
}
v7 = v79;
if( v40 != (_DWORD)v37 && v40 != v79 && v41 )
MiChangePageAttribute((INT64)v19, (unsigned int)v37, 0);
v19->Header.WaitListHead.Blink = (_LIST_ENTRY *)((unsigned __int64)v19->Header.WaitListHead.Blink & 0xFFFFFFFFFFFFFC1Fui64);
_InterlockedOr(v76, 0);
v55 = (signed __int64)v19->EntryListHead.Flink;
v56 = (KiTbFlushTimeStamp & 0xF) << 56;
v57 = _InterlockedCompareExchange64(
(volatile signed __int64 *)&v19->EntryListHead,
v56 | v55 & 0xF0FFFFFFFFFFFFFFui64,
v55);
if( v55 != v57 )
{
do
{
v58 = v57;
v57 = _InterlockedCompareExchange64(
(volatile signed __int64 *)&v19->EntryListHead,
v56 | v57 & 0xF0FFFFFFFFFFFFFFui64,
v57);
}
while( v58 != v57 );
}
v20 = v83;
}
v59 = BYTE2(v19->EntryListHead.Blink) >> 6;
if( v59 != v7 )
{
if( v59 == 1
|| v59 != 3
&& (v71 = HIBYTE(v19->EntryListHead.Flink) & 0xF,
_InterlockedOr(v76, 0),
v72 = ((_BYTE)KiTbFlushTimeStamp - v71) & 0xF,
v72 <= 2)
&& ((v71 & 1) != 0 || v72 < 2) )
{
if( ((__int64)v19->Header.WaitListHead.Blink & 0x3E0i64) != 0 )
MiZeroPhysicalPage(v34, 1ui64, v7);
v19->Header.WaitListHead.Blink = v93;
v93 = (_LIST_ENTRY *)v19;
LABEL_93:
v36 = 1;
goto LABEL_94;
}
MiChangePageAttribute((INT64)v19, (unsigned int)v7, 4);
}
v60 = (signed __int64)v19->EntryListHead.Flink;
v61 = _InterlockedCompareExchange64(
(volatile signed __int64 *)&v19->EntryListHead,
v60 & 0xF0FFFFFFFFFFFFFFui64,
v60);
if( v60 != v61 )
{
do
{
v62 = v61;
v61 = _InterlockedCompareExchange64(
(volatile signed __int64 *)&v19->EntryListHead,
v61 & 0xF0FFFFFFFFFFFFFFui64,
v61);
}
while( v62 != v61 );
}
goto LABEL_93;
}
LODWORD(a6[1]) = 16;
a6[0] = 1i64;
v21 = 1;
v22 = 17;
v23 = v15;
while( 1 )
{
v24 = v13 & _InterlockedExchangeAdd((volatile signed __int32 *)v14, 1u) | v12;
if( (unsigned __int8)CurrentIrql < 2u )
{
v22 = KeGetCurrentIrql();
__writecr8(2ui64);
}
if( v23 < 0x200 || v21 != 1 )
goto LABEL_18;
LODWORD(BugCheckParameter4) = 4;
LargePage = (KQUEUE *)MiGetLargePage((INT64)v9, 1ui64, (unsigned int)v7, v24, BugCheckParameter4, (INT64)a6);
if( !LargePage )
{
v9 = Partitiona;
LABEL_18:
v21 = 2;
LODWORD(BugCheckParameter4) = 4;
LargePage = (KQUEUE *)MiGetLargePage((INT64)v9, 2ui64, (unsigned int)v7, v24, BugCheckParameter4, (INT64)a6);
if( !LargePage )
goto LABEL_20;
}
MiConvertEntireLargePageToSmall(LargePage, v21, 2u, (LARGE_INTEGER *)1, 0i64, 0i64);
LABEL_20:
v26 = v86;
if( (unsigned __int8)v86 < 2u )
__writecr8(v22);
if( !LargePage )
goto LABEL_25;
PfnDb = MmGetPfnDb();
v28 = ((char *)LargePage - (char *)PfnDb) / 48;
MiSetPfnBlink((_MMPFN *)((char *)PfnDb + 48 * v28 + 48 * MiLargePageSizes[v21] - 48), v18, 0i64);
v18 = v28;
v19 = LargePage;
v7 = v79;
v23 = v87 - (MiLargePageSizes[v21] + v83);
v14 = v90;
v9 = Partitiona;
v13 = v81;
v12 = v84;
v83 += MiLargePageSizes[v21];
if( v23 < 0x10 )
break;
LOBYTE(CurrentIrql) = v86;
}
v26 = v86;
LABEL_25:
v92 = v18;
if( HIDWORD(a6[0]) )
MiNotifyPageHeat(a6);
if( v26 < 2u )
{
v20 = v83;
goto LABEL_32;
}
if( MiWorkingSetIsContended(v96) )
{
v20 = v83;
}
else
{
v20 = v83;
if( !KeShouldYieldProcessor() )
{
LABEL_32:
v15 = v87;
v13 = v81;
v9 = Partitiona;
v17 = v80;
v16 = -1i64;
goto LABEL_33;
}
}
LABEL_129:
v74 = v79;
*v99 = v20;
if( (_DWORD)v82 )
MiPerformFinalZeroing((UINT64 *)v109, (unsigned int)v82, (unsigned int)v74);
if( v93 )
MiChangePageAttributeBatch((INT64)v93, (_BYTE *)(unsigned int)v74, ZeroPte);
return(_MMPFN *)v19;
}Referenced by:
MiCreateSharedZeroPages
MiGetClusterPage
MiGetHardFaultPages
MiPfPrepareSequentialReadList
MiResolvePageFileFault
MiResolvePrivateZeroFault