MiDeleteSubsectionPages
NTSTATUS __stdcall MiDeleteSubsectionPages(_SUBSECTION *Subsection, UINT64 *DanglingPageCount){
_CONTROL_AREA *ControlArea;
_MSUBSECTION *v3;
UINT64 *v4;
__int64 v5;
unsigned __int64 Value;
NTSTATUS v7;
_MMPTE *SubsectionBase;
ULONG_PTR v9;
INT64 v10;
unsigned __int64 v11;
__int64 v12;
union {$8D9ED47C9F2F2CD645B633E301950288 __s0;unsigned __int64 EntireField;} *p_u4;
__int64 v14;
_MMPFN *PfnDb;
CHAR *v16;
INT64 v17;
__int64 v18;
_MMPFN *v19;
_MMPTE v20;
_MMPTE v21;
int v22;
_MMPFN *v23;
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;} v24;
_MI_PAGE_DELETE_RESULT v25;
_MMPTE v26;
__int64 v27;
UINT64 v28;
UINT64 v29;
unsigned __int64 v30;
PVOID v31;
NTSTATUS v33;
union {unsigned int LongFlags;_MMSECTION_FLAGS Flags;} v34;
char a2[12];
CHAR *v36;
_MMPTE PointerPte;
unsigned __int64 v38;
_MI_PARTITION *Partition;
unsigned __int64 v40;
PVOID P;
UINT64 *v43;
UINT8 PageIrql;
UINT64 SpinCount;
v43 = DanglingPageCount;
ControlArea = Subsection->ControlArea;
v3 = (_MSUBSECTION *)Subsection;
v4 = DanglingPageCount;
*(_QWORD *)&a2[4] = 0i64;
LOBYTE(DanglingPageCount) = 17;
v5 = ControlArea->u1.Flags._bf_0 & 0x3FF;
PageIrql = 17;
Partition = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v5);
Value = ControlArea->FilePointer.Value;
v7 = 0;
*(_QWORD *)a2 = Value != 0;
SubsectionBase = Subsection->SubsectionBase;
v9 = 0;
v10 = 0i64;
v40 = Value & 0xFFFFFFFFFFFFFFF0ui64;
v33 = 0;
v34.LongFlags = (unsigned int)ControlArea->u;
P = SubsectionBase;
if( !SubsectionBase )
goto LABEL_66;
v11 = (unsigned __int64)SubsectionBase;
v38 = (unsigned __int64)&SubsectionBase[v3->Core.PtesInSubsection];
if( (unsigned __int64)SubsectionBase >= v38 )
goto LABEL_66;
v12 = 0xFFFFFFFFFi64;
p_u4 = &MmGetPfnDb()->u4;
v14 = 0x4000000000000i64;
PfnDb = MmGetPfnDb();
v16 = 0i64;
do
{
v17 = v10;
if( (v11 & 0xFFF) != 0 )
{
if( (_BYTE)DanglingPageCount != 17 )
goto LABEL_17;
}
else if( (_BYTE)DanglingPageCount != 17 )
{
MiUnlockProtoPoolPage(v9, (UINT8)DanglingPageCount);
}
while( 1 )
{
if( (ControlArea->u.LongFlags & 0x20) == 0 )
{
LODWORD(v18) = MI_READ_PTE_LOCK_FREE((INT64)MmGetPteBase() + ((v11 >> 9) & 0x7FFFFFFFF8i64));
*(_QWORD *)&a2[4] = v18;
if( (v18 & 1) == 0 && (v18 & 0x400) != 0 && (v18 & 2) != 0 )
{
LOBYTE(DanglingPageCount) = 17;
v9 = 0;
PageIrql = 17;
v11 = (v11 & 0xFFFFFFFFFFFFF000ui64) + 4096;
goto LABEL_61;
}
}
v19 = MiLockProtoPoolPage((_MMPTE *)v11, &PageIrql);
v9 = (unsigned int)v19;
if( v19 )
break;
MmAccessFault(2ui64, (PVOID)v11, 0, 0i64);
}
PfnDb = MmGetPfnDb();
v12 = 0xFFFFFFFFFi64;
p_u4 = &PfnDb->u4;
v14 = 0x4000000000000i64;
while( 1 )
{
LABEL_17:
while( 1 )
{
v20.u.Long = *(_QWORD *)v11;
if( (*(_QWORD *)v11 & 1) == 0 )
break;
v21.u.Long = *(_QWORD *)v11;
LABEL_25:
DanglingPageCount = (UINT64 *)(6 * (v12 & (v21.u.Long >> 12)));
if( (v14 & p_u4[6 * (v12 & (v21.u.Long >> 12))]._bf_0) != 0 )
{
v23 = &PfnDb[v12 & (v21.u.Long >> 12)];
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)&v23->u2, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( v23->u2._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&v23->u2, 0x3Fui64) );
PfnDb = MmGetPfnDb();
v12 = 0xFFFFFFFFFi64;
p_u4 = &PfnDb->u4;
v14 = 0x4000000000000i64;
}
if( *(_QWORD *)v11 == v20.u.Long )
goto LABEL_33;
_InterlockedAnd64(&v23->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
}
}
if( (v20.u.Long & 0x400) != 0 || (v20.u.Long & 0x800) == 0 )
break;
LOBYTE(v22) = MiInvalidPteConforms(*(_QWORD *)v11, (INT64 *)DanglingPageCount);
if( v22 )
{
v21.u.Long = v20.u.Long;
if( *(&stru_140C4DB30 + 42) && (v20.u.Long & 0x10) == 0 )
v21.u.Long = v20.u.Long & ~*(&stru_140C4DB30 + 42);
goto LABEL_25;
}
}
v23 = 0i64;
LABEL_33:
v24.Long = *(unsigned __int64 *)v11;
*(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;} *)&a2[4] = (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;})v24.Long;
if( (v24.Long & 1) != 0 )
{
++v10;
if( v23->u3.ReferenceCount <= 2u )
v10 = v17;
if( (MI_READ_PTE_LOCK_FREE((INT64)&a2[4]) & 0x1FF000) == 0 )
{
MiSetLeafPfnBuddy(v23, (unsigned __int64)v16);
v16 = (CHAR *)v23;
}
_InterlockedAnd64(&v23->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
goto LABEL_58;
}
if( (v24.Long & 0x400) != 0 )
goto LABEL_58;
if( (v24.Long & 0x800) != 0 )
{
if( *(&stru_140C4DB30 + 42) && (v24.Long & 0x10) == 0 )
LOWORD(v24.Long) &= ~*(&stru_140C4DB30 + 168);
v7 = v33;
if( (*(_DWORD *)(&v23->3 + 1) & 0x400i64) != 0
&& (ControlArea->u.LongFlags & 0x20) == 0
&& (*(_BYTE *)(&v23->u3 + 1) & 0x18) != 0 )
{
v7 = ++v33;
}
if( !v40
&& (v24.Long & 0xF000) == 0
&& (__int64)((v38 - v11) & 0xFFFFFFFFFFFFFFF8ui64) >= 128
&& ((4096 - (v11 & 0xFFF)) & 0xFFFFFFF8) >= 0x80
&& MiDeleteClusterSection(v23, (_MMPTE *)v11) == 1 )
{
v4 = v43;
v11 += 128i64;
goto LABEL_60;
}
v25 = MiDeleteTransitionPte((_MMPTE *)v11, v23, 0x11u, 1ui64);
v4 = v43;
if( v25 == PageStillReferenced )
++*v43;
}
else
{
PointerPte.u.Long = v24.Long;
v26.u.Long = MiCapturePageFileInfoInline(&PointerPte, 0i64, 1ui64).u.Long;
PointerPte.u.Long = v26.u.Long;
if( v26.u.Long )
MiReleasePageFileInfo(Partition, v26, 0i64);
LABEL_58:
v4 = v43;
}
v7 = v33;
v11 += 8i64;
LABEL_60:
DanglingPageCount = (UINT64 *)PageIrql;
LABEL_61:
v12 = 0xFFFFFFFFFi64;
PfnDb = MmGetPfnDb();
v14 = 0x4000000000000i64;
p_u4 = &PfnDb->u4;
}
while( v11 < v38 );
v36 = v16;
v3 = (_MSUBSECTION *)Subsection;
if( (_BYTE)DanglingPageCount != 17 )
{
MiUnlockProtoPoolPage(v9, (UINT8)DanglingPageCount);
PageIrql = 17;
}
if( v36 )
{
LODWORD(v27) = MiDeleteSubsectionLargePages((INT64)Subsection, v36, v10);
*v4 += v27;
}
LABEL_66:
if( SLOBYTE(v34.LongFlags) >= 0 || (v34.LongFlags & 0x20) != 0 )
return v7;
LODWORD(v28) = MiDecrementSubsectionViewCount(v3);
v29 = v28;
v30 = (unsigned __int8)ExAcquireSpinLockExclusive((INT64 *)&ControlArea->ControlAreaLock);
while( v3->NumberOfPfnReferences )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&ControlArea->ControlAreaLock);
__writecr8(v30);
_mm_pause();
ExAcquireSpinLockExclusive((INT64 *)&ControlArea->ControlAreaLock);
}
v31 = P;
if( P )
{
MiUpdateSystemProtoPtesTree(&v3->ProtosNode.Node, 0i64);
v3->Core.SubsectionBase = 0i64;
}
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&ControlArea->ControlAreaLock);
__writecr8(v30);
if( v31 )
ExFreePoolWithTag(v31, 0);
if( v29 )
MiReturnCrossPartitionSectionCharges((_MI_CROSS_PARTITION_CHARGES *)Partition, *(unsigned int *)a2, v29);
return v33;
}Referenced by:
MiDeleteSegmentPages
MiExtendSection