MiSwitchToTransition
NTSTATUS __stdcall MiSwitchToTransition(PVOID Mdl, _MMVAD_SHORT *Vad, _MMVAD_SHORT *CacheAttribute){
_MDL *v4;
unsigned __int64 v5;
unsigned __int8 v6;
__int64 v7;
unsigned int v8;
_MMPFN *v9;
_MMPFN *v10;
unsigned int v11;
int v12;
signed __int32 v13;
UINT64 v14;
UINT64 v15;
UINT64 v16;
_MMSUPPORT_INSTANCE *v17;
unsigned int v18;
__int64 v19;
char *v20;
char v21;
UINT64 BugCheckParameter4;
CHAR v23;
UINT64 v24;
__int64 v25;
int v26;
INT64 v27;
void *v28;
unsigned __int64 v29;
_MMPFN *PfnDb;
__int64 v31;
unsigned __int16 v32;
_MMPFN *v33;
__int64 v34;
unsigned int v35;
__int64 v36;
unsigned __int8 v37;
__int64 v38;
_ETHREAD *v39;
_MMINPAGE_SUPPORT *v40;
_LIST_ENTRY *v41;
char v42;
INT64 v43;
char v44;
INT64 v45;
int v46;
NTSTATUS HasShadow;
int v48;
_MMPFN *v49;
_MMPFN *v50;
__int64 v51;
_MMPFN *v52;
NTSTATUS v53;
_EPROCESS *v54;
UINT8 v56;
char v57;
UINT64 BlinkValue;
volatile signed __int64 *BlinkValuea;
_MI_PFN_CACHE_ATTRIBUTE CacheAttributea;
int v61;
_MI_PARTITION *Partition;
unsigned int v64;
INT64 p_Vm;
char EffectivePagePriorityThread;
INT64 v67;
UINT64 v68;
__int64 v69;
_MMINPAGE_SUPPORT *ReadyInPageBlock;
INT64 v71;
unsigned __int64 v72;
unsigned __int64 StartVa;
_MI_COLOR_BASE ColorBase[4];
_ETHREAD *CurrentThread;
unsigned __int64 v76;
_EPROCESS *Process;
_MI_TB_FLUSH_LIST TbFlushList[48];
CacheAttributea = (int)CacheAttribute;
v4 = (_MDL *)Mdl;
*(_OWORD *)ColorBase = 0i64;
memset(TbFlushList, 0i64, 0xB8u);
v68 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Process = CurrentThread->Tcb.ApcState.Process;
EffectivePagePriorityThread = MiGetEffectivePagePriorityThread(CurrentThread);
ReadyInPageBlock = MiGetReadyInPageBlock(Vad);
StartVa = (unsigned __int64)v4->StartVa;
v5 = (unsigned __int64)MmGetPteBase() + ((StartVa >> 9) & 0x7FFFFFFFF8i64);
p_Vm = (INT64)&Process->Vm;
v61 = 0;
v6 = 0;
MiInitializePageColorBase(&Process->Vm.Instance, 0i64, ColorBase);
BlinkValue = 0xFFFFFFFFFi64;
v9 = 0i64;
v10 = 0i64;
Partition = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8i64 * *(unsigned __int16 *)(v7 + 174));
v11 = MiObtainFaultCharges(Partition, v8, 2);
v64 = v11;
v12 = 0;
if( !v11 )
goto LABEL_14;
while( 1 )
{
v13 = _InterlockedExchangeAdd(*(volatile signed __int32 **)ColorBase, 1u);
LODWORD(v14) = MiGetPage(
(ULONG_PTR *)&Partition->Core.PartitionId,
ColorBase[2] & (unsigned int)v13 | ColorBase[3],
0i64);
v16 = v14;
if( v14 != -1i64 )
{
v9 = &MmGetPfnDb()[v14];
if( MiPageAttributeBatchChangeNeeded(v9, CacheAttributea) == 1 )
{
v9->OriginalPte.u.Long = (unsigned __int64)v10;
v10 = v9;
}
MiSetPfnBlink(v9, BlinkValue, 0i64);
BlinkValue = v16;
++v12;
goto LABEL_8;
}
if( v12 )
break;
MiWaitForFreePage(Partition, v15);
LABEL_8:
if( v12 == v11 )
goto LABEL_11;
}
MiReturnFaultCharges(Partition, v11 - v12, 0i64);
v11 = v12;
v64 = v12;
LABEL_11:
if( v10 )
{
MiSetOriginalPtePfnFromFreeList(&v68);
MiChangePageAttributeBatch(v10, CacheAttributea, (_MMPTE)v68);
}
v4 = (_MDL *)Mdl;
LABEL_14:
v17 = (_MMSUPPORT_INSTANCE *)p_Vm;
v18 = 0;
v69 = -1i64;
v19 = v11;
v20 = 0i64;
v72 = v5 + 8 * v19;
MiLockWorkingSetShared();
v57 = v21;
if( v5 >= v72 )
goto LABEL_59;
v24 = 1i64;
v76 = (char *)v4 - ((StartVa >> 9) & 0x7FFFFFFFF8i64) - (char *)MmGetPteBase();
while( 2 )
{
if( v20 )
{
if( (v5 & 0xFFF) == 0 )
{
MiUnlockPageTableInternal((INT64)v17, (UINT64)v20);
goto LABEL_19;
}
}
else
{
LABEL_19:
v20 = (char *)MmGetPteBase() + ((v5 >> 9) & 0x7FFFFFFFF8i64);
MiLockPageTableInternal((INT64)v17, (UINT64)v20, 0i64);
LODWORD(v25) = MiGetContainingPageTable(v5);
v69 = v25;
v24 = 1i64;
}
MiIsProbeActive((_MMPTE *)v5, v24, 3i64, v23);
if( v26 )
goto LABEL_56;
LODWORD(v27) = MI_READ_PTE_LOCK_FREE(v5);
v67 = v27;
v28 = (void *)v27;
if( (v27 & 1) == 0 )
KeBugCheckEx(0x1Au, (PVOID)0x41200, (PVOID)v5, (PVOID)v27, Mdl);
LODWORD(v29) = MI_READ_PTE_LOCK_FREE((INT64)&v67);
PfnDb = MmGetPfnDb();
BugCheckParameter4 = (UINT64)&PfnDb[(v29 >> 12) & 0xFFFFFFFFFi64];
if( (PfnDb[(v29 >> 12) & 0xFFFFFFFFFi64].u4._bf_0 & 0x4000000000000i64) == 0 )
{
LABEL_30:
v33 = v9;
BlinkValuea = &v9->u2.Lock;
v34 = v9->u2._bf_0 & 0xFFFFFFFFFi64;
if( v34 == 0xFFFFFFFFFi64 )
v9 = 0i64;
else
v9 = &PfnDb[v34];
v71 = v33 - PfnDb;
v35 = ((unsigned __int16)v28 & 0x800) != 0i64 ? 4 : 1;
if( CacheAttributea == MiWriteCombined )
{
v35 |= 0x18u;
}
else if( CacheAttributea == MiNonCached )
{
v35 |= 8u;
}
v67 = MiSwizzleInvalidPte(32i64 * v35);
v33->OriginalPte.u.Long = v67;
if( (v6 & v37) == 0 )
{
v38 = (__int64)ReadyInPageBlock;
v39 = CurrentThread;
ReadyInPageBlock->u1.e1._bf_0 |= 0x20u;
*(_DWORD *)(v38 + 80) = 0;
*(_QWORD *)(v38 + 88) = 0i64;
v6 |= v37;
*(_QWORD *)(v38 + 248) = v33;
*(_QWORD *)(v38 + 152) = v39;
}
v33->u4._bf_0 ^= v36 & (v69 ^ v33->u4._bf_0);
v56 = MiLockPageInline(v33);
v40 = ReadyInPageBlock;
*((_BYTE *)&v33->u3 + 2) |= 0x20u;
if( v40 )
v41 = &v40->ListHead[1];
else
v41 = 0i64;
v33->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = (__int64)v41;
*BlinkValuea &= 0xC000000000000000ui64;
MiAddLockedPageCharge(v33, 1ui64);
v42 = *(_BYTE *)(&v33->u3 + 1) & 0xFA;
v33->PteLong = v5;
*((_BYTE *)&v33->u3 + 2) = v42 | 2;
*((_BYTE *)&v33->u3 + 3) ^= (EffectivePagePriorityThread ^ *((_BYTE *)&v33->u3 + 3)) & 7;
if( (((unsigned __int64)v33->u4._bf_0 >> 39) & 0x3FF) != 0 )
ExAcquireRundownProtectionCacheAware(Partition->Segments.ProbeRundownReference);
_InterlockedAnd64(BlinkValuea, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v56);
MiReturnFaultCharges(Partition, 1ui64, 0i64);
LODWORD(v43) = MiMakeTransitionPte(v71, v35);
v44 = v43;
v67 = v43;
v45 = v43;
LOBYTE(v46) = MiPteInShadowRange(v5);
if( v46 )
{
HasShadow = MiPteHasShadow();
v24 = 1i64;
if( HasShadow )
{
v48 = 1;
if( *(&stru_140C4DB30 + 537) )
goto LABEL_53;
}
else
{
v48 = 0;
if( (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) == 0 )
goto LABEL_53;
}
if( (v44 & 1) != 0 )
v45 |= 0x8000000000000000ui64;
}
else
{
v48 = 0;
v24 = 1i64;
}
LABEL_53:
*(_QWORD *)v5 = v45;
if( v48 )
MiWritePteShadow();
v18 += v24;
v17 = (_MMSUPPORT_INSTANCE *)p_Vm;
*(_QWORD *)(v76 + v5 + 48) = v71;
v5 += 8i64;
if( v5 >= v72 )
goto LABEL_56;
continue;
}
break;
}
if( (*(_QWORD *)(BugCheckParameter4 + 8) | 0x8000000000000000ui64) == v5 )
KeBugCheckEx(0x1Au, (PVOID)0x41300, (PVOID)v5, v28, (PVOID)BugCheckParameter4);
v31 = *(_QWORD *)(BugCheckParameter4 + 40);
v32 = 1;
if( (v31 & 0x1000000000i64) != 0 || (v31 & 0xFFFFFFFFFi64) == 0xFFFFFFFFDi64 )
v32 = 2;
if( *(_WORD *)(BugCheckParameter4 + 32) < v32 )
KeBugCheckEx(0x1Au, (PVOID)0x41301, (PVOID)v5, v28, (PVOID)BugCheckParameter4);
if( *(_WORD *)(BugCheckParameter4 + 32) <= v32 )
{
PfnDb = MmGetPfnDb();
goto LABEL_30;
}
v17 = (_MMSUPPORT_INSTANCE *)p_Vm;
v61 = 1;
LABEL_56:
if( v20 )
MiUnlockPageTableInternal((INT64)v17, (UINT64)v20);
v21 = v57;
v4 = (_MDL *)Mdl;
LABEL_59:
LOBYTE(BugCheckParameter4) = v21;
MiUnlockWorkingSetShared(v17, BugCheckParameter4);
if( v9 )
{
v49 = MmGetPfnDb();
do
{
v50 = v9;
v51 = v9->u2._bf_0 & 0xFFFFFFFFFi64;
if( v51 == 0xFFFFFFFFFi64 )
v9 = 0i64;
else
v9 = &v49[v51];
MiSetOriginalPtePfnFromFreeList(&v50->OriginalPte.u.Long);
MiReleaseFreshPage(v52);
}
while( v9 );
v4 = (_MDL *)Mdl;
}
if( v18 == v64 )
{
v53 = v61;
}
else
{
MiReturnFaultCharges(Partition, v64 - v18, 0i64);
v53 = v61;
if( !v18 )
v53 = 1;
}
v4->ByteCount = v18 << 12;
if( v18 )
{
v54 = Process;
_InterlockedExchangeAdd64((volatile signed __int64 *)&Process->NumberOfPrivatePages, v18);
LOWORD(TbFlushList[1]) = 0;
*(_QWORD *)&TbFlushList[4] = 0i64;
*(_QWORD *)&TbFlushList[6] = 0i64;
TbFlushList[0] = 1;
TbFlushList[2] = 20;
MiInsertTbFlushEntry(TbFlushList, (VOID *)(StartVa & 0xFFFFFFFFFFFFF000ui64), v18, 0i64);
MiFlushTbList(TbFlushList);
v4->Process = v54;
v4->MdlFlags |= 2u;
_InterlockedExchangeAdd64((volatile signed __int64 *)&v54->NumberOfLockedPages, v18);
if( (MmTrackLockedPages & 1) != 0 )
MiAddMdlTracker(v4, v18, 4ui64);
}
return v53;
}Referenced by:
MmRotatePhysicalView