MiTrimSharedPageFromViews
NTSTATUS __stdcall MiTrimSharedPageFromViews(
_MI_VIEW_INFO *ViewInfoHead,
UINT64 ReplaceOk,
UINT64 Flags,
_CONTROL_AREA *ControlArea,
_MMPTE *ProtoPte){
char v5;
_ETHREAD *CurrentThread;
_MMVAD *v8;
NTSTATUS v9;
_MMSUPPORT_INSTANCE *p_AllocatedChannelCount;
_MMPTE *v11;
_MI_VIEW_INFO *v12;
_MMSESSION *v13;
_EPROCESS *v14;
__int64 v15;
UINT64 v16;
NTSTATUS v17;
UINT64 v18;
__int64 v19;
_MMVAD *v20;
unsigned __int64 v21;
UINT64 v22;
unsigned int v23;
UINT64 v24;
void *SessionById;
NTSTATUS v26;
_RTL_BALANCED_NODE *i;
unsigned __int64 v28;
_EX_PUSH_LOCK *SystemSpaceViewLockPointer;
__int64 v30;
__int64 v31;
int v32;
UINT64 v33;
_MMPTE *v34;
VOID *v35;
INT64 v36;
NTSTATUS v37;
_MI_WORKING_SET_TYPE v38;
_MMSUPPORT_INSTANCE *SessionVm;
INT64 v40;
NTSTATUS SystemRegionType;
_QWORD *v42;
_QWORD *v43;
__int64 v44;
unsigned __int64 v45;
__int64 v46;
unsigned __int64 v47;
unsigned __int64 v48;
bool v49;
_KTBFLUSH_TYPE v50;
char v51;
_MMVAD *Address;
union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v53;
_CONTROL_AREA *v54;
unsigned __int64 FirstPrototypePte;
__int64 StartingVpn;
_MMPTE *v57;
__int64 v58;
_MMPTE *PteBase;
INT64 *v60;
_MMPTE *v61;
INT64 *v62;
INT64 v63;
char v64;
unsigned __int64 v65;
UINT8 v66;
wchar_t *v67;
_MMPFN *v68;
int v69;
__int16 v70;
_MMPFN *v71;
__int64 v72;
UINT8 v73;
char v74;
__int64 v75;
int v76;
char v77;
_MMPTE *v78;
__int64 v79;
__int64 v80;
NTSTATUS locked;
UINT64 v82;
_EX_PUSH_LOCK *v83;
_ADAPTER_OBJECT *v84;
_MI_VIEW_INFO *v85;
_ADAPTER_OBJECT *v86;
__int64 v88;
char WsIrql;
PADAPTER_OBJECT DmaAdapter;
_MI_VIEW_INFO *v91;
__int64 v92;
__int64 v93;
NTSTATUS v94;
unsigned __int64 v95;
_MMPTE *v96;
_SUBSECTION *Subsection;
UINT64 v98;
int v99;
NTSTATUS v100;
int v101;
_MI_VIEW_INFO *P;
INT64 v104;
_MMSESSION *v105;
PVOID OpaqueSession;
_MMPTE *v107;
INT64 *v108;
_KLOCK_QUEUE_HANDLE LockHandle;
INT64 v110[16];
_KAPC_STATE ApcState;
_MI_TB_FLUSH_LIST TbFlushList[48];
char WsleFlushList[184];
v107 = ProtoPte;
v5 = Flags;
v101 = ReplaceOk;
v104 = 0i64;
v108 = 0i64;
Subsection = 0i64;
memset(&ApcState, 0, sizeof(ApcState));
memset(WsleFlushList, 0i64, sizeof(WsleFlushList));
memset(TbFlushList, 0i64, 0xB8u);
memset(&LockHandle, 0, sizeof(LockHandle));
memset(v110, 0i64, sizeof(v110));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v8 = 0i64;
WsIrql = 17;
v9 = 0;
v88 = (__int64)CurrentThread;
p_AllocatedChannelCount = 0i64;
v94 = 0;
v11 = 0i64;
v96 = 0i64;
if( !ViewInfoHead )
return v9;
while( 1 )
{
v12 = ViewInfoHead;
OpaqueSession = 0i64;
ViewInfoHead = *(_MI_VIEW_INFO **)ViewInfoHead;
P = v12;
v13 = 0i64;
v91 = ViewInfoHead;
v14 = (_EPROCESS *)*((_QWORD *)v12 + 1);
v15 = *((_QWORD *)v12 + 4);
v16 = *((_QWORD *)v12 + 2);
DmaAdapter = (PADAPTER_OBJECT)v14;
v98 = *((_QWORD *)v12 + 3);
v92 = v15;
v105 = 0i64;
v100 = 0;
v99 = 0;
if( v14 && v14 != KeGetCurrentThread()->ApcState.Process )
{
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)&stru_140C4DB30 + 522, &LockHandle);
v100 = MiPrepareAttachThread(v14, &v14->Vm.Instance);
v17 = v100;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
if( v17 )
{
KeForceAttachProcess(v14);
v11 = v96;
LABEL_6:
v8 = 0i64;
LABEL_7:
v18 = v16 - 4096;
v19 = v92 - 4096;
v20 = 0i64;
v21 = v18 >> 12;
v22 = v18 + 4096;
if( v22 < v98 )
{
while( 1 )
{
v95 = ++v21;
v93 = v19 + 4096;
if( !p_AllocatedChannelCount || (_MMPTE *)((char *)MmGetPdeBase() + ((v22 >> 18) & 0x3FFFFFF8)) == v11 )
{
v34 = v96;
}
else
{
if( *(_DWORD *)&WsleFlushList[12] != (_DWORD)v8 )
{
LODWORD(v31) = MiFreeWsleList(p_AllocatedChannelCount, (_MMWSLE_FLUSH_LIST *)WsleFlushList, 0i64);
v32 = v94;
if( v31 )
v32 = 277;
v94 = v32;
}
MiFlushTbList(TbFlushList);
if( DmaAdapter )
{
if( v11 )
MiUnlockPageTableInternal((INT64)p_AllocatedChannelCount, (UINT64)v11);
LOBYTE(v33) = WsIrql;
MiUnlockWorkingSetShared(p_AllocatedChannelCount, v33);
}
else
{
MiUnlockSystemVa((INT64)v110);
}
v8 = 0i64;
v34 = 0i64;
v96 = 0i64;
p_AllocatedChannelCount = 0i64;
}
if( !DmaAdapter )
break;
if( !p_AllocatedChannelCount )
{
p_AllocatedChannelCount = (_MMSUPPORT_INSTANCE *)&DmaAdapter[2].AllocatedChannelCount;
if( (v5 & 1) != 0 )
{
v50 = MiTbFlushType((_MMSUPPORT_INSTANCE *)&DmaAdapter[2].AllocatedChannelCount);
LOWORD(TbFlushList[1]) = 0;
TbFlushList[0] = v50;
*(_QWORD *)&TbFlushList[2] = 20i64;
*(_QWORD *)&TbFlushList[4] = v8;
*(_QWORD *)&TbFlushList[6] = v8;
}
v20 = v8;
MiLockWorkingSetShared();
WsIrql = v51;
v8 = 0i64;
}
if( v20
&& v21 >= (v20->Core.StartingVpn | ((unsigned __int64)v20->Core.StartingVpnHigh << 32))
&& v21 <= (v20->Core.EndingVpn | ((unsigned __int64)v20->Core.EndingVpnHigh << 32)) )
{
v54 = ControlArea;
}
else
{
Address = MiLocateAddress((VOID *)v22);
v20 = Address;
if( !Address )
goto LABEL_122;
v53.LongFlags = (unsigned int)Address->Core.u;
if( (v53.LongFlags & 0x100000) != 0 )
goto LABEL_122;
v54 = ControlArea;
if( (ControlArea->u.LongFlags & 0x20) == 0 && (v53.LongFlags & 0x70) != 0 )
goto LABEL_122;
Subsection = Address->Subsection;
if( Subsection->ControlArea != ControlArea )
goto LABEL_122;
}
if( (v54->u.LongFlags & 0x20) != 0 )
{
FirstPrototypePte = (unsigned __int64)v20->FirstPrototypePte;
if( (unsigned __int64)v107 < FirstPrototypePte )
goto LABEL_122;
StartingVpn = v20->Core.StartingVpn;
if( (unsigned __int64)v107 >= FirstPrototypePte
- 8 * (StartingVpn | ((unsigned __int64)v20->Core.StartingVpnHigh << 32))
+ 8
* ((v20->Core.EndingVpn | ((unsigned __int64)v20->Core.EndingVpnHigh << 32))
+ 1) )
goto LABEL_122;
v22 = ((__int64)((__int64)v107 - FirstPrototypePte) >> 3 << 12)
+ ((StartingVpn | ((unsigned __int64)v20->Core.StartingVpnHigh << 32)) << 12);
}
else
{
MiGetProtoPteAddress();
if( !v57 )
goto LABEL_122;
if( !Subsection )
goto LABEL_122;
LODWORD(v58) = MiStartingOffset(Subsection, v57, 0xFFFFFFFFui64);
if( v93 != v58 )
goto LABEL_122;
v8 = 0i64;
}
PteBase = MmGetPteBase();
v60 = (INT64 *)((char *)PteBase + ((v22 >> 9) & 0x7FFFFFFFF8i64));
v61 = (_MMPTE *)((char *)PteBase + (((unsigned __int64)v60 >> 9) & 0x7FFFFFFFF8i64));
if( v34 != v61 )
{
if( v34 )
{
v22 -= 4096i64;
--v21;
v19 = v93 - 4096;
goto LABEL_121;
}
v96 = MiLockLowestValidPageTable((INT64)p_AllocatedChannelCount, v60, &v108);
v49 = v96 == v61;
LABEL_106:
if( !v49 )
goto LABEL_122;
}
LABEL_107:
v62 = (INT64 *)((char *)MmGetPteBase() + ((v22 >> 9) & 0x7FFFFFFFF8i64));
LODWORD(v63) = MI_READ_PTE_LOCK_FREE((INT64)v62);
v104 = v63;
v64 = v63;
if( (v63 & 1) != 0 )
{
LODWORD(v65) = MI_READ_PTE_LOCK_FREE((INT64)&v104);
v68 = &MmGetPfnDb()[(v65 >> 12) & 0xFFFFFFFFFi64];
if( (v5 & 8) == 0 || (v64 & 0x42) == 0 && (*(_BYTE *)(&v68->u3 + 1) & 0x10) == 0 )
{
LOBYTE(v69) = MI_PFN_IS_PROTO(
(_UNICODE_STRING *)v68,
(_UNICODE_STRING *)v68->OriginalPte.u.Long,
v66,
v67);
v8 = 0i64;
if( !v69 )
goto LABEL_145;
v72 = v70 & 0x400;
if( (v5 & 1) != 0 )
{
if( !v72 || (v64 & 0x42) == 0 )
goto LABEL_145;
v73 = MiLockPageInline(v71);
v74 = *((_BYTE *)&v68->u3 + 2);
if( (v74 & 0x10) == 0 )
*((_BYTE *)&v68->u3 + 2) = v74 | 0x10;
_InterlockedAnd64(&v68->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v73);
v104 &= 0xFFFFFFFFFFFFFFBDui64;
MiWriteValidPteNewProtection(v62, v104);
MiInsertTbFlushEntry(TbFlushList, (VOID *)v22, 1ui64, 0i64);
}
else
{
if( !v72 && (ControlArea->u.LongFlags & 0x80u) != 0 )
goto LABEL_145;
v77 = MiGetWsleContents((INT64)v71, v22) & 0xF;
if( P[11] == 3 && v77 == 9 )
goto LABEL_145;
if( v77 == 8 || (v5 & 0x10) != 0 )
{
if( (v5 & 8) == 0 && v101 != (_DWORD)v8 && (p_AllocatedChannelCount->Flags._bf_0 & 7) != 2 )
{
locked = MiReplaceLockedPage((_MMPFN *)p_AllocatedChannelCount, v68, (_KTBFLUSH_TARGET)v22);
v8 = 0i64;
if( locked )
goto LABEL_145;
}
LABEL_144:
v94 = 277;
LABEL_145:
v21 = v95;
goto LABEL_120;
}
if( *(&stru_140C4DB30 + 654) != (_DWORD)v8 )
{
MI_WSLE_LOG_ACCESS(p_AllocatedChannelCount, (_MMWSLE *)v62, v78);
LODWORD(v8) = 0;
}
if( *(_DWORD *)&WsleFlushList[12] == (_DWORD)v8 )
{
*(_DWORD *)WsleFlushList = MiTbFlushType(p_AllocatedChannelCount);
*(_QWORD *)&WsleFlushList[8] = 20i64;
*(_WORD *)&WsleFlushList[4] = 4;
*(_QWORD *)&WsleFlushList[16] = v79;
*(_QWORD *)&WsleFlushList[24] = v79;
}
MiInsertTbFlushEntry((_MI_TB_FLUSH_LIST *)WsleFlushList, (VOID *)v22, 1ui64, 0i64);
if( *(_DWORD *)&WsleFlushList[12] == *(_DWORD *)&WsleFlushList[8] )
{
LODWORD(v80) = MiFreeWsleList(p_AllocatedChannelCount, (_MMWSLE_FLUSH_LIST *)WsleFlushList, 0i64);
v8 = 0i64;
if( v80 )
goto LABEL_144;
goto LABEL_145;
}
}
}
v21 = v95;
}
v8 = 0i64;
LABEL_120:
v19 = v93;
LABEL_121:
v22 += 4096i64;
if( v22 >= v98 )
goto LABEL_122;
v11 = v96;
}
if( p_AllocatedChannelCount )
{
LABEL_67:
SystemRegionType = MiGetSystemRegionType(v22);
if( P[11] )
goto LABEL_107;
if( SystemRegionType != 8 )
goto LABEL_122;
LODWORD(v42) = MiGetSystemCacheReverseMap(v22);
v43 = v42;
if( !v42 )
goto LABEL_122;
LODWORD(v44) = MiGetSystemCacheReverseMap(v22);
v45 = *(_QWORD *)(v44 + 24) & 0xFFFFFFFFFFFFFFFEui64;
if( (*(_QWORD *)(v44 + 24) & 1) == 0 )
v45 = *(_QWORD *)(v44 + 24);
if( p_AllocatedChannelCount != (_MMSUPPORT_INSTANCE *)(*(_QWORD *)(*(&stru_140C4DB30 + 267)
+ 8i64
* (*(_WORD *)(*(_QWORD *)v45 + 60i64) & 0x3FF))
+ 7232i64) )
goto LABEL_122;
v46 = v43[2];
if( !v46 )
goto LABEL_122;
v47 = v43[3];
Subsection = (_SUBSECTION *)v47;
if( (v47 & 1) != 0 )
{
v47 &= ~1ui64;
Subsection = (_SUBSECTION *)v47;
}
if( *(_CONTROL_AREA **)v47 != ControlArea )
{
LABEL_122:
ViewInfoHead = v91;
goto LABEL_123;
}
v48 = v43[4];
if( (v46 & 3) == 0 )
v48 = 4 * (v48 & 0xFFFFFFFFFFFF0000ui64);
v49 = v48 + (v22 & 0x3FFFF) == v93;
goto LABEL_106;
}
v37 = MiGetSystemRegionType(v22);
switch( v37 )
{
case 8:
v38 = MiWorkingSetTypeSystemCache;
break;
case 1:
SessionVm = MiGetSessionVm(v36, (INT64)v35, 1);
LABEL_62:
p_AllocatedChannelCount = SessionVm;
if( !SessionVm )
{
LABEL_155:
v30 = v88;
ViewInfoHead = v91;
goto LABEL_156;
}
if( !MiSynchronizeSystemVa((INT64)SessionVm, v22, v40, 0i64, (INT64)v110) )
goto LABEL_122;
p_AllocatedChannelCount = (_MMSUPPORT_INSTANCE *)v110[3];
if( (v5 & 1) != 0 )
{
TbFlushList[0] = MiTbFlushType((_MMSUPPORT_INSTANCE *)v110[3]);
*(_QWORD *)&TbFlushList[2] = 20i64;
LOWORD(TbFlushList[1]) = 0;
*(_QWORD *)&TbFlushList[4] = 0i64;
*(_QWORD *)&TbFlushList[6] = 0i64;
}
v96 = (_MMPTE *)((char *)MmGetPdeBase() + ((v22 >> 18) & 0x3FFFFFF8));
goto LABEL_67;
case 6:
v38 = MiWorkingSetTypePagedPool;
break;
case 12:
v38 = MiWorkingSetTypeSystemViews;
break;
default:
goto LABEL_155;
}
SessionVm = MiGetAnyMultiplexedVm(v38, v35);
goto LABEL_62;
}
LABEL_123:
v14 = (_EPROCESS *)DmaAdapter;
goto LABEL_124;
}
goto LABEL_124;
}
v23 = v12[11];
if( v23 < 2 )
goto LABEL_7;
v24 = (unsigned int)v12[10];
if( (_DWORD)v24 == -1 )
{
v13 = &Session;
}
else
{
if( (_DWORD)v24 == -2 )
goto LABEL_18;
SessionById = MmGetSessionById(v24);
OpaqueSession = SessionById;
if( !SessionById )
goto LABEL_124;
if( MmAttachSession(SessionById, &ApcState) < 0 )
{
MmQuitNextSession((_ADAPTER_OBJECT *)OpaqueSession);
OpaqueSession = 0i64;
goto LABEL_124;
}
CurrentThread = (_ETHREAD *)v88;
v23 = P[11];
v13 = (_MMSESSION *)((char *)KeGetCurrentThread()->ApcState.Process->Session + 192);
}
v105 = v13;
LABEL_18:
if( v23 == 3 )
{
v26 = MiGetSystemRegionType(v16);
if( P[10] == -2 )
{
if( v26 != 1 )
goto LABEL_6;
}
else if( v26 == 1 )
{
goto LABEL_6;
}
}
else if( (v5 & 6) == 0 )
{
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockSharedEx(v13->SystemSpaceViewLockPointer, 0i64);
v8 = 0i64;
for( i = v105->ViewRoot.Root; ; i = i->Children[0] )
{
while( 1 )
{
if( !i )
goto LABEL_34;
v28 = i[3].ParentValue & 0xFFFFFFFFFFFFF000ui64;
if( (_RTL_BALANCED_NODE *)v16 < (_RTL_BALANCED_NODE *)((char *)i[1].Children[1] + v28) )
break;
i = i->Children[1];
}
if( v16 >= v28 )
break;
}
Subsection = (_SUBSECTION *)i[2].Children[0];
if( Subsection->ControlArea != ControlArea || v16 + ((__int64)i[1].Children[0] << 12) - v15 != v28 )
{
LABEL_34:
SystemSpaceViewLockPointer = v105->SystemSpaceViewLockPointer;
if( _InterlockedCompareExchange64(&SystemSpaceViewLockPointer->_bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(SystemSpaceViewLockPointer);
KeAbPostRelease(SystemSpaceViewLockPointer);
v30 = v88;
KiLeaveGuardedRegionUnsafe(v88);
goto LABEL_125;
}
v99 = 1;
goto LABEL_7;
}
LABEL_124:
v30 = v88;
LABEL_125:
if( p_AllocatedChannelCount )
{
if( *(_DWORD *)&WsleFlushList[12] )
{
LODWORD(v75) = MiFreeWsleList(p_AllocatedChannelCount, (_MMWSLE_FLUSH_LIST *)WsleFlushList, 0i64);
v76 = v94;
if( v75 )
v76 = 277;
v94 = v76;
}
MiFlushTbList(TbFlushList);
if( v14 )
{
v82 = (UINT64)v96;
if( v96 )
MiUnlockPageTableInternal((INT64)p_AllocatedChannelCount, (UINT64)v96);
LOBYTE(v82) = WsIrql;
MiUnlockWorkingSetShared(p_AllocatedChannelCount, v82);
}
else
{
MiUnlockSystemVa((INT64)v110);
}
v96 = 0i64;
p_AllocatedChannelCount = 0i64;
}
LABEL_156:
if( v99 == 1 )
{
v83 = v105->SystemSpaceViewLockPointer;
if( _InterlockedCompareExchange64(&v83->_bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(v83);
KeAbPostRelease(v83);
KiLeaveGuardedRegionUnsafe(v30);
}
v84 = (_ADAPTER_OBJECT *)OpaqueSession;
if( OpaqueSession )
{
MmDetachSession(OpaqueSession, &ApcState);
MmQuitNextSession(v84);
}
else if( v100 == 1 )
{
KeForceDetachProcess(&ApcState, 0);
MiAttachThreadDone((_MMSUPPORT_INSTANCE *)&DmaAdapter[2].AllocatedChannelCount);
}
if( DmaAdapter )
HalPutDmaAdapter(DmaAdapter);
ExFreePoolWithTag(P, 0);
if( v101 == 1 && (v107->u.Long & 1) == 0 )
break;
v8 = 0i64;
if( !ViewInfoHead )
return v94;
v11 = v96;
CurrentThread = (_ETHREAD *)v88;
}
while( ViewInfoHead )
{
v85 = ViewInfoHead;
ViewInfoHead = *(_MI_VIEW_INFO **)ViewInfoHead;
v86 = (_ADAPTER_OBJECT *)*((_QWORD *)v85 + 1);
if( v86 )
HalPutDmaAdapter(v86);
ExFreePoolWithTag(v85, 0);
}
return 0;
}Referenced by:
MiTrimSection