MiLockPageTableInternal
UINT64 __fastcall MiLockPageTableInternal(INT64 a1, UINT64 a2, UINT8 *r8_0){
unsigned int v4;
char v5;
char v6;
_MMPTE *Pml4eBase;
_MMPTE *Pml4eLimit;
unsigned __int64 v9;
int v10;
signed __int64 v11;
int v12;
__int64 v14;
__int64 *v15;
KSPIN_LOCK_QUEUE *v16;
KSPIN_LOCK_QUEUE *v17;
volatile signed __int32 *PageTableLockBuffer;
unsigned __int32 v19;
char i;
bool v21;
signed __int32 v22;
signed __int64 v23;
struct _KPRCB *CurrentPrcb;
int v25;
signed __int32 v26;
volatile LONG *v27;
int a3;
UINT64 SpinCount;
v4 = 0;
v5 = (char)r8_0;
v6 = *(_BYTE *)(a1 + 184) & 7;
a3 = 0;
if( (_MMPTE *)a2 == MmGetPxeSelfRef() )
{
if( v6 )
{
if( v6 == 7 )
{
v15 = qword_140C4E238;
v16 = (KSPIN_LOCK_QUEUE *)((char *)KeGetCurrentPrcb() + 36184);
}
else
{
CurrentPrcb = KeGetCurrentPrcb();
if( v6 == 5 )
{
v15 = &qword_140C4E230;
v16 = (KSPIN_LOCK_QUEUE *)((char *)CurrentPrcb + 36160);
}
else
{
v15 = qword_140C4E248;
v16 = (KSPIN_LOCK_QUEUE *)((char *)CurrentPrcb + 36232);
}
}
}
else
{
v15 = (__int64 *)(a1 + 176);
v16 = (KSPIN_LOCK_QUEUE *)((char *)KeGetCurrentPrcb() + 36208);
}
v16->Next = 0i64;
v16->Lock = (unsigned __int64 *volatile)v15;
if( ((unsigned __int8)r8_0 & 1) != 0 )
return KxTryToAcquireQueuedSpinLock(v16, (UINT64 *)v15);
v17 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64(v15, (__int64)v16);
if( v17 )
{
KxWaitForLockOwnerShip(v16, v17);
return 1i64;
}
return 1i64;
}
Pml4eBase = MmGetPml4eBase();
Pml4eLimit = MmGetPml4eLimit();
if( v6 )
{
if( a2 >= (unsigned __int64)Pml4eBase && a2 <= (unsigned __int64)Pml4eLimit )
{
LODWORD(SpinCount) = 0;
PageTableLockBuffer = (volatile signed __int32 *)MiGetPageTableLockBuffer(a1, a2, &a3);
v19 = *PageTableLockBuffer;
for( i = a3; ; i = a3 )
{
while( ((v19 >> i) & 1) != 0 )
{
if( (v5 & 1) != 0 )
return 0i64;
if( ((v19 >> i) & 2) != 0 )
{
do
{
KeYieldProcessorEx(&SpinCount);
v19 = *PageTableLockBuffer;
i = a3;
}
while( (((unsigned __int32)*PageTableLockBuffer >> a3) & 1) != 0 );
}
else
{
v25 = v19 | (2 << i);
v26 = _InterlockedCompareExchange(PageTableLockBuffer, v25, v19);
v21 = v19 == v26;
i = a3;
v19 = v26;
if( v21 )
v19 = v25;
}
}
v22 = _InterlockedCompareExchange(PageTableLockBuffer, ~(2 << i) & (v19 | (1 << i)), v19);
v21 = v19 == v22;
v19 = v22;
if( v21 )
return 1i64;
if( (v5 & 1) != 0 )
break;
}
return 0i64;
}
}
else if( a2 >= (unsigned __int64)Pml4eBase && a2 <= (unsigned __int64)Pml4eLimit )
{
v14 = *(_QWORD *)(*(_QWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 1680i64) + 608i64);
if( v14 )
{
v27 = (volatile LONG *)(v14 + 4 * ((a2 >> 3) & 0x1FF));
if( (v5 & 4) != 0 )
{
ExAcquireSpinLockSharedAtDpcLevel(v27);
return 1i64;
}
if( (v5 & 1) == 0 )
{
ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)v27);
return 1i64;
}
return(unsigned int)ExTryAcquireSpinLockExclusiveAtDpcLevel((INT64 *)v27) != 0;
}
}
v9 = *(_QWORD *)a2;
v10 = 0;
if( (*(_QWORD *)a2 & 1) == 0 )
return v4;
v11 = *(_QWORD *)a2;
v12 = v5 & 1;
while( 1 )
{
if( (v9 & 0x1000000000000000i64) != 0 )
{
if( (v5 & 1) != 0 )
return v4;
if( ((v9 >> 60) & 2) != 0 )
{
do
{
++v10;
_mm_pause();
v9 = *(_QWORD *)a2;
}
while( (*(_QWORD *)a2 & 0x1000000000000000i64) != 0 );
}
else
{
v9 |= 0x2000000000000000ui64;
v23 = _InterlockedCompareExchange64((volatile signed __int64 *)a2, v9, v11);
if( v23 != v11 )
v9 = v23;
}
v12 = v5 & 1;
goto LABEL_28;
}
v9 = _InterlockedCompareExchange64(
(volatile signed __int64 *)a2,
v9 & 0xCFFFFFFFFFFFFFDFui64 | 0x1000000000000020i64,
v11);
if( v11 == v9 )
return 1;
if( v12 )
return v4;
LABEL_28:
v11 = v9;
if( (v9 & 1) == 0 )
return v4;
}
}Referenced by:
MiAllocateKernelStackPages
MiClearPteAccessed
MiDeleteKernelStack
MiEncodeProtoFill
MiEvictPageTableLock
MiFastLockLeafPageTable
MiFaultInPagedPool
MiFreePhysicalPages
MiGetNextPageTablePte
MiGetWsAndMakePageTablesNx
MiInitializeWorkingSetList
MiIsPageTableDeletable
MiJumpStackTarget
MiLockCode
MiLockDriverPageRange
MiLockLowestValidPageTable
MiLockPageLeafPageTable
MiLockPageTable
MiLockWorkingSetOptimal
MiMakeDriverPagesPrivate
MiMakeSystemCacheRangeValid
MiMapMdlCommon
MiMapRetpolineStubs
MiMapWithLargePages
MiMarkBootKernelStack
MiOutPageSingleKernelStack
MiReleaseLargePteMappings
MiRemoveMappedPtes
MiReplaceRotateWithDemandZero
MiRewritePteWithLockBit
MiScrubAwePage
MiSetPagingOfDriver
MiSetSystemCodeProtection
MiSwapStackPage
MiSwitchToTransition
MiUnlockPageTableRange
MiUnmapMdlCommon
MiUnmapPatchTable
MiUnmapRetpolineStubs
MiUpdateImportRelocationsOnDriverPrivatePages
MiUserFault
MiWalkPageTables
MiWalkPageTablesRecursively
MiWsleFlush
MmFreeLoaderBlock
MmProtectPool
MmReplaceImportEntry