MiPfPrepareSequentialReadList
NTSTATUS __stdcall MiPfPrepareSequentialReadList(
_MM_PAGE_ACCESS_INFO_HEADER *AccessInfo,
_CONTROL_AREA *ControlArea,
_LARGE_INTEGER FileOffset,
VOID *SystemCacheAddress,
UINT64 NumberOfBytes,
UINT64 DesiredPriority,
_MI_READ_LIST **SessionId,
_MI_READ_LIST **OutMiReadList){
bool v8;
_CONTROL_AREA *v10;
unsigned __int64 v12;
UINT64 v13;
_QWORD *Pool;
_EPROCESS *v15;
_QWORD *v16;
_QWORD *v17;
_SUBSECTION *v18;
__int64 v19;
_MMPTE *v20;
_MMPTE *v21;
_MMPTE *v22;
UINT64 v23;
UINT64 v24;
CHAR v25;
UINT64 v26;
unsigned int v27;
_MMPTE *PxeUserLimit;
__int64 Long;
int v30;
INT64 v31;
int v32;
_QWORD *v33;
_MI_PARTITION *v34;
_MM_PAGE_ACCESS_INFO *v35;
_QWORD *v36;
_SUBSECTION *v37;
unsigned __int64 v38;
_QWORD *v39;
_MMPTE *PteAddress;
_MMPTE *v41;
_MI_PARTITION *v42;
UINT64 v43;
union {unsigned int LongFlags;_MMSECTION_FLAGS Flags;} v44;
UINT64 v45;
_MMPTE *SubsectionBase;
_QWORD *v47;
_QWORD *v48;
_QWORD *v49;
UINT64 v50;
UINT64 v51;
__int64 v52;
_QWORD *v53;
__int64 v54;
NTSTATUS v55;
_MI_PFN_CACHE_ATTRIBUTE v56;
UINT64 v57;
PVOID *v58;
_MMPFN *PageChain;
UINT64 v60;
$559D8309DABD45803AD694472C7FC28A *v61;
_MMPFN *PfnDb;
__int64 v63;
_MMPFN *v64;
_MMPFN *v65;
__int64 v66;
UINT64 v67;
NTSTATUS Mdls;
_MM_PAGE_ACCESS_INFO *PageEntry;
int v71;
_RTL_BALANCED_NODE *SharedProtos;
NTSTATUS v73;
__int64 v74;
__int64 v75;
_QWORD *v76;
__int64 v77;
__int64 v78;
UINT64 v79;
int v80;
int v81;
UINT64 InputGetPageFlags;
_MI_PARTITION *ControlAreaPartition;
unsigned __int64 v84;
__int64 v85;
_QWORD *v86;
UINT64 NumberOfPages;
_SUBSECTION *Subsection;
_SUBSECTION *v89;
_MM_PAGE_ACCESS_INFO *v90;
char *v91;
UINT64 PteOffset;
UINT64 ProtectionMask;
_MMPTE *v94;
_MMPTE *v95;
VOID *Va;
__int64 v97;
_MMSUPPORT_INSTANCE *Vm;
__int128 ColorBase;
int v102;
v8 = (ControlArea->u.LongFlags & 0x400) == 0;
v10 = ControlArea;
ColorBase = 0i64;
*OutMiReadList = 0i64;
if( !v8 || !ControlArea->FilePointer.Value )
return -1073741585;
LODWORD(v12) = MiGetControlAreaPtes(ControlArea);
if( NumberOfBytes )
{
v13 = NumberOfBytes >> 12;
if( NumberOfBytes >> 12 < 0x100000000i64 && (unsigned int)v13 <= v12 )
goto LABEL_6;
return -1073741583;
}
if( v12 >= 0x100000000i64 )
return -1073741583;
LODWORD(v13) = v12;
LABEL_6:
Pool = MiAllocatePool(64i64, 8i64 * (unsigned int)(v13 - 1) + 144, 0x6C526D4Dui64);
v16 = Pool;
if( !Pool )
return -1073741670;
Pool[1] = v10;
v17 = Pool + 15;
PteOffset = 0i64;
v85 = 0i64;
v17[1] = v17;
*v17 = v17;
v16[4] = v16 + 3;
v16[3] = v16 + 3;
Subsection = (_SUBSECTION *)&v10[1];
LODWORD(v17) = (LOWORD(v10[1].NumberOfPfnReferences) >> 1) & 0x1F;
v84 = 0i64;
v86 = 0i64;
Va = 0i64;
LODWORD(ProtectionMask) = (_DWORD)v17;
if( NumberOfBytes )
{
v18 = MiOffsetToProtos(v10, FileOffset.QuadPart, &PteOffset);
Subsection = v18;
}
else
{
v18 = (_SUBSECTION *)&v10[1];
}
ControlAreaPartition = MiGetControlAreaPartition(v10, v15);
LODWORD(v19) = MiGetAvailablePagesExcludeSlists((INT64)ControlAreaPartition);
v97 = v19;
v21 = v20;
v95 = v20;
v22 = v20;
v94 = v20;
if( AccessInfo )
{
PageEntry = AccessInfo->PageEntry;
NumberOfPages = __PAIR64__(HIDWORD(v20), AccessInfo->EmptySequenceNumber & 0x1FF | 0x200);
v23 = NumberOfPages;
v90 = PageEntry;
}
else
{
v90 = (_MM_PAGE_ACCESS_INFO *)v20;
v23 = (UINT64)v20;
}
*((_DWORD *)v16 + 20) = DesiredPriority;
*((_DWORD *)v16 + 21) = 5;
*((_DWORD *)v16 + 22) = 7;
v24 = (v10->u.LongFlags >> 20) & 0x3F;
v91 = (char *)(v16 + 17);
Vm = &KeGetCurrentThread()->ApcState.Process->Vm.Instance;
MiInitializePageColorBase(Vm, v24, (_MI_COLOR_BASE *)&ColorBase);
v26 = 0i64;
v102 = 0;
v27 = 0;
v89 = 0i64;
if( !(_DWORD)v13 )
{
v43 = 0i64;
v53 = 0i64;
v54 = 0i64;
v55 = 0;
goto LABEL_55;
}
while( 1 )
{
PxeUserLimit = MmGetPxeUserLimit();
if( v21 >= v22 )
{
if( v21 )
{
v18 = v18->NextSubsection;
Subsection = v18;
if( !v18 )
{
LABEL_53:
v43 = v84;
v53 = v86;
v54 = v85;
goto LABEL_54;
}
PteOffset = 0i64;
}
v44.LongFlags = (unsigned int)v10->u;
if( (v44.LongFlags & 0x20) != 0 )
{
SubsectionBase = v18->SubsectionBase;
if( (v18->u.SubsectionFlags._bf_2 & 2) != 0 && (v44.LongFlags & 0x4000000) != 0 )
{
if( !v18->GlobalPerSessionHead.Root )
{
v21 = v22 - 1;
goto LABEL_31;
}
SharedProtos = MiGetSharedProtos(ControlArea, (unsigned int)SessionId, v18);
if( !SharedProtos )
{
v21 = v22 - 1;
goto LABEL_31;
}
SubsectionBase = (_MMPTE *)SharedProtos[3].Children[0];
}
}
else
{
v102 = MiAddViewsForSection(v18, v18->PtesInSubsection, 4ui64);
if( v102 < 0 )
{
if( v84 )
MiReturnFaultCharges(ControlAreaPartition, v84, 1ui64);
MiReleaseReadListResources((_MI_READ_LIST *)v16, v45);
ExFreePoolWithTag(v16, 0);
return v102;
}
SubsectionBase = v18->SubsectionBase;
v47 = v16 + 3;
v48 = (_QWORD *)v16[4];
if( (_QWORD *)*v47 == v47 || *((_DWORD *)v48 + 4) == 5 )
{
v48 = MiAllocatePool(256i64, 0x40ui64, 0x6C536D4Dui64);
if( !v48 )
{
MiRemoveViewsFromSectionWithPfn(v18, v18->PtesInSubsection);
MiReleaseReadListResources((_MI_READ_LIST *)v16, v79);
ExFreePoolWithTag(v16, 0);
return -1073741670;
}
v49 = (_QWORD *)v16[4];
if( (_QWORD *)*v49 != v47 )
__fastfail(3u);
*v48 = v47;
v48[1] = v49;
*v49 = v48;
v16[4] = v48;
}
if( !v16[2] )
v16[2] = v18;
v48[(unsigned int)(*((_DWORD *)v48 + 4))++ + 3] = v18;
}
v21 = &SubsectionBase[PteOffset];
v22 = &SubsectionBase[v18->PtesInSubsection];
LODWORD(v50) = MiStartingOffset(v18, SubsectionBase, (unsigned int)SessionId);
v51 = v50;
LODWORD(v52) = MiEndingOffsetWithLock(Subsection);
if( (((_WORD)v52 - (_WORD)v51) & 0xFFF) != 0 )
v95 = &SubsectionBase[((v52 - v51 + 4095) >> 12) - 1];
else
v95 = 0i64;
PxeUserLimit = MmGetPxeUserLimit();
if( v90 )
{
NumberOfPages = v51;
v94 = SubsectionBase;
LODWORD(NumberOfPages) = v51 & 0xFFFFFE00 | AccessInfo->EmptySequenceNumber & 0x1FF | 0x200;
v23 = NumberOfPages;
}
v10 = ControlArea;
}
Long = v21->u.Long;
if( v21 >= MmGetPml4eBase() && v21 <= PxeUserLimit )
LOWORD(Long) = MiReadPteShadow((__int64)v21, v21->u.Long);
if( (Long & 1) != 0 )
{
LABEL_37:
MiUpdatePfnPriorityByPte(v21, (unsigned int)DesiredPriority, v25);
goto LABEL_31;
}
if( (Long & 0x400) != 0 )
break;
if( (Long & 0x800) != 0 )
goto LABEL_37;
IS_PTE_NOT_DEMAND_ZERO();
if( v71 )
goto LABEL_20;
LABEL_31:
++v27;
++v21;
if( v27 >= (unsigned int)v13 )
goto LABEL_53;
v10 = ControlArea;
v18 = Subsection;
v26 = (UINT64)v89;
}
LOBYTE(v30) = MiControlAreaUsingExtents((INT64)v10);
if( v30 )
{
v73 = MiRefillPurgedExtents(Subsection, v21);
v102 = v73;
if( v73 < 0 )
{
v54 = v85;
v43 = v84;
v53 = v86;
if( v85 )
{
v55 = v73;
}
else
{
v55 = -1073741670;
v102 = -1073741670;
}
goto LABEL_55;
}
goto LABEL_31;
}
LOBYTE(v32) = MiControlAreaUsingCopyExtents(v31);
if( v32 )
goto LABEL_31;
v35 = v90;
if( v90 )
{
v23 += (v21 - v94) << 12;
v94 = v21;
v90->FileOffset = v23;
v90 = v35 + 1;
}
LABEL_20:
v36 = v33;
v37 = Subsection;
*v33 = v21;
v38 = (unsigned __int64)v21;
if( v86 )
v36 = v86;
v86 = v36;
v39 = v36;
if( (_SUBSECTION *)v26 != v37 || (MiGetPteAddress(Va), PteAddress = MiGetPteAddress(v21), v41 != PteAddress) )
{
v38 |= 2ui64;
v89 = v37;
*v33 = v38;
}
Va = v21;
if( v21 == v95 )
*v33 = v38 | 1;
v91 = (char *)(v33 + 1);
if( MiObtainFaultCharges(v34, 1ui64, 1) )
{
if( (unsigned int)MiUseSlabAllocator((__int64)ControlAreaPartition, Subsection, Long, 0i64) )
{
LODWORD(InputGetPageFlags) = 0x20000;
LODWORD(v74) = MiGetSlabPage(
(INT64)v42,
((unsigned __int16)Subsection->u.SubsectionFlags._bf_0 >> 1) & 0x1F,
0i64,
(INT64 *)0xFFFFFFFFFFFFFFFFi64,
InputGetPageFlags);
if( v74 == -1 )
{
v43 = v84;
v42 = ControlAreaPartition;
LABEL_105:
MiReturnFaultCharges(v42, 1ui64, 1ui64);
v53 = v39;
v54 = v85;
if( !v85 )
{
v55 = -1073741801;
v102 = -1073741801;
goto LABEL_55;
}
LABEL_54:
v55 = v102;
goto LABEL_55;
}
LODWORD(v75) = MiGetSlabAllocator(
(INT64)ControlAreaPartition,
0i64,
((unsigned __int16)Subsection->u.SubsectionFlags._bf_0 >> 1) & 0x1F);
MiSetPfnLink(v76, v16[*(int *)(v75 + 52) + 6]);
v16[*(int *)(v77 + 52) + 6] = v78;
}
else
{
v43 = v84;
if( v84 > v97 + 160 )
goto LABEL_105;
++v84;
}
++v85;
goto LABEL_31;
}
v80 = v102;
v54 = v85;
v53 = v86;
v43 = v84;
if( !v85 )
v80 = -1073741670;
v102 = v80;
v55 = v80;
LABEL_55:
if( AccessInfo )
AccessInfo->EmptyTime = (unsigned __int64)v90;
if( !v54 )
goto LABEL_73;
if( v43 )
{
NumberOfPages = v43;
v56 = MiProtectionToCacheAttribute((unsigned int)ProtectionMask);
LODWORD(InputGetPageFlags) = 0;
PageChain = MiGetPageChain(
v58,
Vm,
v57,
(unsigned int)v56,
InputGetPageFlags,
0xFFFFFFFFFFFFFFFFui64,
&NumberOfPages);
v60 = NumberOfPages;
v61 = ($559D8309DABD45803AD694472C7FC28A *)PageChain;
if( NumberOfPages != v84 )
{
MiReturnFaultCharges(ControlAreaPartition, v84 - NumberOfPages, 1ui64);
v81 = v102;
v54 += v60 - v84;
if( !v54 )
v81 = -1073741801;
v102 = v81;
v55 = v81;
}
if( v61 )
{
PfnDb = MmGetPfnDb();
do
{
v63 = v61[3]._bf_0 & 0xFFFFFFFFFi64;
if( v63 == 0xFFFFFFFFFi64 )
v64 = 0i64;
else
v64 = &PfnDb[v63];
MiSetPfnLink(v61, v16[5]);
v16[5] = v61;
MiSetPfnBlink(v65, 0i64, 0i64);
v61 = ($559D8309DABD45803AD694472C7FC28A *)v64;
}
while( v64 );
v55 = v102;
}
}
if( v54 )
{
v66 = v91 - (char *)v16 - 136;
v16[12] = v53;
*((_DWORD *)v16 + 23) = v66 >> 3;
Mdls = MiPfAllocateMdls((_MI_READ_LIST *)v16, (unsigned int)SessionId, 0i64);
if( (_QWORD *)v16[15] == v16 + 15 )
{
MiReleaseReadListResources((_MI_READ_LIST *)v16, v67);
ExFreePoolWithTag(v16, 0);
v16 = 0i64;
}
else
{
Mdls = 0;
}
*OutMiReadList = (_MI_READ_LIST *)v16;
return Mdls;
}
else
{
LABEL_73:
MiReleaseReadListResources((_MI_READ_LIST *)v16, v26);
ExFreePoolWithTag(v16, 0);
return v55;
}
}Referenced by:
MiPrefetchControlArea
MmPrefetchForCacheManager