MiPrivateFixup
NTSTATUS __stdcall MiPrivateFixup(
_CONTROL_AREA *ControlArea,
ULONG_PTR ImagePteIndex,
_MMPFN *ProtoPfn,
VOID *FaultingAddress,
UINT64 Diff,
_MMSUPPORT_INSTANCE *VmIrql,
UINT8 a7){
_ETHREAD *CurrentThread;
union {unsigned int LongFlags;_MMSECTION_FLAGS Flags;} *p_u;
__int64 v9;
_SEGMENT *Segment;
_EPROCESS *Process;
_ETHREAD *ForkInProgress;
_MI_PARTITION *v16;
bool v17;
_MMPTE *v18;
__int64 v19;
signed __int64 v20;
UINT64 v21;
UINT64 v22;
INT64 v23;
INT64 v24;
NTSTATUS v25;
__int64 v26;
int v27;
NTSTATUS PfnChannel;
UINT64 v29;
_KTBFLUSH_TYPE v30;
_MMPFN *v31;
_KTBFLUSH_TYPE v32;
__int64 v33;
__int64 v34;
_ETHREAD *v35;
char EffectivePagePriorityThread;
_MMPTE *v37;
VOID *v38;
_MI_READ_IN_PROGRESS_FLAGS v39;
__int64 v40;
__int64 v41;
__int64 v42;
UINT64 v43;
int v44;
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;} v45;
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;} v46;
int v47;
_KTBFLUSH_TYPE v48;
unsigned int v49;
__int64 v50;
_CONTROL_AREA *v51;
INT64 v52;
INT64 v53;
unsigned __int64 v54;
__int64 bf_0;
char v56;
_KEVENT *Event;
_KEVENT *Eventa;
UINT64 ReadInProgressFlags;
char v60[8];
INT16 v61[4];
UINT64 MdlPage;
_MMPTE *PointerPteContents;
VOID *FaultingAddressa;
INT16 v65[4];
_ETHREAD *Thread;
INT16 *v67;
__int64 v68;
__int64 v69;
UINT64 SourcePage;
__int64 v71;
NTSTATUS IsFaultPteIntact;
_CONTROL_AREA *ControlAreaa;
unsigned int ImagePteIndexa;
ImagePteIndexa = (unsigned int)ProtoPfn;
ControlAreaa = *(_CONTROL_AREA **)&ImagePteIndex;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
p_u = &ControlArea->u;
v9 = *(_QWORD *)&ControlArea->u.LongFlags;
Segment = ControlArea->Segment;
v60[0] = 0;
Process = CurrentThread->Tcb.ApcState.Process;
v17 = (*(_BYTE *)(v9 + 184) & 7) == 0;
v67 = (INT16 *)p_u;
v69 = v9;
FaultingAddressa = Segment;
Thread = CurrentThread;
*(_QWORD *)v65 = Process;
if( !v17 || (ForkInProgress = Process->ForkInProgress) == 0i64 )
{
v16 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8i64 * *(unsigned __int16 *)(v9 + 174));
if( (unsigned __int64)Segment < 0xFFFF800000000000ui64 )
{
v17 = (*(_BYTE *)&KeGetCurrentThread()->ApcState.Process->Pcb.SecureState & 1) == 0;
}
else
{
if( (MiFlags & 0x10000) == 0 || (MiFlags & 0x4000) == 0 )
goto LABEL_16;
v17 = ((*((_DWORD *)FaultingAddress + 4) >> 5) & 2) == 0;
}
if( !v17 )
{
v18 = 0i64;
LABEL_13:
PointerPteContents = (_MMPTE *)((char *)MmGetPteBase() + (((unsigned __int64)Segment >> 9) & 0x7FFFFFFFF8i64));
LODWORD(v19) = MI_READ_PTE_LOCK_FREE((INT64)PointerPteContents);
v68 = v19;
v20 = ((_BYTE *)FaultingAddress - (_BYTE *)MmGetPfnDb()) / 48;
SourcePage = v20;
MiObtainFaultCharges(v16, 1ui64, 2);
if( v18 || (unsigned __int64)FaultingAddressa < 0xFFFF800000000000ui64 )
{
LODWORD(v26) = MiSearchNumaNodeTable((PVOID)v20);
v27 = *(_DWORD *)(v26 + 8);
PfnChannel = MiGetPfnChannel((INT64)FaultingAddress);
LODWORD(v29) = MiGetPage(
(ULONG_PTR *)&v16->Core.PartitionId,
(PfnChannel << *(&stru_140C4DB30 + 157)) | (v27 << *(&stru_140C4DB30 + 156)) | *(&stru_140C4DB30 + 66) & (unsigned int)v20,
0i64);
MdlPage = v29;
v22 = v29;
if( v29 == -1i64 )
{
v25 = -1073741670;
goto LABEL_22;
}
}
else
{
*(_QWORD *)v61 = MiReleaseFaultState((INT64)&ControlArea->u, 1u, v60);
__writecr8((unsigned __int8)v60[0]);
LODWORD(v21) = MiAllocateDriverPage();
v22 = v21;
MdlPage = v21;
MiRelockFaultState((INT16 *)&ControlArea->u, v61[0], v23, v24, (INT64)Event);
if( !MiIsFaultPteIntact(ControlArea, (_MMPTE *)ControlArea->Segment, PointerPteContents) )
{
v25 = -1073740748;
LABEL_22:
if( v22 != -1i64 )
MiReleaseFreshPage(&MmGetPfnDb()[v22]);
MiReturnFaultCharges(v16, 1ui64, 2ui64);
if( v18 )
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), v18, 1ui64, v30);
return v25;
}
}
v31 = &MmGetPfnDb()[v22];
MiGetInPageSupportBlock();
v34 = v33;
if( v33 )
{
v35 = Thread;
*(_DWORD *)v61 = 0;
EffectivePagePriorityThread = MiGetEffectivePagePriorityThread(Thread);
v37 = PointerPteContents;
v38 = FaultingAddressa;
*(_DWORD *)(v34 + 192) |= 0x20u;
LOBYTE(v61[0]) = EffectivePagePriorityThread & 7 | 0x48;
v39.EntireFlags = *(_DWORD *)v61;
*(_DWORD *)(v34 + 80) = v40;
*(_QWORD *)(v34 + 88) = v40;
*(_QWORD *)(v34 + 248) = v31;
MiInitializeReadInProgressPfn(v38, &MdlPage, 1ui64, v37, (_KEVENT *)v34, v39);
if( (*(_BYTE *)(v69 + 184) & 7) == 0 )
_InterlockedExchangeAdd64((volatile signed __int64 *)(*(_QWORD *)v65 + 1272i64), 1ui64);
LODWORD(v41) = MI_READ_PTE_LOCK_FREE((INT64)v37);
v71 = v41;
*(_QWORD *)(v34 + 208) = ControlAreaa;
_InterlockedAdd64((volatile signed __int64 *)&ControlAreaa->LockedPages, 1ui64);
v42 = MiReleaseFaultState((INT64)v67, 1u, v60);
--v35->Tcb.SpecialApcDisable;
*(_QWORD *)v65 = v42;
__writecr8((unsigned __int8)v60[0]);
v43 = MdlPage;
MiCopyPage(MdlPage, SourcePage, 0i64, v18 != 0i64 ? 73 : 17);
if( v18 )
{
MiMakeProtectionPfnCompatible((_BYTE *)4, v31);
LODWORD(v45.Long) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v18, v43, v44 | 0xA0000000);
*(_DWORD *)v61 = 0;
v46.Long = v45.Long;
LOBYTE(v47) = MiPteInShadowRange((UINT64)v18);
if( v47 )
{
if( (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v46.Long & 1) != 0 )
v46.Long |= 0x8000000000000000ui64;
v43 = MdlPage;
}
v49 = *(_DWORD *)v61;
v18->u.Long = v46.Long;
if( v49 )
MiWritePteShadow();
v50 = (__int64)(((_QWORD)v18 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
if( (*((_QWORD *)FaultingAddress + 5) & 0x1000000000i64) != 0 || *((__int64 *)FaultingAddress + 1) <= 0 )
{
v51 = ControlAreaa;
MiRelocateImagePfn(ControlAreaa, (VOID *)v50, ImagePteIndexa, v43, Diff, ReadInProgressFlags);
}
else
{
v51 = ControlAreaa;
}
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), v18, 1ui64, v48);
}
else
{
v51 = ControlAreaa;
}
MiDereferenceControlAreaProbe(v51, 0i64);
v25 = 0;
KeGetCurrentIrql();
__writecr8(1ui64);
KiLeaveGuardedRegionUnsafe((__int64)Thread);
MiRelockFaultState(v67, v65[0], v52, v53, (INT64)Eventa);
IsFaultPteIntact = MiIsFaultPteIntact(ControlArea, (_MMPTE *)ControlArea->Segment, PointerPteContents);
v54 = MiLockPageInline(v31);
*((_BYTE *)&v31->u3 + 2) &= ~0x20u;
bf_0 = v31->u2._bf_0;
v31->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
if( (bf_0 & 0x4000000000000000i64) == 0 )
*((_BYTE *)&v31->u3 + 2) |= 0x10u;
if( IsFaultPteIntact == 1 )
{
MiAddLockedPageCharge(v31, 3ui64);
v56 = *(_BYTE *)(&v31->u3 + 1) & 0xF8 | 6;
v31->u2._bf_0 ^= ((v31->u2._bf_0 + 1) ^ v31->u2._bf_0) & 0x3FFFFFFFFFFFFFFFi64;
*((_BYTE *)&v31->u3 + 2) = v56;
if( !v18 && (unsigned __int64)FaultingAddressa >= 0xFFFF800000000000ui64 )
*((_BYTE *)&v31->u3 + 3) |= 8u;
}
else
{
v25 = -1073740748;
}
MiRemoveLockedPageChargeAndDecRef(v31);
_InterlockedAnd64(&v31->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v54);
*(_DWORD *)(v34 + 192) &= ~0x20u;
if( *(int *)(v34 + 176) > 1 )
KeSetEvent((PRKEVENT)(v34 + 56), 0, 0);
MiFreeInPageSupportBlock((_MMINPAGE_SUPPORT *)v34);
return v25;
}
if( v18 )
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), v18, 1ui64, v32);
MiReleaseFreshPage(v31);
MiReturnFaultCharges(v16, 1ui64, 2ui64);
return -1073741670;
}
LABEL_16:
v18 = MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), 1ui64);
if( !v18 )
return -1073741670;
goto LABEL_13;
}
if( ForkInProgress != CurrentThread )
LODWORD(ControlArea->WaitList) |= 4u;
return 297;
}Referenced by:
MiCompleteProtoPteFault