MiPfPrepareSequentialReadList
INT64 __fastcall MiPfPrepareSequentialReadList(
INT64 rcx0,
INT64 rdx0,
UINT64 a3,
INT64 a4,
UINT64 a5,
UINT64 DesiredPriority,
UINT64 a7,
INT64 *a8){
bool v8;
INT64 v10;
unsigned __int64 ControlAreaPtes;
UINT64 v13;
INT64 v14;
INT64 v15;
_QWORD *v16;
unsigned int *v17;
UNICODE_STRING *v18;
UNICODE_STRING *v19;
UNICODE_STRING *v20;
UINT64 v21;
INT64 v22;
UINT8 v23;
WCHAR *v24;
unsigned int v25;
_MMPTE *PxeUserLimit;
__int64 v27;
INT64 v28;
_BYTE *v29;
_QWORD *v30;
_MI_PARTITION *v31;
UINT64 *v32;
_QWORD *v33;
_BYTE *v34;
unsigned __int64 v35;
_QWORD *v36;
MMPTE *PteAddress;
MMPTE *v38;
_MI_PARTITION *v39;
UINT64 v40;
int v41;
unsigned __int64 v42;
_QWORD *v43;
__int64 v44;
__int64 v45;
_QWORD *v46;
unsigned __int64 v47;
UINT64 v48;
_QWORD *v49;
__int64 v50;
unsigned int v51;
unsigned int v52;
UINT64 v53;
_MI_PARTITION *v54;
_MMPFN *PageChain;
UINT64 v56;
_MMPFN *v57;
_MMPFN *PfnDb;
__int64 v59;
_MMPFN *v60;
_MMPFN *v61;
__int64 v62;
unsigned int Mdls;
UINT64 *v65;
__int64 *SharedProtos;
int v67;
INT64 SlabAllocator;
_QWORD *v69;
__int64 v70;
__int64 v71;
int v72;
int v73;
UINT64 InputGetPageFlags;
_MI_PARTITION *a1;
unsigned __int64 v76;
__int64 v77;
_QWORD *v78;
UINT64 NumberOfPages;
_BYTE *a2;
_BYTE *v81;
UINT64 *p_Length;
_QWORD *v83;
UINT64 PteOffset;
UINT64 ProtectionMask;
UNICODE_STRING *v86;
UNICODE_STRING *v87;
PVOID Va;
INT64 AvailablePagesExcludeSlists;
_MMSUPPORT_INSTANCE *Vm;
__int128 v91;
int v94;
v8 = (*(_DWORD *)(rdx0 + 56) & 0x400) == 0;
v10 = rdx0;
v91 = 0i64;
*a8 = 0i64;
if( !v8 || !*(_QWORD *)(rdx0 + 64) )
return 3221225711i64;
ControlAreaPtes = MiGetControlAreaPtes(rdx0);
if( a5 )
{
v13 = a5 >> 12;
if( a5 >> 12 < 0x100000000i64 && (unsigned int)v13 <= ControlAreaPtes )
goto LABEL_6;
return 3221225713i64;
}
if( ControlAreaPtes >= 0x100000000i64 )
return 3221225713i64;
LODWORD(v13) = ControlAreaPtes;
LABEL_6:
LODWORD(v14) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
v15 = v14;
if( !v14 )
return 3221225626i64;
*(_QWORD *)(v14 + 8) = v10;
v16 = (_QWORD *)(v14 + 120);
PteOffset = 0i64;
v77 = 0i64;
v16[1] = v16;
*v16 = v16;
*(_QWORD *)(v15 + 32) = v15 + 24;
*(_QWORD *)(v15 + 24) = v15 + 24;
a2 = (_BYTE *)(v10 + 128);
LODWORD(v16) = (*(unsigned __int16 *)(v10 + 160) >> 1) & 0x1F;
v76 = 0i64;
v78 = 0i64;
Va = 0i64;
LODWORD(ProtectionMask) = (_DWORD)v16;
if( a5 )
{
v17 = (unsigned int *)MiOffsetToProtos((_CONTROL_AREA *)v10, a3, &PteOffset);
a2 = v17;
}
else
{
v17 = (unsigned int *)(v10 + 128);
}
a1 = MiGetControlAreaPartition((_CONTROL_AREA *)v10);
AvailablePagesExcludeSlists = MiGetAvailablePagesExcludeSlists((INT64)a1);
v19 = v18;
v87 = v18;
v20 = v18;
v86 = v18;
if( rcx0 )
{
v65 = *(UINT64 **)(rcx0 + 32);
NumberOfPages = __PAIR64__(HIDWORD(v18), *(_DWORD *)(rcx0 + 12) & 0x1FF | 0x200u);
v21 = NumberOfPages;
p_Length = v65;
}
else
{
p_Length = (UINT64 *)&v18->Length;
v21 = (UINT64)v18;
}
*(_DWORD *)(v15 + 80) = DesiredPriority;
*(_DWORD *)(v15 + 84) = 5;
*(_DWORD *)(v15 + 88) = 7;
v22 = (*(_DWORD *)(v10 + 56) >> 20) & 0x3F;
v83 = (_QWORD *)(v15 + 136);
Vm = (_MMSUPPORT_INSTANCE *)(*((_QWORD *)KeGetCurrentThread() + 23) + 1664i64);
MiInitializePageColorBase((INT64)Vm, v22, (INT64)&v91);
v94 = 0;
v25 = 0;
v81 = 0i64;
if( !(_DWORD)v13 )
{
v40 = 0i64;
v49 = 0i64;
v50 = 0i64;
v51 = 0;
goto LABEL_55;
}
while( 1 )
{
PxeUserLimit = MmGetPxeUserLimit();
if( v19 >= v20 )
{
if( v19 )
{
v17 = (unsigned int *)*((_QWORD *)v17 + 2);
a2 = v17;
if( !v17 )
{
LABEL_53:
v40 = v76;
v49 = v78;
v50 = v77;
goto LABEL_54;
}
PteOffset = 0i64;
}
v41 = *(_DWORD *)(v10 + 56);
if( (v41 & 0x20) != 0 )
{
v42 = *((_QWORD *)v17 + 1);
if( (*((_BYTE *)v17 + 34) & 2) != 0 && (v41 & 0x4000000) != 0 )
{
if( !*((_QWORD *)v17 + 3) )
{
v19 = (UNICODE_STRING *)((char *)v20 - 8);
goto LABEL_31;
}
SharedProtos = MiGetSharedProtos(rdx0, a7, (__int64)v17);
if( !SharedProtos )
{
v19 = (UNICODE_STRING *)((char *)v20 - 8);
goto LABEL_31;
}
v42 = SharedProtos[9];
}
}
else
{
v94 = MiAddViewsForSection((ULONG_PTR)v17, v17[11], 4);
if( v94 < 0 )
{
if( v76 )
MiReturnFaultCharges(a1, v76, 1ui64);
MiReleaseReadListResources(v15);
ExFreePoolWithTag((PVOID)v15, 0);
return(unsigned int)v94;
}
v42 = *((_QWORD *)v17 + 1);
v43 = (_QWORD *)(v15 + 24);
v44 = *(_QWORD *)(v15 + 32);
if( (_QWORD *)*v43 == v43 || *(_DWORD *)(v44 + 16) == 5 )
{
LODWORD(v45) = MiAllocatePool((struct _SLIST_ENTRY *)0x100);
v44 = v45;
if( !v45 )
{
MiRemoveViewsFromSectionWithPfn((ULONG_PTR)v17, v17[11], 4u);
MiReleaseReadListResources(v15);
ExFreePoolWithTag((PVOID)v15, 0);
return 3221225626i64;
}
v46 = *(_QWORD **)(v15 + 32);
if( (_QWORD *)*v46 != v43 )
__fastfail(3u);
*(_QWORD *)v44 = v43;
*(_QWORD *)(v44 + 8) = v46;
*v46 = v44;
*(_QWORD *)(v15 + 32) = v44;
}
if( !*(_QWORD *)(v15 + 16) )
*(_QWORD *)(v15 + 16) = v17;
*(_QWORD *)(v44 + 8i64 * (unsigned int)(*(_DWORD *)(v44 + 16))++ + 24) = v17;
}
v19 = (UNICODE_STRING *)(v42 + 8 * PteOffset);
v20 = (UNICODE_STRING *)(v42 + 8i64 * v17[11]);
v47 = MiStartingOffset((__int64)v17, v42, a7);
v48 = MiEndingOffsetWithLock((__int64)a2);
if( (((_WORD)v48 - (_WORD)v47) & 0xFFF) != 0 )
v87 = (UNICODE_STRING *)(v42 + 8 * (((v48 - v47 + 4095) >> 12) - 1));
else
v87 = 0i64;
PxeUserLimit = MmGetPxeUserLimit();
if( p_Length )
{
NumberOfPages = v47;
v86 = (UNICODE_STRING *)v42;
LODWORD(NumberOfPages) = v47 & 0xFFFFFE00 | *(_DWORD *)(rcx0 + 12) & 0x1FF | 0x200;
v21 = NumberOfPages;
}
v10 = rdx0;
}
v27 = *(_QWORD *)&v19->Length;
if( v19 >= (UNICODE_STRING *)MmGetPml4eBase() && v19 <= (UNICODE_STRING *)PxeUserLimit )
LOWORD(v27) = MiReadPteShadow(v19, *(UNICODE_STRING **)&v19->Length, v23, v24);
if( (v27 & 1) != 0 )
{
LABEL_37:
MiUpdatePfnPriorityByPte((_MMPTE *)v19, (unsigned int)DesiredPriority);
goto LABEL_31;
}
if( (v27 & 0x400) != 0 )
break;
if( (v27 & 0x800) != 0 )
goto LABEL_37;
if( IS_PTE_NOT_DEMAND_ZERO(v27) )
goto LABEL_20;
LABEL_31:
++v25;
v19 = (UNICODE_STRING *)((char *)v19 + 8);
if( v25 >= (unsigned int)v13 )
goto LABEL_53;
v10 = rdx0;
v17 = (unsigned int *)a2;
}
if( MiControlAreaUsingExtents(v10) )
{
v67 = MiRefillPurgedExtents((__int64 *)a2, (ULONG_PTR)v19);
v94 = v67;
if( v67 < 0 )
{
v50 = v77;
v40 = v76;
v49 = v78;
if( v77 )
{
v51 = v67;
}
else
{
v51 = -1073741670;
v94 = -1073741670;
}
goto LABEL_55;
}
goto LABEL_31;
}
if( MiControlAreaUsingCopyExtents(v28) )
goto LABEL_31;
v32 = p_Length;
if( p_Length )
{
v21 += ((char *)v19 - (char *)v86) >> 3 << 12;
v86 = v19;
*p_Length = v21;
p_Length = v32 + 1;
}
LABEL_20:
v33 = v30;
v34 = a2;
*v30 = v19;
v35 = (unsigned __int64)v19;
if( v78 )
v33 = v78;
v78 = v33;
v36 = v33;
if( v29 != v34 || (MiGetPteAddress(Va), PteAddress = MiGetPteAddress(v19), v38 != PteAddress) )
{
v35 |= 2ui64;
v81 = v34;
*v30 = v35;
}
Va = v19;
if( v19 == v87 )
*v30 = v35 | 1;
v83 = v30 + 1;
if( (unsigned int)MiObtainFaultCharges(v31, 1ui64, 1ui64) )
{
if( (unsigned int)MiUseSlabAllocator((INT64)a1, a2, v27, 0i64) )
{
LODWORD(InputGetPageFlags) = 0x20000;
if( MiGetSlabPage(
(UINT64)v39,
(*((unsigned __int16 *)a2 + 16) >> 1) & 0x1F,
0i64,
(INT64 *)0xFFFFFFFFFFFFFFFFi64,
InputGetPageFlags) == -1 )
{
v40 = v76;
v39 = a1;
LABEL_105:
MiReturnFaultCharges(v39, 1ui64, 1ui64);
v49 = v36;
v50 = v77;
if( !v77 )
{
v51 = -1073741801;
v94 = -1073741801;
goto LABEL_55;
}
LABEL_54:
v51 = v94;
goto LABEL_55;
}
SlabAllocator = MiGetSlabAllocator((INT64)a1, 0i64, (*((unsigned __int16 *)a2 + 16) >> 1) & 0x1F);
MiSetPfnLink(v69, *(_QWORD *)(v15 + 8i64 * *(int *)(SlabAllocator + 52) + 48));
*(_QWORD *)(v15 + 8i64 * *(int *)(v70 + 52) + 48) = v71;
}
else
{
v40 = v76;
if( v76 > AvailablePagesExcludeSlists + 160 )
goto LABEL_105;
++v76;
}
++v77;
goto LABEL_31;
}
v72 = v94;
v50 = v77;
v49 = v78;
v40 = v76;
if( !v77 )
v72 = -1073741670;
v94 = v72;
v51 = v72;
LABEL_55:
if( rcx0 )
*(_QWORD *)(rcx0 + 24) = p_Length;
if( !v50 )
goto LABEL_73;
if( v40 )
{
NumberOfPages = v40;
v52 = MiProtectionToCacheAttribute((unsigned int)ProtectionMask);
LODWORD(InputGetPageFlags) = 0;
PageChain = MiGetPageChain(v54, Vm, v53, v52, InputGetPageFlags, 0xFFFFFFFFFFFFFFFFui64, &NumberOfPages);
v56 = NumberOfPages;
v57 = PageChain;
if( NumberOfPages != v76 )
{
MiReturnFaultCharges(a1, v76 - NumberOfPages, 1ui64);
v73 = v94;
v50 += v56 - v76;
if( !v50 )
v73 = -1073741801;
v94 = v73;
v51 = v73;
}
if( v57 )
{
PfnDb = MmGetPfnDb();
do
{
v59 = *((_QWORD *)v57 + 3) & 0xFFFFFFFFFi64;
if( v59 == 0xFFFFFFFFFi64 )
v60 = 0i64;
else
v60 = (_MMPFN *)((char *)PfnDb + 48 * v59);
MiSetPfnLink(v57, *(_QWORD *)(v15 + 40));
*(_QWORD *)(v15 + 40) = v57;
MiSetPfnBlink(v61, 0i64, 0i64);
v57 = v60;
}
while( v60 );
v51 = v94;
}
}
if( v50 )
{
v62 = (__int64)v83 - v15 - 136;
*(_QWORD *)(v15 + 96) = v49;
*(_DWORD *)(v15 + 92) = v62 >> 3;
Mdls = MiPfAllocateMdls(v15, (unsigned int)a7, 0i64);
if( *(_QWORD *)(v15 + 120) == v15 + 120 )
{
MiReleaseReadListResources(v15);
ExFreePoolWithTag((PVOID)v15, 0);
v15 = 0i64;
}
else
{
Mdls = 0;
}
*a8 = v15;
return Mdls;
}
else
{
LABEL_73:
MiReleaseReadListResources(v15);
ExFreePoolWithTag((PVOID)v15, 0);
return v51;
}
}Referenced by:
MiPrefetchControlArea
MmPrefetchForCacheManager