MiDeleteBatch
NTSTATUS __stdcall MiDeleteBatch(_MI_DELETE_BATCH *DeleteBatch){
bool v1;
NTSTATUS result;
NTSTATUS v4;
unsigned __int64 v5;
_MI_PARTITION *v6;
unsigned __int8 v7;
_MMPFN *PfnDb;
_MMPTE *p_OriginalPte;
struct {unsigned __int16 ReferenceCount;} *v10;
unsigned __int64 v11;
_UNICODE_STRING *v12;
char ReferenceCount;
struct {unsigned __int16 ReferenceCount;} *v14;
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;} v15;
char v16;
_MIPFNBLINK *p_u2;
__int64 v18;
_UNICODE_STRING *v19;
UINT8 v20;
wchar_t *v21;
int v22;
__int64 v23;
unsigned __int64 v24;
unsigned __int8 i;
_MMPTE v26;
_KLOCK_QUEUE_HANDLE LockQueue;
UINT64 SpinCount;
INT64 v29;
v1 = *(_BYTE *)DeleteBatch == 0;
*(_QWORD *)&LockQueue.OldIrql = 0i64;
if( v1 )
return 0;
v4 = 0;
v29 = *((_QWORD *)DeleteBatch + 2);
LODWORD(v5) = MI_READ_PTE_LOCK_FREE((INT64)&v29);
v6 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267)
+ 8 * (((unsigned __int64)MmGetPfnDb()[(v5 >> 12) & 0xFFFFFFFFFi64].u4._bf_0 >> 39) & 0x3FF));
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = &v6->Vp.ModifiedPageListHead.Lock;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, &v6->Vp.ModifiedPageListHead.Lock);
v7 = 0;
if( *(_BYTE *)DeleteBatch )
{
PfnDb = MmGetPfnDb();
p_OriginalPte = &PfnDb->OriginalPte;
do
{
v29 = *(_QWORD *)&DeleteBatch[2 * v7 + 4];
v10 = &MmGetPfnDb()->u3 + 1;
v11 = 48 * (((unsigned __int64)v29 >> 12) & 0xFFFFFFFFFi64);
v12 = (_UNICODE_STRING *)&PfnDb[v11 / 0x30];
ReferenceCount = v10[v11 / 2].ReferenceCount;
v14 = &v10[v11 / 2];
if( (ReferenceCount & 7) != 6 )
MiBadShareCount();
v15.Long = 0i64;
if( (v29 & 0x42) != 0 && (ReferenceCount & 0x10) == 0 )
{
v16 = ReferenceCount;
if( (p_OriginalPte[v11 / 8].u.Long & 0x400) == 0 && (ReferenceCount & 8) == 0 )
{
v15.Long = MiCapturePageFileInfoInline(&p_OriginalPte[v11 / 8], 1ui64, 0i64).u.Long;
v16 = v14->ReferenceCount;
}
LOBYTE(v14->ReferenceCount) = v16 | 0x10;
}
*(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;} *)&DeleteBatch[2 * v7 + 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;})v15.Long;
p_u2 = &MmGetPfnDb()[v11 / 0x30].u2;
v18 = p_u2->_bf_0 ^ (p_u2->_bf_0 ^ (p_u2->_bf_0 - 1)) & 0x3FFFFFFFFFFFFFFFi64;
p_u2->_bf_0 = v18;
if( (v18 & 0x3FFFFFFFFFFFFFFFi64) == 0
&& MiPfnShareCountIsZero((_MMPFN *)v12, (_MMPFN *)1) == PageStillReferenced )
{
LOBYTE(v22) = MI_PFN_IS_PROTO(v12, v19, v20, v21);
if( !v22 )
++v4;
}
_InterlockedAnd64(&p_u2->Lock, 0x7FFFFFFFFFFFFFFFui64);
++v7;
p_OriginalPte = &MmGetPfnDb()->OriginalPte;
PfnDb = MmGetPfnDb();
}
while( v7 < *(_BYTE *)DeleteBatch );
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
v23 = *((_QWORD *)DeleteBatch + 1);
if( *((_BYTE *)DeleteBatch + 1) == 1 )
{
MiLockNestedPageAtDpcInline(*((_MMPFN **)DeleteBatch + 1));
}
else
{
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v23 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)(v23 + 24) < 0 );
}
}
if( (*(_BYTE *)(v23 + 34) & 7) != 6
|| (v24 = *(unsigned __int8 *)DeleteBatch, (*(_QWORD *)(v23 + 24) & 0x3FFFFFFFFFFFFFFFui64) < v24) )
{
MiBadShareCount();
}
*(_QWORD *)(v23 + 24) ^= (*(_QWORD *)(v23 + 24) ^ (*(_QWORD *)(v23 + 24) - v24)) & 0x3FFFFFFFFFFFFFFFi64;
_InterlockedAnd64((volatile signed __int64 *)(v23 + 24), 0x7FFFFFFFFFFFFFFFui64);
for( i = 0; i < *(_BYTE *)DeleteBatch; ++i )
{
v26.u.Long = *(_QWORD *)&DeleteBatch[2 * i + 4];
if( v26.u.Long )
MiReleasePageFileInfo(v6, v26, 1ui64);
}
result = v4;
*(_BYTE *)DeleteBatch = 0;
return result;
}Referenced by:
MiDeleteClusterPage
MiDeletePteRun