MiUnlinkPageFromList
UINT64 __stdcall MiUnlinkPageFromList(_MMPFN *Pfn1, UINT64 LockHeld){
ULONG_PTR BugCheckParameter4;
unsigned __int64 v5;
__int64 v6;
INT64 v7;
WCHAR *v8;
unsigned int v9;
unsigned __int64 v10;
unsigned int PfnPriority;
UNICODE_STRING *v12;
UINT8 v13;
WCHAR *v14;
int v15;
unsigned int v16;
INT64 SlabAllocatorStandbyList;
unsigned int v18;
int v19;
KSPIN_LOCK_QUEUE *v20;
__int64 v21;
unsigned __int64 v22;
unsigned __int64 v23;
ULONG_PTR v24;
unsigned __int64 *v25;
unsigned __int64 v26;
unsigned __int64 v27;
char *v28;
signed __int64 v29;
signed __int64 v30;
signed __int64 v31;
unsigned int v32;
ULONG_PTR v33;
_MMPFN *PfnDb;
unsigned int v35;
ULONG_PTR v36;
int v37;
int v38;
__int64 v39;
KSPIN_LOCK_QUEUE *v40;
unsigned __int16 v41;
char v42;
__int64 v43;
KSPIN_LOCK_QUEUE *v44;
int v45;
WORK_QUEUE_TYPE v46;
void *v47;
int v48;
__int64 v49;
int v50;
volatile signed __int64 *v51;
volatile signed __int64 v52;
signed __int64 v53;
signed __int64 v54;
signed __int64 v55;
signed __int64 v56;
unsigned int v57;
unsigned __int64 *v58;
char v59;
__int64 v60;
int v61;
__int64 v62;
__int64 v63;
UINT8 *v64;
int v65;
int v66;
__int64 v67;
unsigned int v68;
__int64 v69;
_MMPFN *v70;
_QWORD *v71;
char *v72;
signed __int64 v73;
unsigned __int64 v74;
signed __int64 v75;
signed __int64 v76;
char *v77;
__int64 v78;
unsigned __int64 v79;
unsigned __int64 v80;
volatile signed __int32 *v81;
int v82;
unsigned __int64 v83;
volatile signed __int64 *Flink;
unsigned __int64 v85;
__int64 v86;
int v87;
struct _IO_WORKITEM LockQueue;
int v89;
__int64 v90;
int v91;
v91 = LockHeld;
BugCheckParameter4 = *((unsigned __int16 *)Pfn1 + 16);
memset(&LockQueue, 0, 24);
if( (_WORD)BugCheckParameter4 )
{
if( (*((_QWORD *)Pfn1 + 3) & 0x3FFFFFFFFFFFFFFFi64) != 0 )
KeBugCheckEx(0x4Eu, 2ui64, (Pfn1 - MmGetPfnDb()) / 48, HighestPhysicalPage, BugCheckParameter4);
return 1i64;
}
v5 = *((_QWORD *)Pfn1 + 5);
v6 = *(_QWORD *)(qword_140C4E388 + 8 * ((v5 >> 39) & 0x3FF));
v7 = *(_QWORD *)(v6 + 8i64 * (*((_BYTE *)Pfn1 + 34) & 7) + 4216);
v8 = (WCHAR *)*(unsigned int *)(v7 + 8);
v89 = *(_DWORD *)(v7 + 8);
if( (*((_BYTE *)Pfn1 + 34) & 7) == 5 )
{
MiUnlinkPageFromBadList((_RTL_ATOM_TABLE *)Pfn1);
return 1i64;
}
v9 = 65;
v10 = (Pfn1 - MmGetPfnDb()) / 48;
if( v10 < BasePage || v10 >= BasePage + 2048 )
{
if( byte_140C51D9E && _bittest64((const signed __int64 *)qword_140C522C8, v10 >> 9) )
v9 = 81;
}
else
{
v9 = 69;
}
if( (_DWORD)v8 == 2 )
{
if( (v5 & 0x2000000000000i64) != 0 )
{
if( (*((_BYTE *)Pfn1 + 35) & 0x40) != 0 )
MiUnlinkPageFromBadList((_RTL_ATOM_TABLE *)Pfn1);
*(_QWORD *)Pfn1 = 0i64;
MiSetPfnBlink(Pfn1, 0i64, 1ui64);
return 1i64;
}
PfnPriority = MiGetPfnPriority((INT64)Pfn1);
v9 |= 2u;
v16 = PfnPriority;
if( (v9 & 4) == 0 || (v9 = (unsigned int)v12 & 0xFFFFFFBD, ((unsigned __int8)v12 & 4) == 0) )
{
if( (*((_BYTE *)Pfn1 + 35) & 8) != 0 )
v9 |= 8u;
}
v7 = v6 + 8 * (PfnPriority + 4 * (PfnPriority + 76i64));
if( (v9 & 0x10) != 0 )
{
if( *(_QWORD *)Pfn1 >= 0 )
{
v18 = v9 & 0xFFFFFFBF;
}
else
{
SlabAllocatorStandbyList = MiGetSlabAllocatorStandbyList((INT64)Pfn1, 0i64);
v15 = v91;
v7 = SlabAllocatorStandbyList;
v18 = v9 | 0x20;
}
v9 = v18 & 0xFFFFFFFD;
}
if( (v9 & 2) != 0 )
{
LOBYTE(v19) = MI_PFN_IS_PROTO((UNICODE_STRING *)Pfn1, v12, v13, v14);
if( v19 )
_InterlockedDecrement64((volatile signed __int64 *)(v6 + 4352));
else
_InterlockedDecrement64((volatile signed __int64 *)(v6 + 5056));
}
if( !v15 )
{
LockQueue.WorkItem.List.Flink = 0i64;
LockQueue.WorkItem.List.Blink = (_LIST_ENTRY *)(v7 + 32);
v20 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)(v7 + 32), (__int64)&LockQueue);
if( v20 )
KxWaitForLockOwnerShip((KSPIN_LOCK_QUEUE *)&LockQueue, v20);
}
v21 = 0xFFFFFFFFFi64;
v22 = *(_QWORD *)Pfn1 & 0xFFFFFFFFFi64;
v23 = *((_QWORD *)Pfn1 + 3) & 0xFFFFFFFFFi64;
if( (v9 & 8) == 0 )
{
if( v22 == 0xFFFFFFFFFi64 || v22 >= BasePage && v22 < BasePage + 2048 )
{
PfnDb = MmGetPfnDb();
}
else
{
v32 = MiGetPfnPriority((INT64)MmGetPfnDb() + 48 * v22);
if( v16 != v32 )
KeBugCheckEx(0x1Au, 0x8886ui64, (ULONG_PTR)Pfn1, v33, v32 | (unsigned __int64)(v16 << 8));
}
if( v23 != v21 && (v23 < BasePage || v23 >= BasePage + 2048) )
{
v35 = MiGetPfnPriority((INT64)PfnDb + 48 * v23);
if( v16 != v35 )
KeBugCheckEx(0x1Au, 0x8887ui64, (ULONG_PTR)Pfn1, v36, v35 | (unsigned __int64)(v16 << 8));
}
goto LABEL_56;
}
v24 = BasePage;
if( v22 >= BasePage && v22 < BasePage + 2048 && v23 == v22 )
{
MiDeleteParentDecayNode(Pfn1);
LABEL_55:
v21 = 0xFFFFFFFFFi64;
v22 = 0xFFFFFFFFFi64;
v23 = 0xFFFFFFFFFi64;
LABEL_56:
if( v16 < *(unsigned __int8 *)(v6 + 4828) && (v9 & 0x20) == 0 )
v9 &= ~1u;
goto LABEL_90;
}
v25 = (unsigned __int64 *)((char *)MmGetPfnDb() + 48 * v23);
if( v23 < BasePage || v23 >= BasePage + 2048 )
{
*v25 = v22 | *v25 & 0xFFFFFFF000000000ui64;
goto LABEL_50;
}
v26 = v25[2];
if( qword_140C4DC80 )
{
if( (v26 & 0x10) != 0 )
v26 &= ~0x10ui64;
else
v26 &= ~qword_140C4DC80;
}
v27 = v26 & 0xFFFF000000000FFFui64 | (v22 << 12);
if( qword_140C4DC80 )
{
if( (qword_140C4DC80 & v27) == 0 )
{
v25[2] = qword_140C4DC80 | v27;
LABEL_50:
v28 = (char *)MmGetPfnDb() + 48 * v22;
if( v22 < v24 || v22 >= v24 + 2048 )
{
v29 = *((_QWORD *)v28 + 3);
v30 = _InterlockedCompareExchange64(
(volatile signed __int64 *)v28 + 3,
v23 | v29 & 0xFFFFFFF000000000ui64,
v29);
if( v29 != v30 )
{
do
{
v31 = v30;
v30 = _InterlockedCompareExchange64(
(volatile signed __int64 *)v28 + 3,
v23 | v30 & 0xFFFFFFF000000000ui64,
v30);
}
while( v31 != v30 );
}
}
else
{
*((_QWORD *)v28 + 5) = v23 | *((_QWORD *)v28 + 5) & 0xFFFFFFF000000000ui64;
}
goto LABEL_55;
}
v27 |= 0x10ui64;
}
v25[2] = v27;
goto LABEL_50;
}
if( (_DWORD)v8 == 3 )
{
_InterlockedDecrement64((volatile signed __int64 *)v7);
LOBYTE(v37) = MI_PFN_IS_PROTO((UNICODE_STRING *)Pfn1, (UNICODE_STRING *)v9, v5, v8);
v39 = 4352i64;
if( !v37 )
v39 = 5056i64;
_InterlockedDecrement64((volatile signed __int64 *)(v39 + v6));
if( (*((_DWORD *)Pfn1 + 4) & 0x400i64) != 0 )
{
v7 = v6 + 8 * ((*((_BYTE *)Pfn1 + 39) & 0xF) + 4 * ((*((_BYTE *)Pfn1 + 39) & 0xF) + 108i64));
if( !v38 )
{
LockQueue.WorkItem.List.Flink = 0i64;
LockQueue.WorkItem.List.Blink = (_LIST_ENTRY *)(v7 + 32);
v44 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)(v7 + 32), (__int64)&LockQueue);
if( v44 )
KxWaitForLockOwnerShip((KSPIN_LOCK_QUEUE *)&LockQueue, v44);
}
*((_BYTE *)Pfn1 + 39) &= 0xF0u;
}
else
{
if( !v38 )
{
LockQueue.WorkItem.List.Flink = 0i64;
LockQueue.WorkItem.List.Blink = (_LIST_ENTRY *)(v7 + 32);
v40 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)(v7 + 32), (__int64)&LockQueue);
if( v40 )
KxWaitForLockOwnerShip((KSPIN_LOCK_QUEUE *)&LockQueue, v40);
}
--*(_QWORD *)(v6 + 7600);
v41 = *((_QWORD *)Pfn1 + 2);
v42 = (unsigned __int8)v41 >> 1;
v43 = v41 >> 12;
if( (v42 & 1) != 0 || (_DWORD)v43 == *(_DWORD *)(v6 + 1156) )
v7 = v6 + 8 * (v43 + 4 * (v43 + 88));
else
v7 = v6 + 2752;
}
}
else
{
LOBYTE(v45) = MI_PFN_IS_PROTO((UNICODE_STRING *)Pfn1, (UNICODE_STRING *)v9, v5, v8);
v49 = 4352i64;
if( !v45 )
v49 = 5056i64;
_InterlockedDecrement64((volatile signed __int64 *)(v49 + v6));
if( !v48 )
{
LockQueue.WorkItem.List.Flink = 0i64;
LockQueue.WorkItem.List.Blink = (_LIST_ENTRY *)(v7 + 32);
KxAcquireQueuedSpinLock(&LockQueue, (PIO_WORKITEM_ROUTINE)(v7 + 32), v46, v47);
}
}
v21 = 0xFFFFFFFFFi64;
v22 = *(_QWORD *)Pfn1 & 0xFFFFFFFFFi64;
v23 = *((_QWORD *)Pfn1 + 3) & 0xFFFFFFFFFi64;
LABEL_90:
if( v22 == v21 )
{
v50 = v89;
v57 = v9 >> 3;
if( (v9 & 8) == 0 )
*(_QWORD *)(v7 + 24) = v23;
}
else
{
v50 = v89;
v51 = (volatile signed __int64 *)((char *)MmGetPfnDb() + 48 * v22 + 24);
v52 = *v51;
v53 = _InterlockedCompareExchange64(v51, v23 | *v51 & 0xFFFFFFF000000000ui64, *v51);
v54 = v53;
if( v50 == 2 )
{
if( v52 != v53 )
{
do
{
v55 = v54;
v54 = _InterlockedCompareExchange64(v51, v23 | v54 & 0xFFFFFFF000000000ui64, v54);
}
while( v55 != v54 );
}
}
else if( v52 != v53 )
{
do
{
v56 = v54;
v54 = _InterlockedCompareExchange64(v51, v23 | v54 & 0xFFFFFFF000000000ui64, v54);
}
while( v56 != v54 );
}
v21 = 0xFFFFFFFFFi64;
v57 = v9 >> 3;
}
if( v23 == v21 )
{
if( (v57 & 1) == 0 )
*(_QWORD *)(v7 + 16) = v22;
}
else
{
v58 = (unsigned __int64 *)((char *)MmGetPfnDb() + 48 * v23);
*v58 = v22 | *v58 & 0xFFFFFFF000000000ui64;
}
if( v9 >= 0x40 )
--*(_QWORD *)v7;
if( v50 == 2 && (v9 & 0x14) == 0 )
{
v59 = *((_BYTE *)Pfn1 + 35);
if( (v59 & 8) != 0 )
v60 = 5i64;
else
v60 = v59 & 7;
v61 = dword_140C4DBC8;
v62 = *((unsigned __int8 *)Pfn1 + 39) | (*(_QWORD *)Pfn1 >> 28) & 0xFFFFFFF00i64;
v63 = (*((_QWORD *)Pfn1 + 3) >> 20) & 0xFFFFF0000i64 | *((unsigned __int16 *)Pfn1 + 18);
v90 = v63;
if( dword_140C4DBC4 > (unsigned int)dword_140C4DBC8
|| (v64 = &qword_140C4DC08[16 * dword_140C4DBC4], v10 < *(_QWORD *)v64)
|| dword_140C4DBC4 != dword_140C4DBC8 && v10 >= *((_QWORD *)v64 + 2) )
{
v65 = 0;
if( dword_140C4DBC8 < 0 )
LABEL_179:
KeBugCheckEx(0x1Au, 0x6201ui64, v10, 0i64, 0i64);
while( 1 )
{
v66 = (v65 + v61) >> 1;
v64 = &qword_140C4DC08[16 * v66];
if( v10 >= *(_QWORD *)v64 )
{
if( v66 == dword_140C4DBC8 || v10 < *((_QWORD *)v64 + 2) )
{
dword_140C4DBC4 = (v65 + v61) >> 1;
break;
}
v65 = v66 + 1;
}
else
{
if( !v66 )
KeBugCheckEx(0x1Au, 0x6200ui64, v10, (ULONG_PTR)qword_140C4DC08, 0i64);
v61 = v66 - 1;
}
if( v61 < v65 )
goto LABEL_179;
}
}
v67 = *(_QWORD *)(*(_QWORD *)(qword_140C4E388 + 8 * ((*((_QWORD *)Pfn1 + 5) >> 39) & 0x3FFi64)) + 16i64)
+ 4544i64 * *((unsigned int *)v64 + 2);
if( qword_140C4DC10 )
{
v68 = MiPageToChannel(v10);
v63 = v90;
}
else
{
v68 = 0;
}
v69 = v60 + 8i64 * v68;
v70 = MmGetPfnDb();
v71 = (_QWORD *)(v67 + 24 * v69);
if( v62 == 0xFFFFFFFFFi64 )
{
v71[409] = v63;
}
else
{
v72 = (char *)v70 + 48 * v62;
*((_WORD *)v72 + 18) = v63;
v73 = *((_QWORD *)v72 + 3);
v74 = (v63 & 0xFFFFFFFFFFFF0000ui64) << 20;
v75 = _InterlockedCompareExchange64((volatile signed __int64 *)v72 + 3, v74 | v73 & 0xFF00000FFFFFFFFFui64, v73);
if( v73 != v75 )
{
do
{
v76 = v75;
v75 = _InterlockedCompareExchange64(
(volatile signed __int64 *)v72 + 3,
v74 | v75 & 0xFF00000FFFFFFFFFui64,
v75);
}
while( v76 != v75 );
}
v63 = v90;
}
if( v63 == 0xFFFFFFFFFi64 )
{
v71[408] = v62;
}
else
{
v77 = (char *)v70 + 48 * v63;
v78 = *(_QWORD *)v77 ^ (v62 << 28);
v77[39] = v62;
*(_QWORD *)v77 = (v62 << 28) ^ v78 & 0xFFFFFFFFFi64;
}
--v71[407];
if( (v9 & 8) != 0 )
*((_BYTE *)Pfn1 + 35) &= ~8u;
}
*(_QWORD *)Pfn1 = 0i64;
if( (v9 & 4) != 0 )
{
MiSetPfnBlink(Pfn1, 0i64, 0i64);
}
else
{
*((_QWORD *)Pfn1 + 3) &= 0xFFFFFFF000000000ui64;
if( (*((_QWORD *)Pfn1 + 5) & 0x2000000000000i64) == 0 && dword_140C4E40C == 1 )
{
v79 = v10 & 0x1F;
LOBYTE(v80) = 1;
v81 = (volatile signed __int32 *)(qword_140C4E468 + 4 * (v10 >> 5));
if( v79 + 1 > 0x20 )
{
if( (v10 & 0x1F) == 0 )
goto LABEL_148;
v82 = v10 & 0x1F;
_InterlockedOr(v81++, ((1 << (32 - v82)) - 1) << v79);
v80 = 1i64 - (unsigned int)(32 - v82);
if( v80 >= 0x20 )
{
v83 = v80 >> 5;
v80 += -32i64 * (v80 >> 5);
do
{
*v81++ = -1;
--v83;
}
while( v83 );
}
if( v80 )
LABEL_148:
_InterlockedOr(v81, (1 << v80) - 1);
}
else
{
_InterlockedOr(v81, 1 << v79);
}
}
}
if( v91 )
goto LABEL_155;
_m_prefetchw(&LockQueue);
Flink = (volatile signed __int64 *)LockQueue.WorkItem.List.Flink;
if( LockQueue.WorkItem.List.Flink )
goto LABEL_154;
if( (struct _IO_WORKITEM *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.WorkItem.List.Blink,
0i64,
(signed __int64)&LockQueue) != &LockQueue )
{
Flink = (volatile signed __int64 *)KxWaitForLockChainValid((_KSPIN_LOCK_QUEUE *)&LockQueue);
LABEL_154:
LockQueue.WorkItem.List.Flink = 0i64;
_InterlockedXor64(Flink + 1, 1ui64);
}
LABEL_155:
if( (v9 & 2) != 0 )
{
v85 = _InterlockedDecrement64((volatile signed __int64 *)(v6 + 7104));
if( v85 == *(_QWORD *)(v6 + 5168) || v85 == *(_QWORD *)(v6 + 5176) )
MiUpdateAvailableEvents((_MI_PARTITION *)v6);
if( v85 <= 0x420 )
{
v86 = *(_QWORD *)(v6 + 6848);
if( !v86 || !*(_BYTE *)(v86 + 52) )
MiObtainFreePages((_MI_PARTITION *)v6);
if( v85 < 0xA0 && v85 + 1 >= 0xA0 && *(_DWORD *)(v6 + 1160) )
KeSetEvent((PRKEVENT)(v6 + 1008), 0);
}
if( v85 < 0x9F )
{
v87 = *((_DWORD *)KeGetCurrentThread() + 325);
if( (v87 & 0xC) != 8
&& (v85 < 0x20 && (ULONG_PTR *)v6 == &MiSystemPartition
|| ((v87 & 2) == 0 || v85 < 0x21) && (*(_DWORD *)(v6 + 4) & 0x20) == 0) )
{
LOBYTE(v9) = -2;
}
}
}
return v9 & 1;
}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
MiRelinkStandbyPage
MiRemoveLowestPriorityStandbyPage
MiReplaceTransitionPage
MiReservePageFileSpaceForPage
MiResolveProtoCombine
MiReuseStandbyPage
MiUnlinkStandbyBatch
MiUnlinkStandbyPfn
MiWalkEntireImage
MiWalkResetCommitPte
MiZeroCfgSystemWideBitmapWorker
MmCheckCachedPageStates