MiAllocateFileExtents
NTSTATUS __stdcall MiAllocateFileExtents(
_SUBSECTION *Subsection,
UINT64 SubsectionProtoOffset,
_MMPTE *ProtoPtes,
UINT64 NumberOfProtos,
UINT64 AllocationFlags){
int v5;
_MMPTE *v7;
UINT64 v8;
_CONTROL_AREA *ControlArea;
unsigned __int64 v10;
UINT64 v11;
UINT64 v12;
_KSCHEDULING_GROUP_POLICY v13;
_FILE_OBJECT *v14;
ULONG i;
PHYSICAL_EXTENTS_DESCRIPTOR *Pool;
_MMPTE *SubsectionBase;
PHYSICAL_EXTENTS_DESCRIPTOR *v18;
__int64 v20;
int v21;
unsigned __int64 v22;
UINT64 *v23;
int v24;
_MMPTE *v25;
int v26;
_EPROCESS *v27;
UINT64 v28;
UINT64 v29;
int v30;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v31;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v32;
_MMPTE *v33;
int v34;
UINT64 v35;
_CONTROL_AREA *v36;
_MI_PARTITION *ControlAreaPartition;
__int64 v38;
void *v39;
int FileExtents;
ULONG NumberOfValidRuns;
int v42;
int a3;
unsigned int a3_4;
UINT64 StartPage;
_KSCHEDULING_GROUP_POLICY Policy;
UINT64 NumberOfPages;
_CONTROL_AREA *v48;
_LARGE_INTEGER NumberOfBytes;
_LARGE_INTEGER StartAddress;
__int128 Node;
__int128 Node_16;
__int128 v53;
__int128 v54[2];
__int64 v55;
_SUBSECTION *v56;
_MMPTE *v57;
int v58;
int v59;
int v60;
int v61;
int v62;
v62 = SubsectionProtoOffset;
v5 = NumberOfProtos;
a3_4 = 0;
NumberOfPages = 0i64;
Policy = 0i64;
v7 = ProtoPtes;
v8 = (unsigned int)(v5 << 12);
StartPage = (unsigned int)v8;
memset(v54, 0, sizeof(v54));
v55 = 0i64;
Node = 0i64;
Node_16 = 0i64;
v53 = 0i64;
while( 2 )
{
ControlArea = Subsection->ControlArea;
v10 = v8;
v48 = ControlArea;
if( (ControlArea->u.LongFlags & 0x20) != 0 )
{
a3 = 1;
if( Subsection->SubsectionBase )
{
LODWORD(v12) = MiStartingOffset(Subsection, v7, 0i64);
v11 = v12;
}
else
{
v11 = (unsigned __int64)(unsigned int)SubsectionProtoOffset << 12;
}
MiEndingOffset(Subsection);
Policy = v13;
if( v11 == v13 && !v11 )
return 0;
if( v10 + v11 > *(_QWORD *)&v13 )
v10 = ((unsigned int)(v13.Value - v11) + 511i64) & 0xFFFFFFFFFFFFFE00ui64;
}
else
{
a3 = 2;
v11 = ((unsigned int)SubsectionProtoOffset
+ (Subsection->StartingSector | ((unsigned __int64)(Subsection->u.SubsectionFlags._bf_0 & 0xFFC0) << 26))) << 12;
}
v14 = MiReferenceControlAreaFile(ControlArea);
v42 = 1;
for( i = ((__rdtsc() >> 4) & 7) + 8; ; i = NumberOfValidRuns )
{
while( 1 )
{
if( !i )
{
LABEL_16:
MiDereferenceControlAreaFile(ControlArea, v14);
return -1073741670;
}
Pool = (PHYSICAL_EXTENTS_DESCRIPTOR *)MiAllocatePool(64i64, 16i64 * (i - 1) + 24, 0x6546694Dui64);
v18 = Pool;
if( Pool )
break;
if( !v42 )
goto LABEL_16;
i >>= 1;
}
Pool->NumberOfRuns = i;
Pool->NumberOfValidRuns = 0;
v42 = 0;
v60 = 0;
if( a3 == 1 )
{
if( v10 + v11 > *(_QWORD *)&Policy )
v10 = (unsigned int)(Policy.Value - v11);
SubsectionBase = Subsection->SubsectionBase;
if( SubsectionBase && ((__int64)ControlArea->u2.SeImageStub->u1.ImageFileExtents & 1) != 0 )
v11 = (SubsectionBase - ControlArea->Segment->PrototypePte) << 12;
}
v10 = (v10 + 4095) & 0xFFFFFFFFFFFFF000ui64;
if( a3 != 1 || (ControlArea->u.LongFlags & 2) == 0 )
{
v61 = MiChangingSubsectionProtos((ULONG_PTR)Subsection);
if( v61 < 0 )
{
MiDereferenceControlAreaFile(ControlArea, v14);
ExFreePoolWithTag(v18, 0);
return v61;
}
v60 = 1;
}
FileExtents = FsRtlGetFileExtents(v14, (UINT64)SubsectionBase, v11, (PHYSICAL_EXTENTS_DESCRIPTOR *)v10, v18);
if( FileExtents < 0 )
{
MiDereferenceControlAreaFile(ControlArea, v14);
if( v60 == 1 )
MiUnlinkSubsectionWaitBlock(Subsection, (_MI_CONTROL_AREA_WAIT_BLOCK *)v54, 0i64);
v39 = v18;
LABEL_120:
ExFreePoolWithTag(v39, 0);
return FileExtents;
}
NumberOfValidRuns = v18->NumberOfValidRuns;
if( NumberOfValidRuns <= i )
break;
if( v60 == 1 )
{
MiUnlinkSubsectionWaitBlock(Subsection, (_MI_CONTROL_AREA_WAIT_BLOCK *)v54, 0i64);
NumberOfValidRuns = v18->NumberOfValidRuns;
}
v18->NumberOfValidRuns = i;
ExFreePoolWithTag(v18, 0);
}
MiDereferenceControlAreaFile(ControlArea, v14);
v20 = 0i64;
if( !MiNewPfnsSuitable(v18) )
{
v24 = -1073740761;
LABEL_114:
ExFreePoolWithTag(v18, 0);
if( v60 == 1 )
MiUnlinkSubsectionWaitBlock(Subsection, (_MI_CONTROL_AREA_WAIT_BLOCK *)v54, 0i64);
return v24;
}
if( v18->NumberOfValidRuns )
{
v23 = MiConvertRunsToPages(v18, &NumberOfPages, (UINT64 *)&a3_4);
if( v23 )
{
if( (AllocationFlags & 0x40) == 0 || a3_4 <= 1 )
{
v22 = NumberOfPages;
v21 = a3;
goto LABEL_41;
}
v24 = -1073741800;
}
else
{
v24 = -1073741670;
}
goto LABEL_114;
}
if( (AllocationFlags & 0x40) != 0 || (v21 = a3, a3 == 1) )
{
v24 = -1073741823;
goto LABEL_114;
}
a3_4 = -1;
v22 = 0i64;
NumberOfPages = 0i64;
v23 = 0i64;
LABEL_41:
if( v21 == 1 && (ControlArea->u.LongFlags & 2) != 0 )
goto LABEL_54;
v24 = MiChangingSubsectionProtos((ULONG_PTR)Subsection);
if( v24 >= 0 )
{
if( v23 )
{
v25 = ProtoPtes;
if( (AllocationFlags & 1) == 0 )
MiEliminateStaleExtents(ProtoPtes, v23, v22);
goto LABEL_55;
}
LABEL_54:
v25 = ProtoPtes;
LABEL_55:
ExFreePoolWithTag(v18, 0);
if( v23 && (ControlArea->u.LongFlags & 0x20) == 0 && (AllocationFlags & 1) != 0 )
{
*((_QWORD *)&v53 + 1) = v22;
*(_QWORD *)&v53 = v25;
*((_QWORD *)&Node_16 + 1) = *((_QWORD *)&Node_16 + 1) & 0xFFFFFFFFFFFFFFF8ui64 | 4;
MiUpdateSystemProtoPtesTree((_RTL_BALANCED_NODE *)&Node, 1i64);
}
v26 = 0;
v27 = 0i64;
FileExtents = 0;
v28 = -1i64;
Policy = 0i64;
v29 = 0i64;
StartPage = -1i64;
v30 = AllocationFlags & 0x40;
while( 1 )
{
if( (unsigned int)v20 == v22 )
{
if( !v29 )
goto LABEL_77;
}
else
{
if( !v29 )
{
v28 = v23[v20];
StartPage = v28;
v29 = 1i64;
goto LABEL_99;
}
v27 = (_EPROCESS *)Policy;
if( v23[v20 - 1] + 1 == v23[v20] )
{
++v29;
goto LABEL_100;
}
v30 = AllocationFlags & 0x40;
}
if( v28 == 0x8000000000000000ui64 )
{
if( v26 >= 0 )
{
MiMakeSubsectionPte(
(_KSCHEDULING_GROUP *)Subsection,
(_KSCHEDULING_GROUP_POLICY)v27,
(_KSCHEDULING_GROUP *)0x8000000000000000i64);
v32.Long = v31.Long;
v33 = &ProtoPtes[(unsigned int)v20 - v29];
LOBYTE(v34) = MiPteInShadowRange((UINT64)v33);
if( v34 )
{
if( (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v32.Long & 1) != 0 )
v32.Long |= 0x8000000000000000ui64;
v22 = NumberOfPages;
}
v33->u.Long = v32.Long;
if( (AllocationFlags & 2) != 0 )
{
v26 = -1073740023;
FileExtents = -1073740023;
LABEL_76:
v30 = AllocationFlags & 0x40;
LABEL_77:
if( v26 < 0 )
{
if( (_QWORD)v53 )
MiUpdateSystemProtoPtesTree((_RTL_BALANCED_NODE *)&Node, 0i64);
LABEL_106:
v38 = (__int64)v48;
}
else
{
if( (AllocationFlags & 1) == 0 )
goto LABEL_106;
if( v30 )
Subsection[1]._bf_34 = 2;
MiSetSubsectionBase(Subsection, ProtoPtes);
if( (_QWORD)v53 )
{
MiReplaceSystemProtoPtesNode((_RTL_BALANCED_NODE *)&Node, (_RTL_BALANCED_NODE *)&Subsection[2]);
goto LABEL_106;
}
v38 = (__int64)v48;
if( (v48->u.LongFlags & 0x20) == 0 )
MiUpdateSystemProtoPtesTree((_RTL_BALANCED_NODE *)&Subsection[2], 1i64);
}
if( a3 != 1 || (*(_DWORD *)(v38 + 56) & 2) == 0 )
MiSubsectionProtosCreated(Subsection, (_MI_CONTROL_AREA_WAIT_BLOCK *)v54);
if( v23 )
{
v39 = v23;
goto LABEL_120;
}
return FileExtents;
}
goto LABEL_95;
}
goto LABEL_97;
}
if( (v28 & 0x4000000000000000i64) != 0 )
{
if( v26 >= 0 || &v23[v20] > (UINT64 *)v27 )
goto LABEL_97;
if( (unsigned int)v20 == v22 )
goto LABEL_76;
v29 = 0i64;
LODWORD(v20) = v20 - 1;
}
else
{
if( v26 < 0 )
{
if( &v23[v20] <= (UINT64 *)v27 )
{
if( (AllocationFlags & 0x40) != 0 )
MiDecrementProtoShareCounts(v28, v29);
MiRemovePhysicalMemory(StartPage, v29, 0x12ui64);
LABEL_95:
v26 = FileExtents;
LABEL_96:
v28 = StartPage;
}
LABEL_97:
if( (unsigned int)v20 == v22 )
goto LABEL_76;
v29 = 0i64;
LODWORD(v20) = v20 - 1;
LABEL_99:
v27 = (_EPROCESS *)Policy;
goto LABEL_100;
}
v59 = 0;
v56 = Subsection;
v35 = (unsigned int)v20 - v29;
v58 = 2 - (v30 != 0);
v36 = Subsection->ControlArea;
NumberOfBytes.QuadPart = v29 << 12;
v57 = &ProtoPtes[v35];
StartAddress.QuadPart = v28 << 12;
ControlAreaPartition = MiGetControlAreaPartition(v36, v27);
FileExtents = MiAddPhysicalMemory(ControlAreaPartition, &StartAddress, &NumberOfBytes, 2ui64);
v26 = FileExtents;
if( FileExtents >= 0 )
goto LABEL_96;
v28 = StartPage;
v27 = (_EPROCESS *)&v23[v35];
v29 = 0i64;
Policy = (_KSCHEDULING_GROUP_POLICY)v27;
LODWORD(v20) = -1;
}
LABEL_100:
v20 = (unsigned int)(v20 + 1);
v30 = AllocationFlags & 0x40;
if( (unsigned int)v20 > v22 )
goto LABEL_77;
}
}
ExFreePoolWithTag(v18, 0);
if( v23 )
ExFreePoolWithTag(v23, 0);
if( v24 == -1073740748 )
{
LODWORD(SubsectionProtoOffset) = v62;
v8 = StartPage;
v7 = ProtoPtes;
continue;
}
return v24;
}
}Referenced by:
MiAddViewsForSection
MiCreatePrototypePtes
MiFaultGetFileExtents
MiInitializeImageExtents
MiRefillPurgedExtents
MiUpdateActiveSubsection