MiGetPageChain
_MMPFN *__stdcall MiGetPageChain(
PVOID *Partition,
_MMSUPPORT_INSTANCE *Vm,
UINT64 PreferredNode,
UINT64 ProtectionCode,
UINT64 InputGetPageFlags,
UINT64 Alignment,
UINT64 *NumberOfPages){
_MI_PFN_CACHE_ATTRIBUTE v7;
ULONG_PTR *v9;
__int64 CurrentIrql;
struct _KPRCB *CurrentPrcb;
int NodeShiftedColor;
int v13;
_MMSUPPORT_INSTANCE *p_PageColor;
UINT64 v15;
UINT64 v16;
unsigned int v17;
UINT64 v18;
_MMPFN *v19;
unsigned __int64 v20;
int v21;
unsigned __int8 v22;
unsigned __int64 v23;
signed __int32 v24;
_KQUEUE *LargePage;
unsigned __int8 v26;
_MMPFN *PfnDb;
__int64 v28;
int v29;
signed __int32 v30;
unsigned int v31;
__int64 v32;
UINT64 v33;
__int64 v34;
__int64 v35;
__int64 v36;
int v37;
int v38;
__int64 v39;
int v40;
struct {unsigned __int16 ReferenceCount;} *v41;
_MI_PFN_CACHE_ATTRIBUTE v42;
UINT64 v43;
int v44;
__int64 v45;
__int64 v46;
int v47;
_KTBFLUSH_TYPE v48;
struct _KPRCB *v49;
_XSTATE_CONFIGURATION *v50;
__int64 HyperPte;
int v52;
int v53;
__int64 v54;
__int64 v55;
unsigned __int8 v56;
struct _KPRCB *v57;
_MI_ZERO_THREAD_CONTEXT *MmInternal;
UINT64 v59;
UINT64 v60;
char *v61;
UINT64 Phase0Mapping;
unsigned __int64 v63;
unsigned __int64 v64;
int v65;
unsigned __int64 Long;
int v67;
signed __int64 v68;
UINT64 v69;
signed __int64 v70;
signed __int64 v71;
int v72;
signed __int64 v73;
signed __int64 v74;
signed __int64 v75;
signed __int64 bf_0;
__int64 v77;
signed __int64 v78;
signed __int64 v79;
_DWORD *v80;
struct _KPRCB *v81;
volatile int DpcRequestSummary;
int v83;
char v84;
unsigned int v85;
_ETHREAD *NextThread;
_MI_PFN_CACHE_ATTRIBUTE v87;
signed __int32 v89[8];
UINT8 v90;
_MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
unsigned int v92;
int v93;
UINT64 PostZeroCount;
unsigned __int64 v95;
int v96;
ULONG_PTR *Partitiona;
__int64 v98;
unsigned __int64 v99;
int v100;
_MI_PFN_CACHE_ATTRIBUTE v101;
_MMSUPPORT_INSTANCE *v102;
__int64 v103;
UINT64 v104;
_MMPFN *PfnChain;
struct {unsigned __int16 ReferenceCount;} *v106;
__int64 v107;
INT64 v108;
__int64 v109;
UINT64 v110;
UINT64 *v111;
INT64 a6[2];
__int128 v113;
__int128 v114;
__int128 v115;
__int128 v116;
__int128 v117;
__int128 v118;
__int128 v119;
__int128 v120;
__int64 PostZeroPages[16];
v111 = NumberOfPages;
v7 = (int)ProtectionCode;
*(_OWORD *)a6 = 0i64;
CacheAttribute = (int)ProtectionCode;
v113 = 0i64;
v108 = (INT64)Vm;
v9 = (ULONG_PTR *)Partition;
v114 = 0i64;
Partitiona = (ULONG_PTR *)Partition;
v115 = 0i64;
v116 = 0i64;
v117 = 0i64;
v118 = 0i64;
v119 = 0i64;
v120 = 0i64;
CurrentIrql = KeGetCurrentIrql();
v98 = CurrentIrql;
if( (_DWORD)PreferredNode )
{
CurrentPrcb = KeGetCurrentPrcb();
NodeShiftedColor = ((_DWORD)PreferredNode - 1) << *(&stru_140C4DB30 + 156);
}
else
{
CurrentPrcb = *(&KiProcessorBlock + KeGetCurrentThread()->IdealProcessor);
NodeShiftedColor = CurrentPrcb->NodeShiftedColor;
}
v13 = (1 << *(&stru_140C4DB30 + 157)) - 1;
v96 = NodeShiftedColor;
v93 = v13;
if( !Vm || (p_PageColor = Vm, (Vm->Flags._bf_0 & 7u) >= 2) )
p_PageColor = (_MMSUPPORT_INSTANCE *)&CurrentPrcb->PageColor;
v15 = *NumberOfPages;
v16 = Alignment;
v17 = InputGetPageFlags & 0xFFFFF0FF;
v102 = p_PageColor;
v18 = 0xFFFFFFFFFi64;
v92 = InputGetPageFlags & 0xFFFFF0FF;
v19 = 0i64;
v99 = v15;
v20 = 0i64;
v104 = 0xFFFFFFFFFi64;
PfnChain = 0i64;
LODWORD(PostZeroCount) = 0;
v95 = 0i64;
if( Alignment != -1i64 )
{
v17 = InputGetPageFlags & 0xFFFFB0FF | 0x4000;
goto LABEL_33;
}
if( v15 < 0x10 )
{
LABEL_33:
if( v20 >= v15 )
goto LABEL_141;
v109 = v7;
while( 1 )
{
v30 = v13 & _InterlockedExchangeAdd((volatile signed __int32 *)v102, 1u);
v31 = v30 | v96;
if( v16 == -1i64 )
goto LABEL_149;
v32 = 15i64;
if( *(&stru_140C4DB30 + 66) < 0xFui64 )
v32 = *(&stru_140C4DB30 + 66);
v33 = v32 & v16;
v31 = v33 | v31 & 0xFFFFFFF0;
LODWORD(v34) = MiGetPage(v9, v31, v17);
v103 = v34;
v35 = v34;
if( v34 == -1 )
v17 &= ~0x4000u;
v16 = v32 & (v33 + 1);
v7 = CacheAttribute;
Alignment = v16;
if( v34 == -1 )
{
LABEL_149:
LODWORD(v36) = MiGetPage(Partitiona, v31, v17);
v103 = v36;
v35 = v36;
if( v36 == -1 )
goto LABEL_141;
}
v37 = v17 | 0x4000;
if( v16 == -1i64 )
v37 = v17;
v92 = v37;
v19 = &MmGetPfnDb()[v35];
v38 = 1;
v39 = *((unsigned __int8 *)&v19->u3 + 2) >> 6;
v100 = v39;
if( (_DWORD)v39 == v7 || ((unsigned __int8)((1 << v39) | (1 << v7)) & *(&stru_140C4DB30 + 488)) == 0 )
break;
v40 = PostZeroCount;
PostZeroPages[(unsigned int)PostZeroCount] = v35;
LODWORD(PostZeroCount) = v40 + 1;
if( v40 == 15 )
{
MiPerformFinalZeroing(PostZeroPages, 0x10ui64, v7);
LODWORD(PostZeroCount) = 0;
}
LABEL_106:
bf_0 = v19->u2._bf_0;
v77 = v104 & 0xFFFFFFFFFi64;
v78 = _InterlockedCompareExchange64(&v19->u2.Lock, v104 & 0xFFFFFFFFFi64 | bf_0 & 0xFFFFFFF000000000ui64, bf_0);
if( bf_0 != v78 )
{
do
{
v79 = v78;
v78 = _InterlockedCompareExchange64(&v19->u2.Lock, v77 | v78 & 0xFFFFFFF000000000ui64, v78);
}
while( v79 != v78 );
}
++v20;
v104 = v35;
v95 = v20;
if( (unsigned __int8)v98 >= 2u )
{
v80 = (_DWORD *)((char *)&stru_140C4DB30 + 6544);
if( (*(_BYTE *)(v108 + 184) & 7) != 2 )
v80 = (_DWORD *)(v108 + 192);
if( (*v80 & 0x40000000) != 0 )
goto LABEL_141;
v81 = KeGetCurrentPrcb();
DpcRequestSummary = v81->DpcRequestSummary;
if( (DpcRequestSummary & 1) != 0 )
{
v83 = 1;
if( v81->DpcTimeCount > 7 )
{
if( v81->QuantumEnd )
goto LABEL_136;
LABEL_131:
if( (DpcRequestSummary & 0x1E) != 0 )
{
v38 = 5;
goto LABEL_136;
}
if( v81->CurrentThread != v81->IdleThread )
{
v38 = 6;
goto LABEL_136;
}
LABEL_135:
_disable();
v81->DpcWatchdogCount = 0;
v81->DpcTimeCount = 0;
KiResetGlobalDpcWatchdogProfiler((INT64)v81);
_enable();
v38 = 0;
goto LABEL_136;
}
LABEL_129:
if( v81->DpcWatchdogCount > 7u )
{
if( v83 )
goto LABEL_131;
goto LABEL_135;
}
}
else
{
v83 = 0;
if( (DpcRequestSummary & 0x1E) != 0 )
{
v38 = 2;
}
else if( v81->QuantumEnd )
{
v38 = 3;
}
else
{
NextThread = v81->NextThread;
if( !NextThread || NextThread == v81->CurrentThread )
goto LABEL_129;
v38 = 4;
}
LABEL_136:
if( v38 )
goto LABEL_141;
}
v7 = CacheAttribute;
}
if( v20 >= v99 )
goto LABEL_141;
v16 = Alignment;
v17 = v92;
v9 = Partitiona;
v13 = v93;
}
if( (*(_DWORD *)(&v19->3 + 1) & 0x3E0i64) != 0 && (InputGetPageFlags & 0x100) != 0 )
{
v41 = &v19->u3 + 1;
v106 = &v19->u3 + 1;
v42 = *((_DWORD *)&stru_140C4DB30 + 4 * v39 + v109 + 106);
v101 = v42;
if( v42 != (_DWORD)v39 )
MiChangePageAttribute(v19, v42, 0i64);
v43 = 0i64;
if( KeGetCurrentPrcb()->HyperPte
|| (v43 = (UINT64)MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), 1ui64)) == 0 )
{
v90 = 17;
v49 = KeGetCurrentPrcb();
if( v49->HyperPte )
v43 = 1i64;
v50 = 0i64;
v110 = v43;
HyperPte = (__int64)v49->HyperPte;
v107 = HyperPte;
do
{
if( HyperPte )
{
v52 = 4;
v53 = LOBYTE(v41->ReferenceCount) >> 6;
if( !v53 || v53 == 3 )
{
v52 = 12;
}
else if( v53 == 2 )
{
v52 = 28;
}
LODWORD(v54) = MiMakeValidPte(0i64, v35, v52 | 0xA0000000);
v55 = v54;
v56 = KeGetCurrentIrql();
__writecr8(2ui64);
v57 = KeGetCurrentPrcb();
v90 = v56;
MmInternal = (_MI_ZERO_THREAD_CONTEXT *)v57->MmInternal;
if( !MmInternal
|| (MiGetUltraMapping(MmInternal + 3112, 3i64),
v60 = v59,
v61 = (char *)MmGetPteBase() + ((v59 >> 9) & 0x7FFFFFFFF8i64),
*((_QWORD *)MmInternal + 1543) = v61,
!v59) )
{
v60 = ((unsigned __int64)v57->HyperPte & 0xFFFFFFFFFFFFF000ui64)
+ (((__int64)v57->HyperPte & 0xFFF) << 12);
v61 = (char *)MmGetPteBase() + ((v60 >> 9) & 0x7FFFFFFFF8i64);
}
if( v61 >= (char *)MmGetPml4eBase()
&& v61 <= (char *)MmGetPxeUserLimit()
&& (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0
&& (v55 & 1) != 0 )
{
v55 |= 0x8000000000000000ui64;
}
v41 = v106;
*(_QWORD *)v61 = v55;
}
else
{
Phase0Mapping = (UINT64)MxGetPhase0Mapping();
v60 = Phase0Mapping;
if( !Phase0Mapping )
KeBugCheckEx(0x1Au, (PVOID)0x3030305, (PVOID)v35, 0i64, 0i64);
v50 = (_XSTATE_CONFIGURATION *)((char *)MmGetPteBase() + ((Phase0Mapping >> 9) & 0x7FFFFFFFF8i64));
LODWORD(v63) = MiMakeValidPte(v50, v35, 2684354564i64);
v64 = v63;
LOBYTE(v65) = MiPteInShadowRange((UINT64)v50);
if( v65 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v64 & 1) != 0 )
v64 |= 0x8000000000000000ui64;
v50->EnabledFeatures = v64;
}
KeZeroPages((VOID *)v60, 0x1000ui64);
if( v107 )
{
MiUnmapPageInHyperSpaceWorker((VOID *)v60, v90, 0x80000000ui64);
}
else
{
Long = ZeroPte.u.Long;
LOBYTE(v67) = MiPteInShadowRange((UINT64)v50);
if( v67 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
Long = ZeroPte.u.Long | 0x8000000000000000ui64;
v50->EnabledFeatures = Long;
KeFlushSingleTb(v60, FlushKernel, 1i64);
}
++v35;
v41 += 24;
v106 = v41;
HyperPte = v107;
}
while( v35 == v103 );
v43 = v110;
LODWORD(v39) = v100;
v42 = v101;
v35 = v103;
}
else
{
MiMakeProtectionPfnCompatible((_BYTE *)4, v19);
LODWORD(v45) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v43, v35, v44 | 0xA0000000);
v46 = v45;
LOBYTE(v47) = MiPteInShadowRange(v43);
if( v47 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v46 & 1) != 0 )
v46 |= 0x8000000000000000ui64;
*(_QWORD *)v43 = v46;
KeZeroPages((VOID *)((__int64)((v43 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16), 0x1000ui64);
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), (_MMPTE *)v43, 1ui64, v48);
}
v7 = CacheAttribute;
if( v42 != (_DWORD)v39 && v42 != CacheAttribute && v43 )
MiChangePageAttribute(v19, (_MI_PFN_CACHE_ATTRIBUTE)v39, 0i64);
v19->OriginalPte.u.Long &= 0xFFFFFFFFFFFFFC1Fui64;
_InterlockedOr(v89, 0);
v68 = v19->u2._bf_0;
v69 = (KiTbFlushTimeStamp & 0xF) << 56;
v70 = _InterlockedCompareExchange64(&v19->u2.Lock, v69 | v68 & 0xF0FFFFFFFFFFFFFFui64, v68);
if( v68 != v70 )
{
do
{
v71 = v70;
v70 = _InterlockedCompareExchange64(&v19->u2.Lock, v69 | v70 & 0xF0FFFFFFFFFFFFFFui64, v70);
}
while( v71 != v70 );
}
v20 = v95;
}
v72 = *((unsigned __int8 *)&v19->u3 + 2) >> 6;
if( v72 != v7 )
{
if( v72 == 1
|| v72 != 3
&& (v84 = HIBYTE(v19->u2._bf_0) & 0xF,
_InterlockedOr(v89, 0),
v85 = ((_BYTE)KiTbFlushTimeStamp - v84) & 0xF,
v85 <= 2)
&& ((v84 & 1) != 0 || v85 < 2) )
{
if( (*(_DWORD *)(&v19->3 + 1) & 0x3E0i64) != 0 )
MiZeroPhysicalPage(v35, 1ui64, v7);
v19->OriginalPte.u.Long = (unsigned __int64)PfnChain;
PfnChain = v19;
LABEL_105:
v38 = 1;
goto LABEL_106;
}
MiChangePageAttribute(v19, v7, 4ui64);
}
v73 = v19->u2._bf_0;
v74 = _InterlockedCompareExchange64(&v19->u2.Lock, v73 & 0xF0FFFFFFFFFFFFFFui64, v73);
if( v73 != v74 )
{
do
{
v75 = v74;
v74 = _InterlockedCompareExchange64(&v19->u2.Lock, v74 & 0xF0FFFFFFFFFFFFFFui64, v74);
}
while( v75 != v74 );
}
goto LABEL_105;
}
LODWORD(a6[1]) = 16;
a6[0] = 1i64;
v21 = 1;
v22 = 17;
v23 = v15;
while( 1 )
{
v24 = v13 & _InterlockedExchangeAdd((volatile signed __int32 *)p_PageColor, 1u) | NodeShiftedColor;
if( (unsigned __int8)CurrentIrql < 2u )
{
v22 = KeGetCurrentIrql();
__writecr8(2ui64);
}
if( v23 < 0x200 || v21 != 1 )
goto LABEL_18;
LargePage = (_KQUEUE *)MiGetLargePage((INT64)v9, 1u, v7, v24, 4, (__int64)a6);
if( !LargePage )
{
v9 = Partitiona;
LABEL_18:
v21 = 2;
LargePage = (_KQUEUE *)MiGetLargePage((INT64)v9, 2u, v7, v24, 4, (__int64)a6);
if( !LargePage )
goto LABEL_20;
}
MiConvertEntireLargePageToSmall(LargePage, v21, 2u, (_LARGE_INTEGER *)1, 0i64, 0i64);
LABEL_20:
v26 = v98;
if( (unsigned __int8)v98 < 2u )
__writecr8(v22);
if( !LargePage )
goto LABEL_25;
PfnDb = MmGetPfnDb();
v28 = (LargePage - (_KQUEUE *)PfnDb) / 48;
MiSetPfnBlink(&PfnDb[v28 - 1 + MiLargePageSizes[v21]], v18, 0i64);
v18 = v28;
v19 = (_MMPFN *)LargePage;
v7 = CacheAttribute;
v23 = v99 - (MiLargePageSizes[v21] + v95);
p_PageColor = v102;
v9 = Partitiona;
v13 = v93;
NodeShiftedColor = v96;
v95 += MiLargePageSizes[v21];
if( v23 < 0x10 )
break;
LOBYTE(CurrentIrql) = v98;
}
v26 = v98;
LABEL_25:
v104 = v18;
if( HIDWORD(a6[0]) )
MiNotifyPageHeat(a6);
if( v26 < 2u )
{
v20 = v95;
goto LABEL_32;
}
LOBYTE(v29) = MiWorkingSetIsContended(v108);
if( v29 )
{
v20 = v95;
}
else
{
v20 = v95;
if( !(unsigned int)KeShouldYieldProcessor() )
{
LABEL_32:
v15 = v99;
v13 = v93;
v9 = Partitiona;
v17 = v92;
v16 = -1i64;
goto LABEL_33;
}
}
LABEL_141:
v87 = CacheAttribute;
*v111 = v20;
if( (_DWORD)PostZeroCount )
MiPerformFinalZeroing(PostZeroPages, (unsigned int)PostZeroCount, v87);
if( PfnChain )
MiChangePageAttributeBatch(PfnChain, v87, ZeroPte);
return v19;
}Referenced by:
MiCreateSharedZeroPages
MiGetClusterPage
MiGetHardFaultPages
MiPfPrepareSequentialReadList
MiResolvePageFileFault
MiResolvePrivateZeroFault