MiUnlinkFreeOrZeroedPage
BOOL __fastcall MiUnlinkFreeOrZeroedPage(UINT64 Page, _MMPFNLIST *ColorHead, UINT8 *Flags){
char *v4;
int v5;
unsigned __int64 v6;
UINT8 *v7;
int v8;
int v9;
int v10;
int v11;
int v12;
_MMPFNLIST *v13;
__int64 v14;
__int64 v15;
int v16;
__int64 v17;
UINT8 *v18;
int v19;
int v20;
int v21;
volatile __int64 *p_Lock;
struct _KPRCB *CurrentPrcb;
KSPIN_LOCK_QUEUE *v24;
__int64 v25;
unsigned __int64 v26;
UINT64 v27;
volatile signed __int32 *v28;
unsigned int v29;
unsigned __int64 v30;
__int64 v31;
char *v32;
signed __int64 v33;
signed __int64 v34;
signed __int64 v35;
_MMPFN *PfnDb;
__int64 v37;
__int64 v38;
char *v39;
__int64 v40;
signed __int64 v41;
signed __int64 v42;
signed __int64 v43;
_KSPIN_LOCK_QUEUE *volatile Next;
unsigned __int64 v45;
unsigned __int64 v46;
__int64 v47;
int v48;
int v49;
__int64 v50;
unsigned __int64 v51;
INT64 updated;
unsigned int v53;
__int64 v55;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v57;
char v58;
__int16 v60;
unsigned int v61;
v60 = (__int16)Flags;
v57 = 0i64;
LockQueue = 0i64;
v4 = (char *)MmGetPfnDb() + 48 * Page;
v5 = 0;
v61 = v4[34] & 7;
v6 = (__int64)(48 * Page) / 48;
if( dword_140C4DBC4 <= (unsigned int)dword_140C4DBC8 )
{
v7 = &qword_140C4DC08[16 * dword_140C4DBC4];
if( v6 >= *(_QWORD *)v7 && (dword_140C4DBC4 == dword_140C4DBC8 || v6 < *((_QWORD *)v7 + 2)) )
goto LABEL_15;
}
v8 = 0;
v9 = dword_140C4DBC8;
if( dword_140C4DBC8 < 0 )
LABEL_117:
KeBugCheckEx(0x1Au, 0x6201ui64, v6, 0i64, 0i64);
while( 1 )
{
v10 = (v8 + v9) >> 1;
v7 = &qword_140C4DC08[16 * v10];
if( v6 < *(_QWORD *)v7 )
{
if( !v10 )
KeBugCheckEx(0x1Au, 0x6200ui64, v6, (ULONG_PTR)v7, 0i64);
v9 = v10 - 1;
goto LABEL_12;
}
if( v10 == dword_140C4DBC8 || v6 < *((_QWORD *)v7 + 2) )
break;
v8 = v10 + 1;
LABEL_12:
if( v9 < v8 )
goto LABEL_117;
}
dword_140C4DBC4 = (v8 + v9) >> 1;
LABEL_15:
v11 = *((_DWORD *)v7 + 2);
if( qword_140C4DC10 )
v12 = MiPageToChannel(v6);
else
v12 = 0;
v13 = ColorHead;
v14 = dword_140C4DC38 & (unsigned int)Page | (v11 << byte_140C4DBCC) | (v12 << byte_140C4DBCD);
v15 = *(_QWORD *)(qword_140C4E388 + 8 * ((*((_QWORD *)v4 + 5) >> 39) & 0x3FFi64));
if( ColorHead )
{
v21 = -1;
}
else
{
v16 = dword_140C4DBC8;
v17 = *(_QWORD *)(v15 + 8i64 * v61 + 2176);
if( dword_140C4DBC4 > (unsigned int)dword_140C4DBC8
|| (v18 = &qword_140C4DC08[16 * dword_140C4DBC4], Page < *(_QWORD *)v18)
|| dword_140C4DBC4 != dword_140C4DBC8 && Page >= *((_QWORD *)v18 + 2) )
{
v19 = 0;
if( dword_140C4DBC8 < 0 )
LABEL_119:
KeBugCheckEx(0x1Au, 0x6201ui64, Page, 0i64, 0i64);
while( 1 )
{
v20 = (v19 + v16) >> 1;
v18 = &qword_140C4DC08[16 * v20];
if( Page >= *(_QWORD *)v18 )
{
if( v20 == dword_140C4DBC8 || Page < *((_QWORD *)v18 + 2) )
{
dword_140C4DBC4 = (v19 + v16) >> 1;
break;
}
v19 = v20 + 1;
}
else
{
if( !v20 )
KeBugCheckEx(0x1Au, 0x6200ui64, Page, (ULONG_PTR)qword_140C4DC08, 0i64);
v16 = v20 - 1;
}
if( v16 < v19 )
goto LABEL_119;
}
}
v21 = *((_DWORD *)v18 + 2);
LockQueue.Next = 0i64;
v13 = (_MMPFNLIST *)(v17 + 40 * v14);
p_Lock = (volatile __int64 *)&v13->Lock;
ColorHead = v13;
LockQueue.Lock = &v13->Lock;
CurrentPrcb = KeGetCurrentPrcb();
if( *((_QWORD *)CurrentPrcb + 4247) && *((_BYTE *)CurrentPrcb + 32) <= 1u && *((_BYTE *)CurrentPrcb + 32) == 1 )
v13 = (_MMPFNLIST *)(v17 + 40 * v14);
v24 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64(p_Lock, (__int64)&LockQueue);
if( v24 )
{
KxWaitForLockOwnerShip(&LockQueue, v24);
v13 = ColorHead;
}
}
v25 = v61;
_InterlockedDecrement64(*(volatile signed __int64 **)(v15 + 8i64 * v61 + 4216));
if( dword_140C4E40C == 1 )
{
LOBYTE(v26) = 1;
v27 = Page & 0x1F;
v28 = (volatile signed __int32 *)(qword_140C4E468 + 4 * (Page >> 5));
if( v27 + 1 <= 0x20 )
{
v29 = 1 << v27;
goto LABEL_49;
}
if( (Page & 0x1F) == 0 )
goto LABEL_48;
_InterlockedOr(v28++, ((1 << (32 - (Page & 0x1F))) - 1) << v27);
v26 = 1i64 - (32 - (unsigned int)(Page & 0x1F));
if( v26 >= 0x20 )
{
v30 = v26 >> 5;
v26 += -32i64 * (v26 >> 5);
do
{
*v28++ = -1;
--v30;
}
while( v30 );
}
if( v26 )
{
LABEL_48:
v29 = (1 << v26) - 1;
LABEL_49:
_InterlockedOr(v28, v29);
}
v25 = v61;
}
--v13->Total;
if( v13->Flink == Page )
{
v31 = *(_QWORD *)v4 & 0xFFFFFFFFFi64;
v13->Flink = v31;
if( v31 == 0xFFFFFFFFFi64 )
{
_InterlockedAnd(
(volatile signed __int32 *)(*(_QWORD *)(*(_QWORD *)(v15 + 16)
+ 4544 * ((unsigned __int64)(unsigned int)v14 >> byte_140C4DBCC)
+ 16 * (v25 + 252)
+ 8)
+ 4 * ((unsigned __int64)((unsigned int)v14 & dword_140C4DC38) >> 5)),
~(1 << (v14 & dword_140C4DC38 & 0x1F)));
v13->Blink = 0xFFFFFFFFFi64;
}
else
{
v32 = (char *)MmGetPfnDb() + 48 * v31;
v33 = *((_QWORD *)v32 + 3);
v34 = _InterlockedCompareExchange64((volatile signed __int64 *)v32 + 3, v33 | 0xFFFFFFFFFi64, v33);
if( v33 != v34 )
{
do
{
v35 = v34;
v34 = _InterlockedCompareExchange64((volatile signed __int64 *)v32 + 3, v34 | 0xFFFFFFFFFi64, v34);
}
while( v35 != v34 );
}
}
}
else
{
PfnDb = MmGetPfnDb();
*((_QWORD *)PfnDb + 6 * (*((_QWORD *)v4 + 3) & 0xFFFFFFFFFi64)) ^= (*(_QWORD *)v4 ^ *((_QWORD *)PfnDb
+ 6
* (*((_QWORD *)v4 + 3) & 0xFFFFFFFFFi64))) & 0xFFFFFFFFFi64;
v37 = *((_QWORD *)v4 + 3);
v38 = *(_QWORD *)v4 & 0xFFFFFFFFFi64;
if( v38 == 0xFFFFFFFFFi64 )
{
ColorHead->Blink = v37 & 0xFFFFFFFFFi64;
}
else
{
v39 = (char *)PfnDb + 48 * v38;
v40 = v37 & 0xFFFFFFFFFi64;
v41 = *((_QWORD *)v39 + 3);
v42 = _InterlockedCompareExchange64((volatile signed __int64 *)v39 + 3, v40 | v41 & 0xFFFFFFF000000000ui64, v41);
if( v41 != v42 )
{
do
{
v43 = v42;
v42 = _InterlockedCompareExchange64(
(volatile signed __int64 *)v39 + 3,
v40 | v42 & 0xFFFFFFF000000000ui64,
v42);
}
while( v43 != v42 );
}
}
}
v4[34] = v4[34] & 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);
}
}
v45 = *(_QWORD *)(v15 + 16) + 4544 * ((unsigned __int64)(unsigned int)v14 >> byte_140C4DBCC);
_InterlockedDecrement64((volatile signed __int64 *)(v45 + 8i64 * v61 + 4128));
if( (unsigned int)MmNumberOfChannels > 1 )
_InterlockedDecrement64((volatile signed __int64 *)(v45
+ 8
* (v61
+ 2i64
* (unsigned __int8)(MiChannelMaximumPowerOf2Mask & ((unsigned int)v14 >> byte_140C4DBCD)))
+ 4216));
v46 = _InterlockedDecrement64((volatile signed __int64 *)(v15 + 7104));
if( v46 == *(_QWORD *)(v15 + 5168) || v46 == *(_QWORD *)(v15 + 5176) )
MiUpdateAvailableEvents((_MI_PARTITION *)v15);
if( v46 <= 0x420 )
{
v47 = *(_QWORD *)(v15 + 6848);
if( !v47 || !*(_BYTE *)(v47 + 52) )
MiObtainFreePages((_MI_PARTITION *)v15);
if( v46 < 0xA0 && v46 + 1 >= 0xA0 && *(_DWORD *)(v15 + 1160) )
KeSetEvent((PRKEVENT)(v15 + 1008), 0);
}
if( v46 < 0x9F )
{
if( (v60 & 0x2000) != 0 )
{
v48 = 1;
}
else
{
v49 = *((_DWORD *)KeGetCurrentThread() + 325);
if( (v49 & 0xC) == 8 )
{
v48 = 1;
}
else if( v46 < 0x20 && (ULONG_PTR *)v15 == &MiSystemPartition )
{
v48 = 0;
}
else if( (v60 & 4) != 0 )
{
v48 = 1;
}
else if( (v49 & 2) != 0 && v46 >= 0x21 )
{
v48 = 1;
}
else
{
v48 = (*(unsigned __int8 *)(v15 + 4) >> 5) & 1;
}
}
}
else
{
v48 = 1;
}
if( (v4[34] & 8) != 0 )
MiPageListCollision((INT64)v4);
v50 = qword_140C4DC80;
*((_QWORD *)v4 + 3) &= 0xFFFFFFF000000000ui64;
v51 = *((_QWORD *)v4 + 2);
*(_QWORD *)v4 = 0i64;
if( v50 && (v51 & 0x10) == 0 )
v51 &= ~v50;
if( HIDWORD(v51) == 4294967293 )
v5 = 2;
updated = ZeroPte;
v53 = v48 | v5;
*((_QWORD *)v4 + 2) = ZeroPte;
if( v53 >= 2 )
{
updated = MiUpdatePageFileHighInPte(ZeroPte, 4294967293i64);
*((_QWORD *)v4 + 2) = updated;
}
if( v61 == 1 || v58 == 1 )
{
if( updated )
{
*((_QWORD *)v4 + 2) = updated & 0xFFFFFFFFFFFFFC1Fui64 | 0x80;
return v53 & 1;
}
v55 = 128i64;
if( v50 )
{
if( (v50 & 0x80u) == 0i64 )
{
*((_QWORD *)v4 + 2) = v50 | 0x80;
return v53 & 1;
}
v55 = 144i64;
}
*((_QWORD *)v4 + 2) = v55;
return v53 & 1;
}
else
{
if( (MiFlags & 0x80u) != 0 && (++dword_140C4E50C & MmPageValidationFrequency) == 0 )
{
MiArePageContentsZero((PVOID)Page);
return v53 & 1;
}
return v53 & 1;
}
}Referenced by:
MiCoalesceFreePages
MiGetPage
MiGetPerfectColorHeadPage
MiPurgeZeroList
MiTradePage
MiTransferPartitionPageRun
MiZeroPage