MiInitializeReadInProgressPfn
VOID __stdcall MiInitializeReadInProgressPfn(
VOID *FaultingAddress,
UINT64 *MdlPage,
UINT64 ReadSize,
_MMPTE *BasePte,
_KEVENT *Event,
_MI_READ_IN_PROGRESS_FLAGS ReadInProgressFlags){
unsigned __int64 v6;
UINT64 *v7;
VOID *v8;
_MMPFN *v9;
unsigned __int64 v10;
_MMPFN *PfnDb;
unsigned __int64 PxeUserLimit;
_MMPFN *v13;
UINT64 v14;
unsigned __int64 Long;
bool v16;
int v17;
int v18;
UINT64 v19;
__int64 v20;
INT64 v21;
unsigned __int64 v22;
unsigned __int64 v23;
__int64 Address;
char v25;
_MI_PFN_CACHE_ATTRIBUTE v26;
__int64 v27;
unsigned __int8 CurrentIrql;
_KEVENT *v29;
unsigned __int8 v30;
unsigned __int64 v31;
__int64 v32;
int v33;
UINT64 SpinCount;
INT64 v35;
unsigned __int64 v36;
UINT64 *v37;
UINT64 *v39;
_MMPTE *v40;
v40 = BasePte;
v39 = MdlPage;
v6 = (unsigned __int64)BasePte;
v7 = MdlPage;
v8 = FaultingAddress;
v9 = 0i64;
v10 = 0xFFFFFFFFFi64;
v37 = &MdlPage[(unsigned int)ReadSize];
if( MdlPage < v37 )
{
PfnDb = MmGetPfnDb();
PxeUserLimit = (unsigned __int64)MmGetPxeUserLimit();
while( 1 )
{
v13 = &PfnDb[*v7];
if( v13 != (_MMPFN *)*(&stru_140C4DB30 + 496) )
break;
LABEL_70:
v6 += 8i64;
v7 = v39 + 1;
v40 = (_MMPTE *)v6;
v39 = v7;
if( v7 >= v37 )
return;
}
v14 = *(_QWORD *)v6;
v35 = v14;
Long = v14;
v16 = (ReadInProgressFlags._bf_0 & 0x40) != 0;
LOBYTE(v33) = 0;
v17 = 0;
if( (ReadInProgressFlags._bf_0 & 0x40) != 0 )
{
LOBYTE(v18) = MiIsPrototypePteVadLookup(v14);
if( v18 )
{
v19 = v14;
}
else
{
v20 = v14;
if( *(&stru_140C4DB30 + 42) && (v14 & 0x10) == 0 )
v20 = v14 & ~*(&stru_140C4DB30 + 42);
LODWORD(v21) = MI_READ_PTE_LOCK_FREE(v20 >> 16);
v35 = v21;
LODWORD(v22) = MI_READ_PTE_LOCK_FREE((INT64)&v35);
LODWORD(v19) = MI_READ_PTE_LOCK_FREE((INT64)&MmGetPfnDb()[(v22 >> 12) & 0xFFFFFFFFFi64].OriginalPte.u.Hard);
}
v33 = MmMakeProtectNotWriteCopy[(v19 >> 5) & 0x1F];
Long = MiSwizzleInvalidPte(32i64 * (v33 & 0x1F));
}
else
{
v23 = v14;
if( (v14 & 0x400) != 0 || (v14 & 0x800) == 0 )
goto LABEL_19;
if( *(&stru_140C4DB30 + 42) && (v14 & 0x10) == 0 )
Long = v14 & ~*(&stru_140C4DB30 + 42);
Long = MmGetPfnDb()[(Long >> 12) & 0xFFFFFFFFFi64].OriginalPte.u.Long;
}
v23 = Long;
v35 = Long;
LABEL_19:
v13->OriginalPte.u.Long = Long;
if( v16 )
{
LODWORD(Address) = v17;
}
else
{
if( (ReadInProgressFlags._bf_0 & 0x10) == 0
|| (v13->u4._bf_0 |= 0x8000000000000000ui64, &v35 < (INT64 *)MmGetPml4eBase())
|| (unsigned __int64)&v35 > PxeUserLimit )
{
PxeUserLimit = v23;
}
v33 = (PxeUserLimit >> 5) & 0x1F;
Address = (PxeUserLimit >> 5) & 0x1F;
if( v33 == 24 )
{
LOBYTE(v33) = 24;
if( (unsigned __int64)v8 <= 0x7FFFFFFEFFFFi64 )
{
Address = (__int64)MiLocateAddress(v8);
LOBYTE(v33) = v25;
LODWORD(Address) = (*(_DWORD *)(Address + 48) >> 7) & 0x1F;
}
}
}
if( (_DWORD)Address )
{
if( (_DWORD)Address == 31 )
{
v26 = MiCached;
}
else if( (unsigned int)Address >> 3 == 3 && (Address & 7) != 0 )
{
v26 = MiWriteCombined;
}
else
{
v26 = (unsigned int)Address >> 3 != 1;
}
}
else
{
v26 = MiNotMapped;
}
if( v10 == 0xFFFFFFFFFi64 )
{
v36 = *(unsigned __int64 *)((char *)&MmGetPteBase()->u.Long + ((v6 >> 9) & 0x7FFFFFFFF8i64));
v10 = (v36 >> 12) & 0xFFFFFFFFFi64;
v9 = &MmGetPfnDb()[v10];
}
v27 = v6;
if( (ReadInProgressFlags._bf_0 & 0x20) != 0 )
v27 = v6 & 0x7FFFFFFFFFFFFFFFi64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v13->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v13->u2._bf_0 < 0 );
}
*((_BYTE *)&v13->u3 + 2) |= 0x20u;
v29 = Event;
if( Event )
v29 = (_KEVENT *)((char *)Event + 32);
v13->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = (__int64)v29;
v30 = *((_BYTE *)&v13->u3 + 2);
if( v30 >> 6 != v26 )
{
MiChangePageAttribute(v13, v26, 1ui64);
v30 = *((_BYTE *)&v13->u3 + 2);
}
v13->u2._bf_0 &= 0xC000000000000000ui64;
v13->u3.ReferenceCount = 1;
if( (ReadInProgressFlags._bf_0 & 8) != 0 )
*((_BYTE *)&v13->u3 + 3) ^= (*((_BYTE *)&v13->u3 + 3) ^ ReadInProgressFlags._bf_0) & 7;
v31 = v10 ^ v13->u4._bf_0;
v13->PteLong = v27;
v13->u4._bf_0 ^= v31 & 0xFFFFFFFFFi64;
*((_BYTE *)&v13->u3 + 2) = v30 & 0xF8 | 2;
if( ReadInProgressFlags._bf_0 < 0 )
*((_BYTE *)&v13->u3 + 3) |= 0x20u;
_InterlockedAnd64(&v13->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(CurrentIrql);
if( (v14 & 0x400) == 0 && (v14 & 0x800) != 0 )
{
v6 = (unsigned __int64)v40;
}
else
{
v32 = 32 * (((*v39 & 0xFFFFFFFFFi64) << 7) | v33 & 0x1F | 0x40);
if( *(&stru_140C4DB30 + 42) )
{
if( (*(&stru_140C4DB30 + 42) & v32) != 0 )
v32 |= 0x10ui64;
else
v32 |= *(&stru_140C4DB30 + 42);
}
v6 = (unsigned __int64)v40;
if( v40 >= MmGetPml4eBase()
&& v40 <= MmGetPxeUserLimit()
&& (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0
&& (v32 & 1) != 0 )
{
v32 |= 0x8000000000000000ui64;
}
v40->u.Long = v32;
}
if( (ReadInProgressFlags._bf_0 & 0x40) == 0 )
{
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v9->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( v9->u2._bf_0 < 0 );
}
v9->u2._bf_0 ^= (v9->u2._bf_0 ^ (v9->u2._bf_0 + 1)) & 0x3FFFFFFFFFFFFFFFi64;
_InterlockedAnd64(&v9->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v6 = (unsigned __int64)v40;
}
v8 = FaultingAddress;
PfnDb = MmGetPfnDb();
PxeUserLimit = (unsigned __int64)MmGetPxeUserLimit();
goto LABEL_70;
}
}Referenced by:
MiPfPutPagesInTransition
MiPrivateFixup
MiResolvePageFileFault