MiUnlinkPageFromList
VOID __fastcall MiUnlinkPageFromList(_MMPFN *Pfn1, UINT64 LockHeld){
void *BugCheckParameter4;
unsigned __int64 EntireField;
__int64 v5;
__int64 v6;
wchar_t *v7;
unsigned int v8;
UINT64 v9;
unsigned int PfnPriority;
_UNICODE_STRING *v11;
UINT8 v12;
wchar_t *v13;
int v14;
unsigned int v15;
__int64 v16;
unsigned int v17;
int v18;
__int64 v19;
unsigned __int64 v20;
unsigned __int64 v21;
unsigned __int64 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;
unsigned __int64 v25;
_MMPFN *v26;
signed __int64 bf_0;
signed __int64 v28;
signed __int64 v29;
unsigned int v30;
void *v31;
_MMPFN *PfnDb;
unsigned int v33;
void *v34;
int v35;
int v36;
__int64 v37;
unsigned __int16 Long;
char v39;
__int64 v40;
int v41;
int v42;
__int64 v43;
int v44;
_MIPFNBLINK *p_u2;
volatile signed __int64 v46;
signed __int64 v47;
signed __int64 v48;
signed __int64 v49;
signed __int64 v50;
unsigned int v51;
_MMPFN *v52;
char v53;
__int64 v54;
int v55;
unsigned __int64 v56;
unsigned __int64 v57;
__int64 v58;
int v59;
int v60;
__int64 v61;
unsigned int v62;
__int64 v63;
_MMPFN *v64;
_QWORD *v65;
_MMPFN *v66;
signed __int64 v67;
unsigned __int64 v68;
signed __int64 v69;
signed __int64 v70;
_MMPFN *v71;
unsigned __int64 v72;
UINT64 v73;
unsigned __int64 v74;
volatile signed __int32 *v75;
int v76;
unsigned __int64 v77;
_KSPIN_LOCK_QUEUE *volatile Next;
unsigned __int64 v79;
__int64 v80;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v82;
int v83;
unsigned __int64 v84;
int v85;
v85 = LockHeld;
BugCheckParameter4 = (void *)Pfn1->u3.ReferenceCount;
v82 = 0i64;
LockQueue = 0i64;
if( (_WORD)BugCheckParameter4 )
{
if( (Pfn1->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64) != 0 )
KeBugCheckEx(0x4Eu, (PVOID)2, (PVOID)(Pfn1 - MmGetPfnDb()), *(&stru_140C50B28 + 852), BugCheckParameter4);
return;
}
EntireField = Pfn1->u4.EntireField;
v5 = *(_QWORD *)(*(&stru_140C4DB30 + 267) + 8 * ((EntireField >> 39) & 0x3FF));
v6 = *(_QWORD *)(v5 + 8i64 * (*(_BYTE *)(&Pfn1->u3 + 1) & 7) + 4216);
v7 = (wchar_t *)*(unsigned int *)(v6 + 8);
v83 = *(_DWORD *)(v6 + 8);
if( (*(_BYTE *)(&Pfn1->u3 + 1) & 7) == 5 )
{
MiUnlinkPageFromBadList(Pfn1);
return;
}
v8 = 65;
v9 = Pfn1 - MmGetPfnDb();
if( v9 < *(&stru_140C4DB30 + 374) || v9 >= *(&stru_140C4DB30 + 374) + 2048i64 )
{
if( *(&stru_140C50B28 + 4726) && _bittest64(*(&stru_140C50B28 + 756), v9 >> 9) )
v8 = 81;
}
else
{
v8 = 69;
}
if( (_DWORD)v7 == 2 )
{
if( (EntireField & 0x2000000000000i64) != 0 )
{
if( (*((_BYTE *)&Pfn1->u3 + 3) & 0x40) != 0 )
MiUnlinkPageFromBadList(Pfn1);
Pfn1->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
MiSetPfnBlink(Pfn1, 0i64, 1ui64);
return;
}
PfnPriority = MiGetPfnPriority(Pfn1);
v8 |= 2u;
v15 = PfnPriority;
if( (v8 & 4) == 0 || (v8 = (unsigned int)v11 & 0xFFFFFFBD, ((unsigned __int8)v11 & 4) == 0) )
{
if( (*((_BYTE *)&Pfn1->u3 + 3) & 8) != 0 )
v8 |= 8u;
}
v6 = v5 + 8 * (PfnPriority + 4 * (PfnPriority + 76i64));
if( (v8 & 0x10) != 0 )
{
if( Pfn1->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 >= 0 )
{
v17 = v8 & 0xFFFFFFBF;
}
else
{
LODWORD(v16) = MiGetSlabAllocatorStandbyList((INT64)Pfn1, 0i64);
v14 = v85;
v6 = v16;
v17 = v8 | 0x20;
}
v8 = v17 & 0xFFFFFFFD;
}
if( (v8 & 2) != 0 )
{
LOBYTE(v18) = MI_PFN_IS_PROTO((_UNICODE_STRING *)Pfn1, v11, v12, v13);
if( v18 )
_InterlockedDecrement64((volatile signed __int64 *)(v5 + 4352));
else
_InterlockedDecrement64((volatile signed __int64 *)(v5 + 5056));
}
if( !v14 )
{
LockQueue.Next = 0i64;
LockQueue.Lock = (unsigned __int64 *volatile)(v6 + 32);
if( _InterlockedExchange64((volatile __int64 *)(v6 + 32), (__int64)&LockQueue) )
KxWaitForLockOwnerShip((INT64)&LockQueue);
}
v19 = 0xFFFFFFFFFi64;
v20 = Pfn1->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFi64;
v21 = Pfn1->u2._bf_0 & 0xFFFFFFFFFi64;
if( (v8 & 8) == 0 )
{
if( v20 == 0xFFFFFFFFFi64 || v20 >= *(&stru_140C4DB30 + 374) && v20 < *(&stru_140C4DB30 + 374) + 2048i64 )
{
PfnDb = MmGetPfnDb();
}
else
{
v30 = MiGetPfnPriority(&MmGetPfnDb()[v20]);
if( v15 != v30 )
KeBugCheckEx(0x1Au, (PVOID)0x8886, Pfn1, v31, (PVOID)(v30 | (unsigned __int64)(v15 << 8)));
}
if( v21 != v19 && (v21 < *(&stru_140C4DB30 + 374) || v21 >= *(&stru_140C4DB30 + 374) + 2048i64) )
{
v33 = MiGetPfnPriority(&PfnDb[v21]);
if( v15 != v33 )
KeBugCheckEx(0x1Au, (PVOID)0x8887, Pfn1, v34, (PVOID)(v33 | (unsigned __int64)(v15 << 8)));
}
goto LABEL_56;
}
v22 = *(&stru_140C4DB30 + 374);
if( v20 >= *(&stru_140C4DB30 + 374) && v20 < *(&stru_140C4DB30 + 374) + 2048i64 && v21 == v20 )
{
MiDeleteParentDecayNode(Pfn1);
LABEL_55:
v19 = 0xFFFFFFFFFi64;
v20 = 0xFFFFFFFFFi64;
v21 = 0xFFFFFFFFFi64;
LABEL_56:
if( v15 < *(unsigned __int8 *)(v5 + 4828) && (v8 & 0x20) == 0 )
v8 &= ~1u;
goto LABEL_90;
}
v23 = &MmGetPfnDb()[v21];
if( v21 < *(&stru_140C4DB30 + 374) || v21 >= *(&stru_140C4DB30 + 374) + 2048i64 )
{
v23->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = v20 | v23->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFF000000000ui64;
goto LABEL_50;
}
v24.Long = (unsigned __int64)v23->OriginalPte.u;
if( *(&stru_140C4DB30 + 42) )
{
if( (v24.Long & 0x10) != 0 )
v24.Long &= ~0x10ui64;
else
v24.Long &= ~*(&stru_140C4DB30 + 42);
}
v25 = v24.Long & 0xFFFF000000000FFFui64 | (v20 << 12);
if( *(&stru_140C4DB30 + 42) )
{
if( (*(&stru_140C4DB30 + 42) & v25) == 0 )
{
v23->OriginalPte.u.Long = *(&stru_140C4DB30 + 42) | v25;
LABEL_50:
v26 = &MmGetPfnDb()[v20];
if( v20 < v22 || v20 >= v22 + 2048 )
{
bf_0 = v26->u2._bf_0;
v28 = _InterlockedCompareExchange64(&v26->u2.Lock, v21 | bf_0 & 0xFFFFFFF000000000ui64, bf_0);
if( bf_0 != v28 )
{
do
{
v29 = v28;
v28 = _InterlockedCompareExchange64(&v26->u2.Lock, v21 | v28 & 0xFFFFFFF000000000ui64, v28);
}
while( v29 != v28 );
}
}
else
{
v26->u4._bf_0 = v21 | v26->u4._bf_0 & 0xFFFFFFF000000000ui64;
}
goto LABEL_55;
}
v25 |= 0x10ui64;
}
v23->OriginalPte.u.Long = v25;
goto LABEL_50;
}
if( (_DWORD)v7 == 3 )
{
_InterlockedDecrement64((volatile signed __int64 *)v6);
LOBYTE(v35) = MI_PFN_IS_PROTO((_UNICODE_STRING *)Pfn1, (_UNICODE_STRING *)v8, EntireField, v7);
v37 = 4352i64;
if( !v35 )
v37 = 5056i64;
_InterlockedDecrement64((volatile signed __int64 *)(v37 + v5));
if( (*(_DWORD *)(&Pfn1->3 + 1) & 0x400i64) != 0 )
{
v6 = v5 + 8 * ((Pfn1->ViewCount & 0xF) + 4 * ((Pfn1->ViewCount & 0xF) + 108i64));
if( !v36 )
{
LockQueue.Next = 0i64;
LockQueue.Lock = (unsigned __int64 *volatile)(v6 + 32);
if( _InterlockedExchange64((volatile __int64 *)(v6 + 32), (__int64)&LockQueue) )
KxWaitForLockOwnerShip((INT64)&LockQueue);
}
Pfn1->ViewCount &= 0xF0u;
}
else
{
if( !v36 )
{
LockQueue.Next = 0i64;
LockQueue.Lock = (unsigned __int64 *volatile)(v6 + 32);
if( _InterlockedExchange64((volatile __int64 *)(v6 + 32), (__int64)&LockQueue) )
KxWaitForLockOwnerShip((INT64)&LockQueue);
}
--*(_QWORD *)(v5 + 7600);
Long = Pfn1->OriginalPte.u.Long;
v39 = (unsigned __int8)Long >> 1;
v40 = Long >> 12;
if( (v39 & 1) != 0 || (_DWORD)v40 == *(_DWORD *)(v5 + 1156) )
v6 = v5 + 8 * (v40 + 4 * (v40 + 88));
else
v6 = v5 + 2752;
}
}
else
{
LOBYTE(v41) = MI_PFN_IS_PROTO((_UNICODE_STRING *)Pfn1, (_UNICODE_STRING *)v8, EntireField, v7);
v43 = 4352i64;
if( !v41 )
v43 = 5056i64;
_InterlockedDecrement64((volatile signed __int64 *)(v43 + v5));
if( !v42 )
{
LockQueue.Next = 0i64;
LockQueue.Lock = (unsigned __int64 *volatile)(v6 + 32);
KxAcquireQueuedSpinLock(&LockQueue, (UINT64 *)(v6 + 32));
}
}
v19 = 0xFFFFFFFFFi64;
v20 = Pfn1->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFi64;
v21 = Pfn1->u2._bf_0 & 0xFFFFFFFFFi64;
LABEL_90:
if( v20 == v19 )
{
v44 = v83;
v51 = v8 >> 3;
if( (v8 & 8) == 0 )
*(_QWORD *)(v6 + 24) = v21;
}
else
{
v44 = v83;
p_u2 = &MmGetPfnDb()[v20].u2;
v46 = p_u2->_bf_0;
v47 = _InterlockedCompareExchange64(&p_u2->Lock, v21 | p_u2->_bf_0 & 0xFFFFFFF000000000ui64, p_u2->_bf_0);
v48 = v47;
if( v44 == 2 )
{
if( v46 != v47 )
{
do
{
v49 = v48;
v48 = _InterlockedCompareExchange64(&p_u2->Lock, v21 | v48 & 0xFFFFFFF000000000ui64, v48);
}
while( v49 != v48 );
}
}
else if( v46 != v47 )
{
do
{
v50 = v48;
v48 = _InterlockedCompareExchange64(&p_u2->Lock, v21 | v48 & 0xFFFFFFF000000000ui64, v48);
}
while( v50 != v48 );
}
v19 = 0xFFFFFFFFFi64;
v51 = v8 >> 3;
}
if( v21 == v19 )
{
if( (v51 & 1) == 0 )
*(_QWORD *)(v6 + 16) = v20;
}
else
{
v52 = &MmGetPfnDb()[v21];
v52->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = v20 | v52->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFF000000000ui64;
}
if( v8 >= 0x40 )
--*(_QWORD *)v6;
if( v44 == 2 && (v8 & 0x14) == 0 )
{
v53 = *((_BYTE *)&Pfn1->u3 + 3);
if( (v53 & 8) != 0 )
v54 = 5i64;
else
v54 = v53 & 7;
v55 = *(&stru_140C4DB30 + 38);
v56 = Pfn1->ViewCount | ((unsigned __int64)Pfn1->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 >> 28) & 0xFFFFFFF00i64;
v57 = ((unsigned __int64)Pfn1->u2._bf_0 >> 20) & 0xFFFFF0000i64 | Pfn1->NodeBlinkLow;
v84 = v57;
if( *(&stru_140C4DB30 + 37) > *(&stru_140C4DB30 + 38)
|| (v58 = *(&stru_140C4DB30 + 27) + 16i64 * *(&stru_140C4DB30 + 37), v9 < *(_QWORD *)v58)
|| *(&stru_140C4DB30 + 37) != *(&stru_140C4DB30 + 38) && v9 >= *(_QWORD *)(v58 + 16) )
{
v59 = 0;
if( *(&stru_140C4DB30 + 38) < 0 )
LABEL_171:
KeBugCheckEx(0x1Au, (PVOID)0x6201, (PVOID)v9, 0i64, 0i64);
while( 1 )
{
v60 = (v59 + v55) >> 1;
v58 = *(&stru_140C4DB30 + 27) + 16i64 * v60;
if( v9 >= *(_QWORD *)v58 )
{
if( v60 == *(&stru_140C4DB30 + 38) || v9 < *(_QWORD *)(v58 + 16) )
{
*(&stru_140C4DB30 + 37) = (v59 + v55) >> 1;
break;
}
v59 = v60 + 1;
}
else
{
if( !v60 )
KeBugCheckEx(0x1Au, (PVOID)0x6200, (PVOID)v9, *(&stru_140C4DB30 + 27), 0i64);
v55 = v60 - 1;
}
if( v55 < v59 )
goto LABEL_171;
}
}
v61 = *(_QWORD *)(*(_QWORD *)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)Pfn1->u4._bf_0 >> 39) & 0x3FF))
+ 16i64)
+ 4544i64 * *(unsigned int *)(v58 + 8);
if( *(&stru_140C4DB30 + 28) )
{
v62 = MiPageToChannel(v9);
v57 = v84;
}
else
{
v62 = 0;
}
v63 = v54 + 8i64 * v62;
v64 = MmGetPfnDb();
v65 = (_QWORD *)(v61 + 24 * v63);
if( v56 == 0xFFFFFFFFFi64 )
{
v65[409] = v57;
}
else
{
v66 = &v64[v56];
v66->NodeBlinkLow = v57;
v67 = v66->u2._bf_0;
v68 = (v57 & 0xFFFFFFFFFFFF0000ui64) << 20;
v69 = _InterlockedCompareExchange64(&v66->u2.Lock, v68 | v67 & 0xFF00000FFFFFFFFFui64, v67);
if( v67 != v69 )
{
do
{
v70 = v69;
v69 = _InterlockedCompareExchange64(&v66->u2.Lock, v68 | v69 & 0xFF00000FFFFFFFFFui64, v69);
}
while( v70 != v69 );
}
v57 = v84;
}
if( v57 == 0xFFFFFFFFFi64 )
{
v65[408] = v56;
}
else
{
v71 = &v64[v57];
v72 = v71->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 ^ (v56 << 28);
v71->ViewCount = v56;
v71->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = (v56 << 28) ^ v72 & 0xFFFFFFFFFi64;
}
--v65[407];
if( (v8 & 8) != 0 )
*((_BYTE *)&Pfn1->u3 + 3) &= ~8u;
}
Pfn1->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
if( (v8 & 4) != 0 )
{
MiSetPfnBlink(Pfn1, 0i64, 0i64);
}
else
{
Pfn1->u2._bf_0 &= 0xFFFFFFF000000000ui64;
if( (Pfn1->u4._bf_0 & 0x2000000000000i64) == 0 && *(&stru_140C4DB30 + 567) == 1 )
{
v73 = v9 & 0x1F;
LOBYTE(v74) = 1;
v75 = (volatile signed __int32 *)(*(&stru_140C4DB30 + 295) + 4 * (v9 >> 5));
if( v73 + 1 > 0x20 )
{
if( (v9 & 0x1F) == 0 )
goto LABEL_148;
v76 = v9 & 0x1F;
_InterlockedOr(v75++, ((1 << (32 - v76)) - 1) << v73);
v74 = 1i64 - (unsigned int)(32 - v76);
if( v74 >= 0x20 )
{
v77 = v74 >> 5;
v74 += -32i64 * (v74 >> 5);
do
{
*v75++ = -1;
--v77;
}
while( v77 );
}
if( v74 )
LABEL_148:
_InterlockedOr(v75, (1 << v74) - 1);
}
else
{
_InterlockedOr(v75, 1 << v73);
}
}
}
if( v85 )
goto LABEL_155;
_m_prefetchw(&LockQueue);
Next = LockQueue.Next;
if( !LockQueue.Next )
{
if( (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.Lock,
0i64,
(signed __int64)&LockQueue) == &LockQueue )
goto LABEL_155;
Next = KxWaitForLockChainValid(&LockQueue);
}
LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
LABEL_155:
if( (v8 & 2) != 0 )
{
v79 = _InterlockedDecrement64((volatile signed __int64 *)(v5 + 7104));
if( v79 == *(_QWORD *)(v5 + 5168) || v79 == *(_QWORD *)(v5 + 5176) )
MiUpdateAvailableEvents((_MI_PARTITION *)v5);
if( v79 <= 0x420 )
{
v80 = *(_QWORD *)(v5 + 6848);
if( !v80 || !*(_BYTE *)(v80 + 52) )
MiObtainFreePages((_MI_PARTITION *)v5);
if( v79 < 0xA0 && v79 + 1 >= 0xA0 && *(_DWORD *)(v5 + 1160) )
KeSetEvent((PRKEVENT)(v5 + 1008), 0, 0);
}
}
}Referenced by:
MiActOnPte
MiBuildReservationCluster
MiConvertStandbyToProto
MiCopyDataPageToImagePage
MiDecayPfnFullyInitialized
MiDeleteClusterSection
MiDeleteParentDecayNode
MiDeleteTransitionPte
MiEmptyDecayClusterTimers
MiEnableLargeSubsection
MiFlushSectionInternal
MiFreeModifiedReservations
MiFreeSlabEntries
MiGatherMappedPages
MiGetSlabStandbyPage
MiHandleForkTransitionPte
MiHandleTransitionFault
MiMakeOutswappedPageResident
MiMarkFileOnlyPfnBad
MiMirrorPerformBrownWrites
MiNoPagesLastChance
MiOutSwapWorkingSetPte
MiPurgeImageSection
MiPurgeSubsection
MiReferencePageForModifiedWrite
MiRemoveLowestPriorityStandbyPage
MiReplaceTransitionPage
MiReservePageFileSpaceForPage
MiResolveProtoCombine
MiReuseStandbyPage
MiUnlinkStandbyBatch
MiUnlinkStandbyPfn
MiWalkEntireImage
MiWalkResetCommitPte
MiZeroCfgSystemWideBitmapWorker
MmCheckCachedPageStates