MiUnlockImageSection
VOID __stdcall MiUnlockImageSection(
INT64 *SectionLockCountPointer,
_MMPTE *PointerPte,
_MMPTE *LastPte,
ULONG_PTR NtSection){
_ETHREAD *CurrentThread;
_MMPTE *v5;
__int64 CurrentIrql;
signed __int32 v8;
unsigned int v9;
unsigned __int64 v10;
struct _KPRCB *CurrentPrcb;
int v12;
_MMPFN *PfnDb;
_MMPTE *PteBase;
signed __int64 v15;
INT64 v16;
unsigned __int8 v17;
__int16 v18;
bool v19;
__int16 v20;
int v21;
__int64 v22;
__int64 v23;
__int64 v24;
int v25;
unsigned __int64 v26;
char v27;
int v28;
_MMPFN *v29;
unsigned __int64 v30;
int v31;
int v32;
__int64 v33;
_MI_PARTITION *v34;
unsigned __int64 v35;
__int64 CachedResidentAvailable;
signed __int32 v37;
int v38[8];
UINT64 SpinCount;
UINT64 Long;
_ETHREAD *v41;
__int64 v42;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v5 = PointerPte;
v41 = CurrentThread;
CurrentIrql = KeGetCurrentIrql();
v42 = CurrentIrql;
if( !(_BYTE)CurrentIrql )
--CurrentThread->Tcb.KernelApcDisable;
v8 = _InterlockedDecrement((volatile signed __int32 *)SectionLockCountPointer);
if( (unsigned int)(v8 + 1) <= 1 )
KeBugCheckEx(
0x1Au,
(PVOID)0x1010,
(PVOID)((__int64)(((_QWORD)PointerPte << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16),
*(PVOID *)&NtSection,
(PVOID)v8);
if( v8 == 1 )
{
if( PointerPte <= LastPte )
{
LOBYTE(v9) = MiPteInShadowRange((UINT64)&Long);
v10 = v9;
HIDWORD(SpinCount) = v9;
LOBYTE(CurrentPrcb) = (unsigned __int8)MmGetPml4eBase();
v12 = 1;
PfnDb = MmGetPfnDb();
PteBase = MmGetPteBase();
while( 1 )
{
Long = v5->u.Long;
v15 = (Long >> 12) & 0xFFFFFFFFFi64;
v16 = (INT64)&PfnDb[v15];
v17 = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)(v16 + 24), 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)(v16 + 24) < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)(v16 + 24), 0x3Fui64) );
v12 = 1;
}
v18 = *(_WORD *)(v16 + 32);
if( !v18 )
MiBadRefCount((_MMPFN *)v16);
v19 = v18 == 1;
v20 = v18 - 1;
*(_WORD *)(v16 + 32) = v20;
if( v19 )
{
LOBYTE(v21) = MiIsPfnFileOnly(v16);
if( v21 )
{
LABEL_52:
MiPfnReferenceCountIsZero((_MMPFN *)v16, v15 * 48 / 48, (UINT8)CurrentPrcb);
goto LABEL_53;
}
}
v22 = *(_QWORD *)(v16 + 40);
if( (v22 & 0x1000000000i64) != 0 || (v22 & 0x2000000000000i64) != 0 )
goto LABEL_53;
v23 = *(_QWORD *)(v16 + 24);
v24 = v23 & 0x3FFFFFFFFFFFFFFFi64;
if( v20 )
break;
v25 = v12;
LABEL_25:
v26 = *(_QWORD *)(v16 + 8) | 0x8000000000000000ui64;
if( v26 > (unsigned __int64)&PteBase[0x7FFFFFFEFi64] || v26 < (unsigned __int64)PteBase )
{
v27 = *(_BYTE *)(v16 + 35);
if( (v27 & 0x20) != 0 )
{
*(_BYTE *)(v16 + 35) = v27 & 0xDF;
goto LABEL_51;
}
}
LOBYTE(v28) = MI_PFN_IS_PROTO(
(_UNICODE_STRING *)v16,
(_UNICODE_STRING *)0x8000000000000000i64,
(UINT8)CurrentPrcb,
(PWCHAR)v10);
if( v28 && (*(_DWORD *)(v16 + 16) & 0x400i64) != 0 )
{
v31 = 1;
}
else
{
MiIsPfnCommitNotCharged(v29);
if( v32 )
{
v31 = 1;
}
else if( v25 == 1 && (v23 & 0x4000000000000000i64) != 0 )
{
v31 = 1;
}
}
v33 = (v30 >> 39) & 0x3FF;
v34 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v33);
if( v31 == 1 )
MiReturnCommit(*(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v33), 1ui64);
v35 = 1i64;
if( v34 != &Irp
|| (CurrentPrcb = KeGetCurrentPrcb(),
CachedResidentAvailable = (int)CurrentPrcb->CachedResidentAvailable,
(_DWORD)CachedResidentAvailable == -1) )
{
LABEL_50:
_InterlockedExchangeAdd64((volatile signed __int64 *)&v34->Vp.ResidentAvailablePages, v35);
goto LABEL_51;
}
if( (unsigned __int64)(CachedResidentAvailable + 1) > 0x100 )
{
LABEL_45:
if( (int)CachedResidentAvailable > 192
&& (_DWORD)CachedResidentAvailable != -1
&& (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
192,
CachedResidentAvailable) )
{
v35 = (int)CachedResidentAvailable - 192 + 1i64;
}
if( v35 )
goto LABEL_50;
}
else
{
while( 1 )
{
v37 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
CachedResidentAvailable + 1,
CachedResidentAvailable);
v19 = (_DWORD)CachedResidentAvailable == v37;
LODWORD(CachedResidentAvailable) = v37;
if( v19 )
break;
if( v37 == -1 || (unsigned __int64)(v37 + 1i64) > 0x100 )
goto LABEL_45;
}
}
LABEL_51:
if( v25 )
goto LABEL_52;
LABEL_53:
_InterlockedAnd64((volatile signed __int64 *)(v16 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v17);
v10 = HIDWORD(SpinCount);
++v5;
v12 = 1;
LOBYTE(CurrentPrcb) = (unsigned __int8)MmGetPml4eBase();
PfnDb = MmGetPfnDb();
if( v5 > LastPte )
{
CurrentThread = v41;
LOBYTE(CurrentIrql) = v42;
goto LABEL_55;
}
}
if( v20 == 1 )
{
if( v24 )
{
LABEL_23:
v25 = 0;
goto LABEL_25;
}
}
else if( v20 != 2 || !v24 )
{
goto LABEL_53;
}
if( (*(_BYTE *)(v16 + 34) & 8) == 0 )
goto LABEL_53;
goto LABEL_23;
}
LABEL_55:
_InterlockedDecrement((volatile signed __int32 *)SectionLockCountPointer);
_InterlockedOr(v38, 0);
if( PushLock._bf_0 )
ExpUnblockPushLock(&PushLock, 0i64, 0);
}
if( !(_BYTE)CurrentIrql )
KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
}Referenced by:
MiLockPagableImageSection