MmPurgeSection
UINT8 __stdcall MmPurgeSection(
_SECTION_OBJECT_POINTERS *FsSectionObjectPointer,
_LARGE_INTEGER *Offset,
UINT64 RegionSize,
UINT64 PurgeFlags,
UINT8 *ExtentPagesActive){
char v5;
_LARGE_INTEGER *v7;
__int64 v8;
_CONTROL_AREA *v9;
UINT8 v10;
INT64 v11;
UINT64 SubsectionBase;
UINT8 v14;
char v15;
_SUBSECTION *NextSubsection;
_MMPTE **p_SubsectionBase;
int v18;
int v19;
__int64 v20;
_MMPFN *v21;
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;} v22;
_MMPTE v23;
_MMPFN *v24;
void *v25;
unsigned __int8 v26;
bool v27;
_MSUBSECTION *v28;
UINT64 v29;
UINT8 v30;
__int64 v31;
__int64 v32;
__int64 v33;
UINT64 v34;
_MI_CROSS_PARTITION_CHARGES *v35;
__int64 v36;
UINT8 *EntryIrql;
char v38;
ULONG_PTR ProtoPagePfn;
_MSUBSECTION *MappedSubsection;
__int64 v41;
UINT64 SpinCount;
LONGLONG QuadPart;
_MI_FLUSH_RANGE FlushRange[4];
_SUBSECTION *LastSubsection[2];
__int128 FirstSubsection;
char v47[32];
__int64 v48;
UINT8 PageIrql;
UINT8 v50;
int v51;
v51 = PurgeFlags;
v50 = 0;
v48 = 0i64;
PageIrql = 0;
QuadPart = 0i64;
v5 = PurgeFlags;
v7 = Offset;
*ExtentPagesActive = 0;
*(_OWORD *)FlushRange = 0i64;
*(_OWORD *)LastSubsection = 0i64;
FirstSubsection = 0i64;
memset(v47, 0, sizeof(v47));
if( Offset )
{
v7 = (_LARGE_INTEGER *)&QuadPart;
QuadPart = Offset->QuadPart;
}
v41 = 0i64;
v8 = 0i64;
v9 = MiCanFileBeTruncatedInternal(
(_MI_SECTION_OBJECT_POINTERS *)FsSectionObjectPointer,
v7,
1ui64,
((unsigned int)PurgeFlags >> 1) & 1,
&v50);
v10 = v50;
v11 = (INT64)v9;
if( v50 == 17 )
return 0;
if( !v9 )
return 1;
if( (v5 & 1) == 0 && v9->u2.NumberOfSystemCacheViews || !v9->FilePointer.Value )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&v9->ControlAreaLock);
__writecr8(v10);
return 0;
}
v9->u.LongFlags |= 0x8000u;
LODWORD(EntryIrql) = 1;
if( !MiComputeDataFlushRange(v9, v10, v7, RegionSize, (UINT64)EntryIrql, FlushRange) )
return 1;
SubsectionBase = *(_QWORD *)&FlushRange[2];
v14 = 17;
v15 = 1;
NextSubsection = LastSubsection[1];
v50 = 17;
v38 = 1;
LABEL_11:
MappedSubsection = (_MSUBSECTION *)NextSubsection;
if( v14 == 17 )
{
v14 = ExAcquireSpinLockExclusive((INT64 *)(v11 + 72));
v50 = v14;
}
if( (_SUBSECTION *)FirstSubsection == NextSubsection )
p_SubsectionBase = &LastSubsection[0]->SubsectionBase;
else
p_SubsectionBase = (_MMPTE **)&NextSubsection->SubsectionBase[NextSubsection->PtesInSubsection
- (NextSubsection->_bf_34 & 0x3FFFFFFF)];
LOBYTE(v18) = MiControlAreaUsingExtents(v11);
v19 = v18;
if( v20 )
{
if( MappedSubsection->LargeViews )
{
v30 = 0;
goto LABEL_49;
}
MiIncrementSubsectionViewCount(MappedSubsection, 0i64);
if( (MappedSubsection->Core.u.SubsectionFlags._bf_2 & 8) != 0 )
MiRemoveUnusedSubsection(MappedSubsection);
MappedSubsection->Core.u.SubsectionFlags._bf_0 |= 1u;
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v11 + 72));
__writecr8(v14);
LODWORD(v21) = 0;
PageIrql = 17;
ProtoPagePfn = 0;
if( v19 )
{
MiChangingSubsectionProtos((ULONG_PTR)MappedSubsection);
LODWORD(v21) = 0;
}
if( SubsectionBase >= (unsigned __int64)p_SubsectionBase )
goto LABEL_43;
while( 1 )
{
if( (SubsectionBase & 0xFFF) != 0 )
{
if( PageIrql != 17 )
goto LABEL_24;
}
else if( PageIrql != 17 )
{
MiUnlockProtoPoolPage((ULONG_PTR)v21, PageIrql);
}
v21 = MiCheckProtoPtePageState((VOID *)SubsectionBase, &PageIrql);
ProtoPagePfn = (unsigned int)v21;
if( v21 )
break;
SubsectionBase = (SubsectionBase & 0xFFFFFFFFFFFFF000ui64) + 4096;
LABEL_60:
if( SubsectionBase >= (unsigned __int64)p_SubsectionBase )
goto LABEL_61;
}
while( 1 )
{
LABEL_24:
while( 1 )
{
v22.Long = *(unsigned __int64 *)SubsectionBase;
v23.u.Long = *(_QWORD *)SubsectionBase;
if( (*(_QWORD *)SubsectionBase & 1) == 0 )
break;
LABEL_32:
if( (MmGetPfnDb()[(v23.u.Long >> 12) & 0xFFFFFFFFFi64].u4._bf_0 & 0x4000000000000i64) != 0 )
{
v24 = &MmGetPfnDb()[(v23.u.Long >> 12) & 0xFFFFFFFFFi64];
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v24->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v24->u2._bf_0 < 0 );
}
if( *(_QWORD *)SubsectionBase == v22.Long )
{
if( !v24 )
{
LABEL_54:
SubsectionBase += 8i64;
LABEL_59:
LODWORD(v21) = ProtoPagePfn;
goto LABEL_60;
}
v25 = *(void **)SubsectionBase;
MiPteInShadowRange(SubsectionBase);
if( ((unsigned __int8)v25 & 1) != 0 )
goto LABEL_40;
if( (*(_DWORD *)(&v24->3 + 1) & 0x401) != 1024i64
|| (v24->PteLong | 0x8000000000000000ui64) != SubsectionBase )
{
KeBugCheckEx(0xDEu, (PVOID)2, (PVOID)SubsectionBase, v24->ListEntry.Blink, v25);
}
v26 = *((_BYTE *)&v24->u3 + 2);
if( (((v51 & 2) != 0) & (v26 >> 4)) != 0 )
{
LABEL_40:
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v15 = 0;
v38 = 0;
goto LABEL_41;
}
if( (v26 & 8) != 0 )
{
MiWaitForPageWriteCompletion(v24, (_CONTROL_AREA *)v11, ProtoPagePfn, PageIrql);
PageIrql = 17;
goto LABEL_59;
}
if( v19 && v24->u3.ReferenceCount )
*ExtentPagesActive = 1;
MiDeleteTransitionPte((_MMPTE *)SubsectionBase, v24, 0x11u, 1ui64);
if( *(_QWORD *)(v11 + 32) )
{
SubsectionBase += 8i64;
if( (SubsectionBase & 0x78) == 0 && (unsigned int)KeShouldYieldProcessor() )
{
MiUnlockProtoPoolPage(ProtoPagePfn, PageIrql);
PageIrql = 17;
}
goto LABEL_59;
}
LABEL_61:
v15 = v38;
LABEL_41:
if( PageIrql != 17 )
MiUnlockProtoPoolPage(ProtoPagePfn, PageIrql);
LABEL_43:
v27 = v19 == 0;
v28 = MappedSubsection;
if( !v27 )
MiSubsectionProtosCreated(&MappedSubsection->Core, (_MI_CONTROL_AREA_WAIT_BLOCK *)v47);
v50 = ExAcquireSpinLockExclusive((INT64 *)(v11 + 72));
v14 = v50;
MiDecrementSubsectionViewCount(MappedSubsection);
if( MappedSubsection->NumberOfMappedViews || (MappedSubsection->Core.u.SubsectionFlags._bf_2 & 1) != 0 )
{
v8 = v41;
}
else
{
LODWORD(v36) = MiInsertUnusedSubsection(MappedSubsection, v29);
v8 = v36 + v41;
v41 += v36;
}
LABEL_47:
if( v28 == (_MSUBSECTION *)FirstSubsection || !v15 )
goto LABEL_48;
NextSubsection = v28->Core.NextSubsection;
SubsectionBase = (UINT64)NextSubsection->SubsectionBase;
goto LABEL_11;
}
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
}
}
if( (*(_QWORD *)SubsectionBase & 0xC00i64) != 2048 )
goto LABEL_54;
if( !v22.Long || !*(&stru_140C4DB30 + 42) || (v22.Long & *(&stru_140C4DB30 + 42)) != 0 )
{
v23.u.Long = *(_QWORD *)SubsectionBase;
if( *(&stru_140C4DB30 + 42) && (v22.Long & 0x10) == 0 )
v23.u.Long = v22.Long & ~*(&stru_140C4DB30 + 42);
goto LABEL_32;
}
}
}
v28 = MappedSubsection;
if( MappedSubsection != (_MSUBSECTION *)FirstSubsection )
goto LABEL_47;
LABEL_48:
v30 = v38;
LABEL_49:
LODWORD(v31) = MiDecrementSubsections(LastSubsection[1], LastSubsection[1], 0i64);
v32 = v31 + v8;
LODWORD(v33) = MiDecrementSubsections((_SUBSECTION *)FirstSubsection, (_SUBSECTION *)FirstSubsection, 0i64);
--*(_QWORD *)(v11 + 40);
*(_DWORD *)(v11 + 56) &= ~4u;
v34 = v33 + v32;
if( v34 )
v35 = *(_MI_CROSS_PARTITION_CHARGES **)(*(&stru_140C4DB30 + 267) + 8i64 * (*(_WORD *)(v11 + 60) & 0x3FF));
else
v35 = 0i64;
MiCheckControlArea((_CONTROL_AREA *)v11, v14);
if( v34 )
MiReturnCrossPartitionSectionCharges(v35, 1i64, v34);
return v30;
}Referenced by:
CcPurgeCacheSection