MiPfPrepareReadList
NTSTATUS __stdcall MiPfPrepareReadList(_READ_LIST *ReadList, _MI_READ_LIST **OutMiReadList, UINT64 *PrefetchPagesMax){
unsigned int Alignment;
PFILE_OBJECT FileObject;
ULONG NumberOfEntries;
void **p_ImageSectionObject;
_CONTROL_AREA *v8;
char *Pool;
_EPROCESS *v10;
_QWORD *v11;
_QWORD *v12;
_SUBSECTION *SubsectionNode;
_EPROCESS *Process;
FILE_SEGMENT_ELEMENT v15;
unsigned __int64 v16;
unsigned __int64 v17;
_MMPTE *v18;
UINT64 Pml4eBase;
unsigned int v20;
__int64 v21;
unsigned __int64 v22;
_MMPTE *PxeUserLimit;
_MMPTE *SubsectionBase;
_MMPTE *v25;
__int64 Long;
int v27;
INT64 v28;
_MMPTE *v29;
int v30;
VOID *v31;
VOID *v32;
__int64 v33;
__int64 *v34;
__int64 *v35;
VOID *v36;
_MMPTE *PteAddress;
_MMPTE *v38;
_MI_READ_LIST *v39;
_MI_PARTITION *v40;
char *v41;
int v42;
unsigned int v43;
__int64 v44;
int v45;
_QWORD *v46;
__int64 v47;
_CONTROL_AREA *v48;
int v49;
unsigned __int64 v50;
unsigned __int64 v51;
_CONTROL_AREA *v52;
__int64 v53;
__int64 *v54;
_DWORD *v56;
_DWORD *v57;
_QWORD *v58;
int v59;
UINT64 v60;
UINT64 v61;
NTSTATUS Mdls;
int v63;
__int64 v64;
_QWORD *v65;
__int64 v66;
__int64 v67;
int v68;
UINT64 v69;
__int64 v70;
__int64 *v71;
_MI_READ_LIST *MiReadList;
__int64 *v73;
_CONTROL_AREA *ControlArea;
unsigned int v75;
_BYTE v76[12];
_QWORD *v77;
VOID *Va;
_MI_PARTITION *Partition;
_MI_COLOR_BASE ColorBase[8];
UINT64 PteOffset;
_MI_READ_LIST **v82;
UINT64 *v83;
UINT64 SessionId;
v83 = PrefetchPagesMax;
v82 = OutMiReadList;
*OutMiReadList = 0i64;
*(_OWORD *)ColorBase = 0i64;
Alignment = ReadList->List[0].Alignment;
PteOffset = 0i64;
if( (Alignment & 0x180) != 0 )
return -1073741585;
FileObject = ReadList->FileObject;
NumberOfEntries = ReadList->NumberOfEntries;
v75 = NumberOfEntries;
p_ImageSectionObject = &ReadList->FileObject->SectionObjectPointer->ImageSectionObject;
if( !ReadList->IsImage )
p_ImageSectionObject = &FileObject->SectionObjectPointer->DataSectionObject;
v8 = (_CONTROL_AREA *)*p_ImageSectionObject;
ControlArea = (_CONTROL_AREA *)*p_ImageSectionObject;
if( (*((_DWORD *)*p_ImageSectionObject + 14) & 0x400) != 0 || !v8->FilePointer.Value )
return -1073741585;
Pool = (char *)MiAllocatePool(64i64, 8i64 * (NumberOfEntries - 1) + 144, 0x6C526D4Dui64);
MiReadList = (_MI_READ_LIST *)Pool;
v11 = Pool;
if( !Pool )
return -1073741670;
*((_QWORD *)Pool + 1) = v8;
v12 = Pool + 120;
SubsectionNode = (_SUBSECTION *)&v8[1];
v12[1] = v12;
*v12 = v12;
v11[4] = v11 + 3;
v11[3] = v11 + 3;
v77 = v11 + 3;
Process = KeGetCurrentThread()->ApcState.Process;
Partition = MiGetControlAreaPartition(v8, v10);
if( (v8->u.LongFlags & 0x20) != 0 )
{
LODWORD(SessionId) = MmGetSessionIdEx(Process);
}
else
{
v15.Buffer = (void *)ReadList->List[0];
if( v15.Alignment > 0x3FFFFFFFFFF000i64
|| (SubsectionNode = MiOffsetToProtos(v8, v15.Alignment, &PteOffset)) == 0i64 )
{
ExFreePoolWithTag(v11, 0);
return 0;
}
LODWORD(SessionId) = -1;
}
v16 = 0i64;
v17 = 0i64;
Va = 0i64;
v70 = 0i64;
v73 = (__int64 *)(MiReadList + 34);
v71 = 0i64;
*(_DWORD *)&v76[8] = 0;
v18 = 0i64;
MiReadList[20] = Alignment & 7;
*(_QWORD *)v76 = Alignment & 7;
MiReadList[21] = (Alignment & 0x40) != 0 ? 5 : 0;
LODWORD(PteOffset) = 0;
MiReadList[22] = (Alignment >> 3) & 7;
MiInitializePageColorBase(&Process->Vm.Instance, (v8->u.LongFlags >> 20) & 0x3F, ColorBase);
v21 = 0i64;
if( !v75 )
goto LABEL_61;
while( 1 )
{
v22 = ReadList->List[v21].Alignment & 0xFFFFFFFFFFFFFF80ui64;
PxeUserLimit = MmGetPxeUserLimit();
Pml4eBase = (UINT64)MmGetPml4eBase();
if( v22 >= v17 || v16 > v22 )
break;
SubsectionBase = SubsectionNode->SubsectionBase;
v25 = &SubsectionBase[(v22 - v16) >> 12];
if( v25 >= &SubsectionBase[SubsectionNode->PtesInSubsection] )
goto LABEL_57;
if( (SubsectionNode->u.SubsectionFlags._bf_2 & 2) != 0 && (v8->u.LongFlags & 0x4000000) != 0 )
goto LABEL_20;
LABEL_16:
if( v25 == v18 )
goto LABEL_20;
Long = v25->u.Long;
v18 = v25;
if( (unsigned __int64)v25 >= Pml4eBase && v25 <= PxeUserLimit )
LOWORD(Long) = MiReadPteShadow((__int64)v25, v25->u.Long);
if( (Long & 1) != 0 )
{
LABEL_19:
MiUpdatePfnPriorityByPte(v25, v20, (CHAR)PxeUserLimit);
goto LABEL_20;
}
if( (Long & 0x400) != 0 )
{
LOBYTE(v27) = MiControlAreaUsingExtents((INT64)v8);
if( !v27 )
{
LOBYTE(v30) = MiControlAreaUsingCopyExtents(v28);
if( v30 )
goto LABEL_20;
LABEL_29:
v33 = (__int64)v31;
v34 = v73;
v35 = v73;
if( v71 )
v35 = v71;
v71 = v35;
*v73 = (__int64)v31;
if( *(_SUBSECTION **)&v76[4] != SubsectionNode
|| (MiGetPteAddress(Va), PteAddress = MiGetPteAddress(v36), v38 != PteAddress) )
{
v33 |= 2ui64;
*(_QWORD *)&v76[4] = SubsectionNode;
*v34 = v33;
}
Va = v31;
if( v31 == v32 )
*v34 = v33 | 1;
v39 = MiReadList;
v73 = v34 + 1;
if( !MiPrefetchNormally(Partition, (unsigned int)(MiReadList[22] + 1)) )
goto LABEL_58;
Pml4eBase = (UINT64)v83;
if( v83 )
{
if( !*v83 )
goto LABEL_58;
--*v83;
}
if( !MiObtainFaultCharges(v40, 1ui64, 1) )
{
v68 = PteOffset;
Pml4eBase = 3221225626i64;
v53 = v70;
v41 = (char *)v73;
if( !v70 )
v68 = -1073741670;
LODWORD(PteOffset) = v68;
goto LABEL_59;
}
MiGetNextPageColor((INT64)ColorBase);
if( (unsigned int)MiUseSlabAllocator((__int64)Partition, SubsectionNode, Long, 0i64) )
{
LODWORD(v69) = v42;
LODWORD(v44) = MiGetSlabPage(
(INT64)Partition,
((unsigned __int16)SubsectionNode->u.SubsectionFlags._bf_0 >> 1) & 0x1F,
0i64,
(INT64 *)0xFFFFFFFFFFFFFFFFi64,
v69);
}
else
{
LODWORD(v44) = MiGetPage((ULONG_PTR *)&Partition->Core.PartitionId, v43, 0x200ui64);
}
if( v44 == -1 )
{
MiReturnFaultCharges(Partition, 1ui64, 1ui64);
v54 = v71;
if( !v70 )
{
LODWORD(v21) = -1073741801;
goto LABEL_61;
}
LABEL_105:
v41 = (char *)v73;
goto LABEL_76;
}
LOBYTE(v45) = MiIsPfnFromSlabAllocation((INT64)&MmGetPfnDb()[v44]);
if( v45 )
{
LODWORD(v64) = MiGetSlabAllocator(
(INT64)Partition,
0i64,
((unsigned __int16)SubsectionNode->u.SubsectionFlags._bf_0 >> 1) & 0x1F);
MiSetPfnLink(v65, *(_QWORD *)&MiReadList[2 * *(int *)(v64 + 52) + 12]);
*(_QWORD *)&MiReadList[2 * *(int *)(v66 + 52) + 12] = v67;
}
else
{
MiSetPfnLink(v46, *((_QWORD *)MiReadList + 5));
*((_QWORD *)MiReadList + 5) = v47;
}
++v70;
goto LABEL_20;
}
LODWORD(PteOffset) = MiRefillPurgedExtents(SubsectionNode, v29);
if( (PteOffset & 0x80000000) == 0i64 )
goto LABEL_20;
if( v70 )
{
v39 = MiReadList;
v54 = v71;
goto LABEL_105;
}
LODWORD(v21) = -1073741670;
LABEL_61:
MiReleaseReadListResources(MiReadList, Pml4eBase);
ExFreePoolWithTag(MiReadList, 0);
return v21;
}
if( (Long & 0x800) != 0 )
goto LABEL_19;
IS_PTE_NOT_DEMAND_ZERO();
if( v63 )
goto LABEL_29;
LABEL_20:
v21 = (unsigned int)(v21 + 1);
if( (unsigned int)v21 >= v75 )
goto LABEL_57;
v8 = ControlArea;
v20 = *(_DWORD *)v76;
}
v48 = ControlArea;
v49 = 0;
while( 1 )
{
if( (v48->u.LongFlags & 0x20) != 0
&& !SubsectionNode->StartingSector
&& SubsectionNode->SubsectionBase != v48->Segment->PrototypePte )
{
SubsectionNode = SubsectionNode->NextSubsection;
LABEL_71:
v48 = ControlArea;
goto LABEL_56;
}
LODWORD(v50) = MiStartingOffsetNeedLock(SubsectionNode, (unsigned int)SessionId);
v16 = v50;
LODWORD(v51) = MiEndingOffsetWithLock(SubsectionNode);
v17 = v51;
if( v16 > v22 )
goto LABEL_20;
if( v22 < v51 )
break;
v48 = ControlArea;
if( (ControlArea->u.LongFlags & 0x20) == 0 )
{
if( v22 > 0x3FFFFFFFFFF000i64 )
goto LABEL_57;
SubsectionNode = MiLocateSubsectionNode(ControlArea, v22, 0i64);
goto LABEL_71;
}
SubsectionNode = SubsectionNode->NextSubsection;
LABEL_56:
if( !SubsectionNode )
goto LABEL_57;
}
v52 = ControlArea;
if( (ControlArea->u.LongFlags & 0x20) != 0 )
goto LABEL_50;
LODWORD(PteOffset) = MiAddViewsForSection(SubsectionNode, SubsectionNode->PtesInSubsection, 4ui64);
if( (PteOffset & 0x80000000) != 0i64 )
goto LABEL_57;
v56 = (_DWORD *)*((_QWORD *)MiReadList + 4);
if( (_QWORD *)*v77 != v77 )
{
v59 = v56[4];
if( v59 != 5 )
{
LABEL_67:
v52 = ControlArea;
*(_QWORD *)&v56[2 * v59 + 6] = SubsectionNode;
++v56[4];
if( !*((_QWORD *)MiReadList + 2) )
*((_QWORD *)MiReadList + 2) = SubsectionNode;
LABEL_50:
Pml4eBase = (UINT64)SubsectionNode->SubsectionBase;
v25 = (_MMPTE *)(Pml4eBase + 8 * ((v22 - v16) >> 12));
if( (unsigned __int64)v25 >= Pml4eBase + 8i64 * SubsectionNode->PtesInSubsection )
goto LABEL_57;
if( (SubsectionNode->u.SubsectionFlags._bf_2 & 2) != 0 && (v52->u.LongFlags & 0x4000000) != 0 )
v49 = 1;
if( v49 == 1 )
goto LABEL_20;
v8 = ControlArea;
v20 = *(_DWORD *)v76;
Pml4eBase = (UINT64)MmGetPml4eBase();
PxeUserLimit = MmGetPxeUserLimit();
goto LABEL_16;
}
}
v57 = MiAllocatePool(256i64, 0x40ui64, 0x6C536D4Dui64);
v56 = v57;
if( v57 )
{
v57[4] = 0;
v58 = (_QWORD *)v77[1];
if( (_QWORD *)*v58 != v77 )
__fastfail(3u);
*(_QWORD *)v56 = v77;
*((_QWORD *)v56 + 1) = v58;
*v58 = v56;
v77[1] = v56;
v59 = v56[4];
goto LABEL_67;
}
MiRemoveViewsFromSectionWithPfn(SubsectionNode, SubsectionNode->PtesInSubsection);
LABEL_57:
v39 = MiReadList;
v41 = (char *)v73;
LABEL_58:
v53 = v70;
LABEL_59:
v54 = v71;
if( !v53 )
{
LODWORD(v21) = PteOffset;
goto LABEL_61;
}
LABEL_76:
v60 = (unsigned int)SessionId;
*((_QWORD *)v39 + 12) = v54;
v39[23] = (v41 - (char *)v39 - 136) >> 3;
Mdls = MiPfAllocateMdls(v39, v60, 0i64);
if( *((_MI_READ_LIST **)v39 + 15) == v39 + 30 )
{
MiReleaseReadListResources(v39, v61);
ExFreePoolWithTag(v39, 0);
v39 = 0i64;
}
else
{
Mdls = 0;
}
*v82 = v39;
return Mdls;
}Referenced by:
MmPrefetchPagesEx