MiUnlinkFreeOrZeroedPage
NTSTATUS __stdcall MiUnlinkFreeOrZeroedPage(ULONG_PTR Page, _MMPFNLIST *ColorHead, UINT8 *Flags){
unsigned __int64 v3;
_MMPFN *v4;
int v5;
unsigned __int64 v6;
unsigned __int64 *v7;
int v8;
int v9;
int v10;
int v11;
NTSTATUS v12;
_MMPFNLIST *v13;
__int64 v14;
__int64 v15;
int v16;
__int64 v17;
__int64 v18;
int v19;
int v20;
int v21;
volatile __int64 *p_Lock;
struct _KPRCB *CurrentPrcb;
__int64 v24;
unsigned __int64 v25;
unsigned __int64 v26;
volatile signed __int32 *v27;
unsigned int v28;
unsigned __int64 v29;
__int64 v30;
_MMPFN *v31;
signed __int64 bf_0;
signed __int64 v33;
signed __int64 v34;
_MMPFN *PfnDb;
__int64 v36;
__int64 v37;
_MMPFN *v38;
__int64 v39;
signed __int64 v40;
signed __int64 v41;
signed __int64 v42;
_KSPIN_LOCK_QUEUE *volatile Next;
unsigned __int64 v44;
unsigned __int64 v45;
__int64 v46;
int v47;
int v48;
__int64 v49;
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;} v50;
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;} v51;
unsigned int v52;
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;} v53;
__int64 v55;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v57;
char v58;
__int16 v60;
unsigned int v61;
v60 = (__int16)Flags;
v57 = 0i64;
v3 = *(_QWORD *)&Page;
LockQueue = 0i64;
v4 = &MmGetPfnDb()[*(_QWORD *)&Page];
v5 = 0;
v61 = *(_BYTE *)(&v4->u3 + 1) & 7;
v6 = 48i64 * *(_QWORD *)&Page / 48;
if( *(&stru_140C4DB30 + 37) <= *(&stru_140C4DB30 + 38) )
{
v7 = (unsigned __int64 *)(*(&stru_140C4DB30 + 27) + 16i64 * *(&stru_140C4DB30 + 37));
if( v6 >= *v7 && (*(&stru_140C4DB30 + 37) == *(&stru_140C4DB30 + 38) || v6 < v7[2]) )
goto LABEL_15;
}
v8 = 0;
v9 = *(&stru_140C4DB30 + 38);
if( *(&stru_140C4DB30 + 38) < 0 )
LABEL_117:
KeBugCheckEx(0x1Au, (PVOID)0x6201, (PVOID)v6, 0i64, 0i64);
while( 1 )
{
v10 = (v8 + v9) >> 1;
v7 = (unsigned __int64 *)(*(&stru_140C4DB30 + 27) + 16i64 * v10);
if( v6 < *v7 )
{
if( !v10 )
KeBugCheckEx(0x1Au, (PVOID)0x6200, (PVOID)v6, v7, 0i64);
v9 = v10 - 1;
goto LABEL_12;
}
if( v10 == *(&stru_140C4DB30 + 38) || v6 < v7[2] )
break;
v8 = v10 + 1;
LABEL_12:
if( v9 < v8 )
goto LABEL_117;
}
*(&stru_140C4DB30 + 37) = (v8 + v9) >> 1;
LABEL_15:
v11 = *((_DWORD *)v7 + 2);
if( *(&stru_140C4DB30 + 28) )
v12 = MiPageToChannel(v6);
else
v12 = 0;
v13 = ColorHead;
v14 = *(&stru_140C4DB30 + 66) & (unsigned int)v3 | (v11 << *(&stru_140C4DB30 + 156)) | (v12 << *(&stru_140C4DB30 + 157));
v15 = *(_QWORD *)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v4->u4._bf_0 >> 39) & 0x3FF));
if( ColorHead )
{
v21 = -1;
}
else
{
v16 = *(&stru_140C4DB30 + 38);
v17 = *(_QWORD *)(v15 + 8i64 * v61 + 2176);
if( *(&stru_140C4DB30 + 37) > *(&stru_140C4DB30 + 38)
|| (v18 = *(&stru_140C4DB30 + 27) + 16i64 * *(&stru_140C4DB30 + 37), v3 < *(_QWORD *)v18)
|| *(&stru_140C4DB30 + 37) != *(&stru_140C4DB30 + 38) && v3 >= *(_QWORD *)(v18 + 16) )
{
v19 = 0;
if( *(&stru_140C4DB30 + 38) < 0 )
LABEL_119:
KeBugCheckEx(0x1Au, (PVOID)0x6201, (PVOID)v3, 0i64, 0i64);
while( 1 )
{
v20 = (v19 + v16) >> 1;
v18 = *(&stru_140C4DB30 + 27) + 16i64 * v20;
if( v3 >= *(_QWORD *)v18 )
{
if( v20 == *(&stru_140C4DB30 + 38) || v3 < *(_QWORD *)(v18 + 16) )
{
*(&stru_140C4DB30 + 37) = (v19 + v16) >> 1;
break;
}
v19 = v20 + 1;
}
else
{
if( !v20 )
KeBugCheckEx(0x1Au, (PVOID)0x6200, (PVOID)v3, *(&stru_140C4DB30 + 27), 0i64);
v16 = v20 - 1;
}
if( v16 < v19 )
goto LABEL_119;
}
}
v21 = *(_DWORD *)(v18 + 8);
LockQueue.Next = 0i64;
v13 = (_MMPFNLIST *)(v17 + 40 * v14);
p_Lock = (volatile __int64 *)&v13->Lock;
ColorHead = v13;
LockQueue.Lock = &v13->Lock;
CurrentPrcb = KeGetCurrentPrcb();
if( CurrentPrcb->SchedulerAssist && CurrentPrcb->NestingLevel <= 1u && CurrentPrcb->NestingLevel == 1 )
v13 = (_MMPFNLIST *)(v17 + 40 * v14);
if( _InterlockedExchange64(p_Lock, (__int64)&LockQueue) )
{
KxWaitForLockOwnerShip((INT64)&LockQueue);
v13 = ColorHead;
}
}
v24 = v61;
_InterlockedDecrement64(*(volatile signed __int64 **)(v15 + 8i64 * v61 + 4216));
if( *(&stru_140C4DB30 + 567) == 1 )
{
LOBYTE(v25) = 1;
v26 = v3 & 0x1F;
v27 = (volatile signed __int32 *)(*(&stru_140C4DB30 + 295) + 4 * (v3 >> 5));
if( v26 + 1 <= 0x20 )
{
v28 = 1 << v26;
goto LABEL_49;
}
if( (v3 & 0x1F) == 0 )
goto LABEL_48;
_InterlockedOr(v27++, ((1 << (32 - (v3 & 0x1F))) - 1) << v26);
v25 = 1i64 - (32 - (unsigned int)(v3 & 0x1F));
if( v25 >= 0x20 )
{
v29 = v25 >> 5;
v25 += -32i64 * (v25 >> 5);
do
{
*v27++ = -1;
--v29;
}
while( v29 );
}
if( v25 )
{
LABEL_48:
v28 = (1 << v25) - 1;
LABEL_49:
_InterlockedOr(v27, v28);
}
v24 = v61;
}
--v13->Total;
if( v13->Flink == v3 )
{
v30 = v4->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFi64;
v13->Flink = v30;
if( v30 == 0xFFFFFFFFFi64 )
{
_InterlockedAnd(
(volatile signed __int32 *)(*(_QWORD *)(*(_QWORD *)(v15 + 16)
+ 4544 * ((unsigned __int64)(unsigned int)v14 >> *(&stru_140C4DB30 + 156))
+ 16 * (v24 + 252)
+ 8)
+ 4 * ((unsigned __int64)((unsigned int)v14 & *(&stru_140C4DB30 + 66)) >> 5)),
~(1 << (v14 & *(&stru_140C4DB30 + 264) & 0x1F)));
v13->Blink = 0xFFFFFFFFFi64;
}
else
{
v31 = &MmGetPfnDb()[v30];
bf_0 = v31->u2._bf_0;
v33 = _InterlockedCompareExchange64(&v31->u2.Lock, bf_0 | 0xFFFFFFFFFi64, bf_0);
if( bf_0 != v33 )
{
do
{
v34 = v33;
v33 = _InterlockedCompareExchange64(&v31->u2.Lock, v33 | 0xFFFFFFFFFi64, v33);
}
while( v34 != v33 );
}
}
}
else
{
PfnDb = MmGetPfnDb();
PfnDb[v4->u2._bf_0 & 0xFFFFFFFFFi64].u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 ^= (v4->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 ^ PfnDb[v4->u2._bf_0 & 0xFFFFFFFFFi64].u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0) & 0xFFFFFFFFFi64;
v36 = v4->u2._bf_0;
v37 = v4->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFi64;
if( v37 == 0xFFFFFFFFFi64 )
{
ColorHead->Blink = v36 & 0xFFFFFFFFFi64;
}
else
{
v38 = &PfnDb[v37];
v39 = v36 & 0xFFFFFFFFFi64;
v40 = v38->u2._bf_0;
v41 = _InterlockedCompareExchange64(&v38->u2.Lock, v39 | v40 & 0xFFFFFFF000000000ui64, v40);
if( v40 != v41 )
{
do
{
v42 = v41;
v41 = _InterlockedCompareExchange64(&v38->u2.Lock, v39 | v41 & 0xFFFFFFF000000000ui64, v41);
}
while( v42 != v41 );
}
}
}
*((_BYTE *)&v4->u3 + 2) = *(_BYTE *)(&v4->u3 + 1) & 0xF8 | 5;
v58 = *(_BYTE *)(v15 + 4829);
if( v21 != -1 )
{
_m_prefetchw(&LockQueue);
Next = LockQueue.Next;
if( LockQueue.Next )
goto LABEL_66;
if( (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.Lock,
0i64,
(signed __int64)&LockQueue) != &LockQueue )
{
Next = KxWaitForLockChainValid(&LockQueue);
LABEL_66:
LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
}
}
v44 = *(_QWORD *)(v15 + 16) + 4544 * ((unsigned __int64)(unsigned int)v14 >> *(&stru_140C4DB30 + 156));
_InterlockedDecrement64((volatile signed __int64 *)(v44 + 8i64 * v61 + 4128));
if( (unsigned int)MmNumberOfChannels > 1 )
_InterlockedDecrement64((volatile signed __int64 *)(v44
+ 8
* (v61
+ 2i64
* (unsigned __int8)(MiChannelMaximumPowerOf2Mask & ((unsigned int)v14 >> *(&stru_140C4DB30 + 157))))
+ 4216));
v45 = _InterlockedDecrement64((volatile signed __int64 *)(v15 + 7104));
if( v45 == *(_QWORD *)(v15 + 5168) || v45 == *(_QWORD *)(v15 + 5176) )
MiUpdateAvailableEvents((_MI_PARTITION *)v15);
if( v45 <= 0x420 )
{
v46 = *(_QWORD *)(v15 + 6848);
if( !v46 || !*(_BYTE *)(v46 + 52) )
MiObtainFreePages((_MI_PARTITION *)v15);
if( v45 < 0xA0 && v45 + 1 >= 0xA0 && *(_DWORD *)(v15 + 1160) )
KeSetEvent((PRKEVENT)(v15 + 1008), 0, 0);
}
if( v45 < 0x9F )
{
if( (v60 & 0x2000) != 0 )
{
v47 = 1;
}
else
{
v48 = *(_DWORD *)&KeGetCurrentThread()[1].gapD8[12];
if( (v48 & 0xC) == 8 )
{
v47 = 1;
}
else if( v45 < 0x20 && (_MI_PARTITION *)v15 == &Irp )
{
v47 = 0;
}
else if( (v60 & 4) != 0 )
{
v47 = 1;
}
else if( (v48 & 2) != 0 && v45 >= 0x21 )
{
v47 = 1;
}
else
{
v47 = (*(unsigned __int8 *)(v15 + 4) >> 5) & 1;
}
}
}
else
{
v47 = 1;
}
if( (*(_BYTE *)(&v4->u3 + 1) & 8) != 0 )
MiPageListCollision(v4);
v49 = *(&stru_140C4DB30 + 42);
v4->u2._bf_0 &= 0xFFFFFFF000000000ui64;
v50.Long = (unsigned __int64)v4->OriginalPte.u;
v4->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
if( v49 && (v50.Long & 0x10) == 0 )
v50.Long &= ~v49;
if( HIDWORD(v50.Long) == 4294967293 )
v5 = 2;
v51.Long = ZeroPte.u.Long;
v52 = v47 | v5;
v4->OriginalPte = ZeroPte;
if( v52 >= 2 )
{
LODWORD(v53.Long) = MiUpdatePageFileHighInPte(ZeroPte.u.Hard._bf_0, 4294967293i64);
v51.Long = v53.Long;
v4->OriginalPte.u = (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;})v53.Long;
}
if( v61 == 1 || v58 == 1 )
{
if( v51.Long )
{
v4->OriginalPte.u.Long = v51.Long & 0xFFFFFFFFFFFFFC1Fui64 | 0x80;
return v52 & 1;
}
v55 = 128i64;
if( v49 )
{
if( (v49 & 0x80u) == 0i64 )
{
v4->OriginalPte.u.Long = v49 | 0x80;
return v52 & 1;
}
v55 = 144i64;
}
v4->OriginalPte.u.Long = v55;
return v52 & 1;
}
else
{
if( (MiFlags & 0x80u) != 0 && (++*(&stru_140C4DB30 + 631) & MmPageValidationFrequency) == 0 )
{
MiArePageContentsZero((PVOID)v3);
return v52 & 1;
}
return v52 & 1;
}
}Referenced by:
MiCoalesceFreePages
MiGetPage
MiGetPerfectColorHeadPage
MiPurgeZeroList
MiTradePage
MiTransferPartitionPageRun
MiZeroPage