MiLockPageTablePage
NTSTATUS __stdcall MiLockPageTablePage(_MMPFN *PageTablePfn, _MI_LOCK_PAGE_TABLE_TYPE PageTableType){
NTSTATUS v2;
_MMPFN *v4;
_MMPFN *v5;
_MMPFN *PfnDb;
NTSTATUS v7;
unsigned __int64 v8;
UINT64 v9;
_MI_PARTITION *v10;
struct _KPRCB *CurrentPrcb;
UINT64 CachedResidentAvailable;
unsigned __int32 v13;
unsigned int i;
bool v15;
unsigned __int64 v16;
unsigned __int64 v17;
struct _KPRCB *v18;
__int64 v19;
signed __int32 v20;
char v22;
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;} v23;
char v24;
unsigned __int64 v25;
struct _KPRCB *v26;
__int64 v27;
signed __int32 v28;
UINT64 v29;
UINT64 SpinCount;
_MMPFN *v31;
v2 = 0;
v4 = PageTablePfn;
if( PageTableType == PageTableLockShared )
{
v5 = PageTablePfn;
}
else
{
v5 = 0i64;
if( PageTableType == PageTableLockPrivate )
v5 = PageTablePfn;
}
v31 = v5;
PfnDb = MmGetPfnDb();
v7 = 1;
while( 1 )
{
LABEL_6:
if( PageTableType == PageTableLockShared )
v4 = &PfnDb[v5->u4._bf_0 & 0xFFFFFFFFFi64];
if( (v4->u2._bf_0 & 0x3FFFFFFFFFFFFFFFui64) < 0x10000 )
goto LABEL_18;
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)&v4->u2, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( v4->u2._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&v4->u2, 0x3Fui64) );
PfnDb = MmGetPfnDb();
}
if( PageTableType == PageTableLockShared && v4 != &PfnDb[v5->u4._bf_0 & 0xFFFFFFFFFi64] )
{
_InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
continue;
}
v8 = v4->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64;
if( v8 >= 0x10000 )
break;
_InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
LABEL_18:
if( PageTableType == PageTableLockPrivateFork )
{
v9 = 3i64;
}
else
{
v9 = 1i64;
if( PageTableType == PageTableLockPrivate )
v9 = 4i64;
}
v10 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v4->u4._bf_0 >> 39) & 0x3FF));
if( v10 == &Irp )
{
CurrentPrcb = KeGetCurrentPrcb();
CachedResidentAvailable = CurrentPrcb->CachedResidentAvailable;
if( v9 <= CachedResidentAvailable )
{
do
{
if( (_DWORD)CachedResidentAvailable == -1 )
break;
v13 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
CachedResidentAvailable - v9,
CachedResidentAvailable);
v15 = (_DWORD)CachedResidentAvailable == v13;
LODWORD(CachedResidentAvailable) = v13;
if( v15 )
goto LABEL_28;
}
while( v9 <= v13 );
}
}
if( MiChargePartitionResidentAvailable(v10, v9, 0x200ui64) == MiChargeFailed )
return 0;
LABEL_28:
for( i = 0; ; ++i )
{
v15 = i == v9;
if( i >= v9 )
goto LABEL_39;
LODWORD(v29) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v4->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v29);
while( v4->u2._bf_0 < 0 );
}
if( PageTableType == PageTableLockShared )
{
PfnDb = MmGetPfnDb();
if( v4 != &PfnDb[v31->u4._bf_0 & 0xFFFFFFFFFi64] )
break;
}
v16 = v4->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64;
if( i )
{
if( v16 >= 0x3FFFFFFFFFFEFDFFi64 )
goto LABEL_56;
}
else if( v16 >= 0x3FFFFFFFFFFEFDFFi64 )
{
v7 = 0;
LABEL_38:
_InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v15 = i == v9;
LABEL_39:
if( !v15 )
{
v17 = v9 - i;
if( v10 == &Irp )
{
v18 = KeGetCurrentPrcb();
v19 = (int)v18->CachedResidentAvailable;
if( (_DWORD)v19 != -1 )
{
if( v17 + v19 <= 0x100 )
{
do
{
if( v17 >= 0x80000 )
break;
v20 = _InterlockedCompareExchange(
(volatile signed __int32 *)&v18->CachedResidentAvailable,
v17 + v19,
v19);
v15 = (_DWORD)v19 == v20;
LODWORD(v19) = v20;
if( v15 )
return v7;
}
while( v20 != -1 && v17 + v20 <= 0x100 );
}
if( (int)v19 > 192
&& (_DWORD)v19 != -1
&& (_DWORD)v19 == _InterlockedCompareExchange(
(volatile signed __int32 *)&v18->CachedResidentAvailable,
192,
v19) )
{
v17 += (int)v19 - 192;
}
}
}
if( v17 )
_InterlockedExchangeAdd64((volatile signed __int64 *)&v10->Vp.ResidentAvailablePages, v17);
}
return v7;
}
v4->u2._bf_0 ^= ((v16 + 0x10000) ^ v4->u2._bf_0) & 0x3FFFFFFFFFFFFFFFi64;
LABEL_56:
if( v16 >= 0x10000 )
goto LABEL_38;
v22 = *((_BYTE *)&v4->u3 + 2);
v23.Long = 0i64;
if( (v22 & 0x10) == 0 )
{
v24 = *((_BYTE *)&v4->u3 + 2);
if( (*(_DWORD *)(&v4->3 + 1) & 0x400i64) == 0 && (v22 & 8) == 0 )
{
v23.Long = MiCapturePageFileInfoInline(&v4->OriginalPte, 1ui64, 0i64).u.Long;
v24 = *((_BYTE *)&v4->u3 + 2);
}
*((_BYTE *)&v4->u3 + 2) = v24 | 0x10;
}
_InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v23.Long )
MiReleasePageFileInfo(v10, (_MMPTE)v23.Long, 1ui64);
v4 = &MmGetPfnDb()[v4->u4._bf_0 & 0xFFFFFFFFFi64];
}
_InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v25 = v9 - i;
if( v10 == &Irp )
{
v26 = KeGetCurrentPrcb();
v27 = (int)v26->CachedResidentAvailable;
if( (_DWORD)v27 != -1 )
{
if( v25 + v27 <= 0x100 )
{
do
{
if( v25 >= 0x80000 )
break;
v28 = _InterlockedCompareExchange((volatile signed __int32 *)&v26->CachedResidentAvailable, v25 + v27, v27);
v15 = (_DWORD)v27 == v28;
v5 = v31;
LODWORD(v27) = v28;
if( v15 )
goto LABEL_6;
}
while( v28 != -1 && v25 + v28 <= 0x100 );
}
if( (int)v27 > 192
&& (_DWORD)v27 != -1
&& (_DWORD)v27 == _InterlockedCompareExchange(
(volatile signed __int32 *)&v26->CachedResidentAvailable,
192,
v27) )
{
v25 += (int)v27 - 192;
}
}
}
v5 = v31;
if( v25 )
_InterlockedExchangeAdd64((volatile signed __int64 *)&v10->Vp.ResidentAvailablePages, v25);
}
if( v8 < 0x3FFFFFFFFFFEFDFFi64 )
{
v2 = 1;
v4->u2._bf_0 ^= (v4->u2._bf_0 ^ (v4->u2._bf_0 + 0x10000)) & 0x3FFFFFFFFFFFFFFFi64;
}
_InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
return v2;
}Referenced by:
MiBuildForkPte
MiLockPageTableRange
MiProbeLockFrame
NtLockVirtualMemory