MiPfnShareCountIsZero
_MI_PAGE_DELETE_RESULT __stdcall MiPfnShareCountIsZero(_MMPFN *Pfn1, _MMPFN *DecayPfn){
UINT8 v2;
wchar_t *v3;
UINT64 v4;
UINT64 v5;
int v8;
__int64 v9;
INT64 v10;
UINT64 v11;
_MMPFN *PfnDb;
_LIST_ENTRY *Blink;
__int64 v14;
__int64 v15;
char v16;
int v17;
__int64 v18;
_MMPTE *PteBase;
unsigned __int64 v20;
unsigned __int64 v21;
__int64 v22;
struct _KPRCB *CurrentPrcb;
unsigned __int64 v24;
_MI_ZERO_THREAD_CONTEXT *MmInternal;
unsigned __int64 v26;
unsigned __int64 v27;
_MMPTE *v28;
_MMPTE *Pml4eBase;
_MMPTE *PxeUserLimit;
__int64 v31;
__int64 v32;
_MMPTE *v33;
__int64 v34;
unsigned __int64 EntireField;
__int64 v36;
char v37;
char v38;
char v40;
unsigned __int64 v41;
_MI_PARTITION *v42;
_MMPTE v43;
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;} v44;
__int64 v45;
char v46;
UINT64 v47;
UINT64 v48;
UINT64 v49;
INT64 bf_0;
LOBYTE(v8) = MI_PFN_IS_PROTO((_UNICODE_STRING *)Pfn1, (_UNICODE_STRING *)DecayPfn, v2, v3);
PfnDb = MmGetPfnDb();
if( v8 )
{
v49 = v4;
v48 = v5;
Blink = Pfn1->ListEntry.Blink;
v14 = Pfn1->u4._bf_0 & 0xFFFFFFFFFi64;
v15 = *(_QWORD *)(v9 + 16) >> 5;
v16 = 4;
v17 = *((unsigned __int8 *)&PfnDb[v14].u3 + 2) >> 6;
if( !v17 || v17 == 3 )
{
v16 = 12;
}
else if( v17 == 2 )
{
v16 = 28;
}
v18 = v14 << 12;
PteBase = MmGetPteBase();
v20 = v18 | MmProtectToPteMask[v16 & 0x1F] & 0xFFFF000000000E7Fui64 | 0x21;
if( PteBase )
{
v21 = v18 | MmProtectToPteMask[v16 & 0x1F] & 0xFFFF000000000E7Fui64 | 0x121;
}
else
{
if( !MmGetPdeBase() )
{
v20 = v18 & 0x7FFFFFFFFFFFFFFFi64 | MmProtectToPteMask[v16 & 0x1F] & 0x7FFF000000000E7Fi64 | 0x21;
if( MiUserPdeOrAbove(0i64) )
v20 |= 4ui64;
}
v21 = v20 | 4;
if( MiIsAddressGlobal(0i64) )
v21 = v22 | 0x104;
}
CurrentPrcb = KeGetCurrentPrcb();
v24 = v21 & 0xFAFFFFFFFFFFFEFFui64 | ((unsigned __int64)(*(&stru_140C4DB30 + 536) & 1) << 8) | 0xA00000000000042i64;
MmInternal = (_MI_ZERO_THREAD_CONTEXT *)CurrentPrcb->MmInternal;
if( !MmInternal
|| (MiGetUltraMapping(MmInternal + 3112, 3i64),
v27 = v26,
v28 = (_MMPTE *)((char *)PteBase + ((v26 >> 9) & 0x7FFFFFFFF8i64)),
*((_QWORD *)MmInternal + 1543) = v28,
!v26) )
{
v27 = ((unsigned __int64)CurrentPrcb->HyperPte & 0xFFFFFFFFFFFFF000ui64)
+ (((__int64)CurrentPrcb->HyperPte & 0xFFF) << 12);
v28 = (_MMPTE *)((char *)PteBase + ((v27 >> 9) & 0x7FFFFFFFF8i64));
}
Pml4eBase = MmGetPml4eBase();
PxeUserLimit = MmGetPxeUserLimit();
if( v28 >= Pml4eBase && v28 <= PxeUserLimit && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 )
v24 |= 0x8000000000000000ui64;
v28->u.Long = v24;
v31 = ((unsigned __int64)Blink >> 3) & 0x1FF;
v32 = *(_QWORD *)(v27 + 8 * v31);
v33 = (_MMPTE *)(v27 + 8 * v31);
v34 = v32 & 0xFFFFFFFFF000i64 | (32 * (v15 & 0x1F | 0x40));
if( *(&stru_140C4DB30 + 42) )
{
if( (*(&stru_140C4DB30 + 42) & v34) != 0 )
v34 |= 0x10ui64;
else
v34 |= *(&stru_140C4DB30 + 42);
}
if( v33 >= Pml4eBase
&& v33 <= PxeUserLimit
&& (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0
&& (v34 & 1) != 0 )
{
v34 |= 0x8000000000000000ui64;
}
v33->u.Long = v34;
MiUnmapPageInHyperSpaceWorker(v33, 0x11u, 0x80000000ui64);
PfnDb = MmGetPfnDb();
}
EntireField = Pfn1->u2.EntireField;
--Pfn1->u3.ReferenceCount;
v36 = (EntireField >> 62) & 1;
if( Pfn1->u3.ReferenceCount )
{
v37 = *((_BYTE *)&Pfn1->u3 + 2);
if( (_DWORD)v36 )
{
v38 = v37 | 7;
}
else if( (v37 & 0x10) != 0 )
{
v38 = v37 & 0xF8 | 3;
}
else
{
v38 = v37 & 0xF8 | 2;
}
*((_BYTE *)&Pfn1->u3 + 2) = v38;
if( (*(_DWORD *)(&Pfn1->3 + 1) & 0x400i64) == 0 )
{
if( MiGetPagingFileOffset(&Pfn1->OriginalPte) )
*(_BYTE *)(*(_QWORD *)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)Pfn1->u4._bf_0 >> 39) & 0x3FF))
+ 675i64) = 1;
}
return 3;
}
else if( (_DWORD)v36 )
{
v40 = *((_BYTE *)&Pfn1->u3 + 3);
if( (v40 & 0x10) != 0 )
*((_BYTE *)&Pfn1->u3 + 3) = v40 & 0xEF;
v41 = ((unsigned __int64)Pfn1->u4._bf_0 >> 39) & 0x3FF;
bf_0 = Pfn1->OriginalPte.u.Hard.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0;
v42 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v41);
if( (bf_0 & 0x400) == 0 && ((bf_0 & 4) != 0 || (bf_0 & 2) != 0) )
{
LODWORD(v43.u.Long) = MI_READ_PTE_LOCK_FREE((INT64)&bf_0);
if( v43.u.Long )
MiReleasePageFileInfo(v42, v43, 0i64);
}
MiInsertPageInFreeOrZeroedList(Pfn1 - PfnDb, 2ui64, v10, v11, v48, v49);
return 4;
}
else
{
v44.Long = (unsigned __int64)Pfn1->OriginalPte.u;
v45 = -9i64;
if( (v44.Long & 0x400) != 0 )
v45 = -2049i64;
Pfn1->OriginalPte.u.Long = v44.Long & v45;
v46 = *((_BYTE *)&Pfn1->u3 + 2);
if( (v46 & 0x10) != 0 )
{
v47 = 136i64;
if( DecayPfn != (_MMPFN *)1 )
v47 = 8i64;
}
else
{
*((_BYTE *)&Pfn1->u3 + 2) = v46 & 0xF8 | 2;
if( (unsigned __int64)DecayPfn > 1 && (unsigned int)MiGetPfnPriority(Pfn1) < 5 )
{
MiInsertProtectedStandbyPage(DecayPfn, Pfn1, v10);
return 4;
}
v47 = 4i64;
}
MiInsertPageInList(Pfn1, v47, v10);
return 4;
}
}Referenced by:
MiDecrementShareCount
MiDeleteBatch
MiDeletePteList
MiDeletePteRun
MiDeleteTransitionPte
MiDeleteValidSystemPage
MiMakePageAvoidRead
MiReduceShareCount
MiUnlockPageTableCharges
MiWsleFree
MmUnlockPages