MiAllocateWsle
NTSTATUS __stdcall MiAllocateWsle(
_MMSUPPORT_INSTANCE *Vm,
_MMPTE *PointerPte,
_MMPFN *Pfn1,
UINT64 InputWsleMask,
_MMPTE PteContents,
_MI_FAULT_VA_LIST *VirtualFaultInfo){
_MMSUPPORT_FLAGS Flags;
char v7;
_MMPTE *PteBase;
unsigned __int64 v10;
_MMPTE *v11;
_MMPTE *PteLimit;
__int64 v13;
_ETHREAD *CurrentThread;
UINT8 v15;
unsigned int SameThreadApcFlags;
unsigned int v17;
char v18;
unsigned int v19;
__int64 bf_0;
unsigned int v21;
unsigned int v22;
int v23;
unsigned __int8 v24;
__int64 v25;
_MMPFN *v26;
_MMPFN *v27;
_MMPTE v28;
_MI_PARTITION *v29;
_MMPFN *v30;
char v31;
char v32;
UINT64 v33;
int v34;
ULONG_PTR v35;
int v36;
_MMPFN *v37;
UINT64 v38;
INT64 v39;
UINT64 *v40;
UINT64 *v41;
int v42;
unsigned __int64 v43;
int v44;
char v45;
unsigned __int64 v46;
_UNICODE_STRING *v47;
int v48;
__int64 v49;
CHAR v50;
UINT8 v52;
char v53;
UINT64 v54;
UINT64 SpinCount;
UINT64 v56;
_UNICODE_STRING *antNameB;
_KE_PRIVILEGED_PAGE_IDENTITY PrivilegedIdentity[4];
_KLOCK_QUEUE_HANDLE v59;
_MMPFN *Pfn1a;
INT64 v63;
Pfn1a = Pfn1;
Flags = Vm->Flags;
v7 = InputWsleMask;
PteBase = MmGetPteBase();
v53 = 0;
v10 = (__int64)(((_QWORD)PointerPte << 25) - ((_QWORD)PteBase << 25)) >> 16;
v54 = v10;
v11 = PteBase;
PteLimit = MmGetPteLimit();
if( v10 < (unsigned __int64)v11 || v10 > (unsigned __int64)PteLimit )
{
v13 = 1i64;
antNameB = (_UNICODE_STRING *)1;
v53 = 1;
}
else
{
v13 = 0i64;
antNameB = 0i64;
if( (Flags.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 & 7) == 0
&& (((unsigned __int8)Pfn1->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 >> 1) & 7) != 0 )
{
Pfn1->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 &= 0xFFFFFFFFFFFFFFF1ui64;
}
}
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v15 = 0;
v52 = 0;
SameThreadApcFlags = CurrentThread->SameThreadApcFlags;
if( (SameThreadApcFlags & 0x100) != 0 )
{
v17 = SameThreadApcFlags >> 9;
}
else
{
v17 = (CurrentThread->CrossThreadFlags >> 12) & 7;
if( (CurrentThread->Tcb.Process->Flags & 0x100000) != 0 )
{
v18 = 2;
if( v17 < 2 )
v18 = v17;
LOBYTE(v17) = v18;
}
}
v19 = v17 & 7;
bf_0 = PteContents.u.Hard._bf_0;
v21 = 5;
v22 = 8 * v19;
if( v13 )
{
if( ((unsigned __int8)VirtualFaultInfo & 2) != 0 )
{
v15 = 9;
}
else if( v19 >= 5 )
{
if( ((unsigned __int8)VirtualFaultInfo & 8) != 0 )
{
v15 = 6;
}
else
{
if( (PteContents.u.Long & 1) == 0 )
{
LABEL_26:
v24 = v15 | (16 * (v7 & 7));
goto LABEL_27;
}
v15 = (PteContents.u.Long & 0x20) == 0;
}
}
else
{
v15 = 7;
}
v52 = v15;
goto LABEL_26;
}
v23 = 5;
if( v19 > 5 )
v23 = v19;
v24 = 0;
v22 = 8 * v23;
LABEL_27:
v25 = 0x7FFFFFFFFFFFFFFFi64;
if( ((unsigned __int8)VirtualFaultInfo & 1) != 0 )
{
v26 = Pfn1a;
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v26->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v26->u2._bf_0 < 0 );
}
v27 = Pfn1a;
v28.u.Long = MiReleaseWsSwapReservationPfn(Pfn1a).u.Long;
v29 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v27->u4._bf_0 >> 39) & 0x3FF));
v25 = 0x7FFFFFFFFFFFFFFFi64;
_InterlockedAnd64(&v26->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v28.u.Long )
{
MiReleasePageFileInfo(v29, v28, 1ui64);
v25 = 0x7FFFFFFFFFFFFFFFi64;
}
bf_0 = PteContents.u.Hard._bf_0;
}
v30 = Pfn1a;
v31 = *((_BYTE *)&Pfn1a->u3 + 3);
if( (v31 & 8) == 0 )
v21 = v31 & 7;
if( v21 < v22 >> 3 )
{
HIDWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)&Pfn1a->u2, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( v30->u2._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&v30->u2, 0x3Fui64) );
v25 = 0x7FFFFFFFFFFFFFFFi64;
}
*((_BYTE *)&v30->u3 + 3) = (v22 >> 3) | *((_BYTE *)&v30->u3 + 3) & 0xF8;
_InterlockedAnd64(&v30->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
bf_0 = PteContents.u.Hard._bf_0;
v30 = Pfn1a;
}
if( (v30->$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::gap0[0] & 1) == 0 )
{
LODWORD(v56) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)&v30->u2, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&v56);
while( v30->u2._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&v30->u2, 0x3Fui64) );
v25 = 0x7FFFFFFFFFFFFFFFi64;
}
if( (Pfn1a->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 1) == 0 )
Pfn1a->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 |= 1ui64;
_InterlockedAnd64(&v30->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
bf_0 = PteContents.u.Hard._bf_0;
v30 = Pfn1a;
}
if( (bf_0 & 1) == 0 )
{
v33 = v54;
goto LABEL_104;
}
v32 = Flags.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 & 7;
if( (Flags.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 & 7) == 2 )
{
bf_0 |= 0x8000000000000000ui64;
PteContents.u.Long = bf_0;
}
else if( (MiFlags & 0x10000) != 0 )
{
v33 = v54;
if( (v54 < (unsigned __int64)MmGetPteBase() || v54 > (unsigned __int64)MmGetPteLimit())
&& (bf_0 & 0x8000000000000000ui64) == 0
&& ((MiFlags & 0x40000) != 0 || v32) )
{
HIDWORD(v56) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v30->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v56 + 4));
while( v30->u2._bf_0 < 0 );
}
v37 = Pfn1a;
if( !MiGetPagePrivilege((ULONG_PTR)Pfn1a, 1ui64, 0i64) )
{
v38 = 38i64;
if( !v32 )
v38 = 7i64;
MiMarkPfnVerified(v37, v38);
}
_InterlockedAnd64(&v30->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
bf_0 = PteContents.u.Hard._bf_0;
v30 = Pfn1a;
}
goto LABEL_54;
}
v33 = v54;
LABEL_54:
if( (MiFlags & 0x8000) != 0 && (MiFlags & 0x10000) != 0 )
{
LOBYTE(v34) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v30, (_UNICODE_STRING *)v25, v15, (PWCHAR)v13);
if( v34 )
{
if( (((unsigned __int64)v30->u4._bf_0 >> 60) & 7) == 3 && (v32 == 4 || v32 == 1) )
{
*(_OWORD *)PrivilegedIdentity = 0i64;
if( (MiGetPagePrivilege(v35, 0i64, PrivilegedIdentity) & 8) != 0 )
{
v36 = (unsigned int)KeSetPagePrivilege(
(_PREFIX_TABLE *)(v30 - MmGetPfnDb()),
(_STRING *)PrivilegedIdentity,
1024);
if( v36 < 0 )
KeBugCheckEx(0x1Au, (PVOID)0x515E4, v30, (PVOID)v36, 0i64);
}
}
}
}
v39 = v63;
if( v63
&& (LODWORD(v40) = MiGetVirtualFaultPageInfo(v63, v33), (v41 = v40) != 0i64)
&& ((v42 = *(_DWORD *)(v39 + 56), (v42 & 0x20) == 0)
|| (v30->u4._bf_0 & 0x1000000000i64) != 0
|| (__int64)v30->ListEntry.Blink <= 0) )
{
if( (v42 & 0x10) != 0 && v52 < 6u )
v24 = v24 & 0xF0 | 6;
}
else
{
v41 = 0i64;
}
if( antNameB )
{
bf_0 = bf_0 & 0x80FFFFFFFFFFFFFFui64 | ((unsigned __int64)v24 << 56);
PteContents.u.Long = bf_0;
LOBYTE(v22) = v22 | 1;
}
v43 = bf_0;
v15 = (unsigned __int8)PointerPte;
if( PointerPte >= MmGetPml4eBase() && PointerPte <= MmGetPxeUserLimit() )
{
if( (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (bf_0 & 1) != 0 )
v43 = bf_0 | 0x8000000000000000ui64;
v30 = Pfn1a;
bf_0 = PteContents.u.Hard._bf_0;
}
PointerPte->u.Long = v43;
if( v41 )
{
v44 = *(_DWORD *)(v39 + 56);
if( ((v44 & 1) == 0 || (bf_0 & 0x42) != 0) && ((v44 & 2) == 0 || bf_0 >= 0) )
{
LOBYTE(v22) = v22 | 4;
if( (v44 & 0x20) != 0 )
{
v45 = MiCompleteSecureProcessFault((INT64 *)&Pfn1a, (INT64 *)&PteContents, (INT64 *)(v39 + 48));
bf_0 = PteContents.u.Hard._bf_0;
v30 = Pfn1a;
LOBYTE(v22) = (v22 ^ (4 * v45)) & 4 ^ v22;
}
if( (v22 & 4) != 0 )
{
LODWORD(v46) = MI_READ_PTE_LOCK_FREE((INT64)&PteContents);
MiFillVirtualFaultInfo(v41, (v46 >> 12) & 0xFFFFFFFFFi64, bf_0);
}
}
}
LABEL_104:
v47 = antNameB;
if( antNameB && (v22 & 1) == 0 )
LOBYTE(antNameB->Length) = v24;
if( ((unsigned __int8)VirtualFaultInfo & 2) != 0 )
{
memset(&v59, 0, sizeof(v59));
MiLockWorkingSetCoreExclusive((INT64)Vm);
MiIncrementVmFaultCount((INT64)Vm, 1i64);
MiUnlockWorkingSetCoreExclusive(&v59);
}
else if( ((unsigned __int8)VirtualFaultInfo & 4) == 0 )
{
LOBYTE(v48) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v30, v47, v15, (PWCHAR)v13);
v50 = v53 | 2;
if( v48 )
v50 = v53;
if( v49 || (Flags.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 & 7) == 0 )
v50 |= 4u;
MiAddWorkingSetEntries((INT64)Vm, v33, (UINT8 *)1, v50);
}
return 1;
}Referenced by:
MiCompletePrivateZeroFault
MiCompleteProtoPteFault
MiCompleteRestrictedImageFault
MiCreateForkWsle
MiInitializeWorkingSetList
MiIssueHardFault
MiMakeSystemCachePteValid
MiMakeSystemCacheRangeValid
MiResolveProtoCombine
MiResolveTransitionFault