MmOutSwapVirtualAddresses
__int64 __fastcall MmOutSwapVirtualAddresses(_EPROCESS *Process, unsigned __int64 *a2, __int64 a3, void ***a4){
_ETHREAD *CurrentThread;
__int64 v7;
_MI_PARTITION *v9;
unsigned int BestOutswapPagefile;
UINT64 v11;
__int64 v12;
UINT64 v13;
unsigned int i;
int v15;
INT64 v16;
_QWORD *v17;
_EPROCESS *v18;
__int64 v19;
unsigned __int64 *v20;
INT64 v21;
RTL_BALANCED_NODE *Address;
int v23;
_EPROCESS *v24;
UINT8 **WorkingSetSwapSupport;
_ETHREAD *v26;
unsigned int SessionId;
char v28;
int v29;
bool v30;
__int64 v31;
unsigned __int64 v32;
__int64 v33;
UINT64 TotalPagesOut;
UINT64 SwapFileNumber;
int v37;
_EPROCESS *Processa;
_ETHREAD *v39;
void ***v40;
INT64 result[5];
UINT64 v42[11];
__int128 v43;
__int128 v44;
__int128 v45;
__int64 v46;
TotalPagesOut = 0i64;
LODWORD(SwapFileNumber) = 0;
v46 = 0i64;
v44 = 0i64;
Processa = Process;
v45 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v7 = *((unsigned __int16 *)Process + 919);
v40 = a4;
v39 = CurrentThread;
v9 = *(_MI_PARTITION **)(qword_140C4E388 + 8 * v7);
BestOutswapPagefile = MiFindBestOutswapPagefile(v9, &SwapFileNumber);
if( BestOutswapPagefile == 16 )
return 3221225799i64;
LODWORD(v44) = 2;
EtwTraceWorkingSetSwap(Process, 2, (__int64)&v44);
MiValidateMemoryRangeEntries((MEMORY_RANGE_ENTRY *)a2, a3, &TotalPagesOut);
memset((INT64)result, 0i64);
--*((_WORD *)CurrentThread + 243);
v11 = (UINT64)v9 + 1128;
ExAcquirePushLockExclusiveEx((UINT64)v9 + 1128, 0i64);
v13 = TotalPagesOut;
for( i = SwapFileNumber; ; BestOutswapPagefile = i )
{
v15 = MiReserveWorkingSetSwapSpace((__int64)v9, v42, v12, BestOutswapPagefile, i, v13);
if( v15 >= 0 )
break;
if( i >= 0x10 )
goto LABEL_49;
v15 = MiExtendWorkingSetSwapPagefile(v9, v13, i);
if( v15 < 0 )
goto LABEL_49;
}
LODWORD(v16) = MiAllocateWorkingSetSwapSupport(v13);
v17 = (_QWORD *)v16;
if( !v16 )
{
v15 = -1073741670;
LABEL_49:
v24 = Processa;
goto LABEL_21;
}
v18 = Processa;
v19 = (__int64)v39;
result[0] = v16;
result[3] = (INT64)v9;
result[2] = (INT64)Processa + 1664;
TotalPagesOut = (UINT64)Processa + 1664;
--*((_WORD *)v39 + 243);
ExAcquirePushLockSharedEx((UINT64)v18 + 1224, 0i64);
*(_BYTE *)(v19 + 1304) |= 2u;
v20 = &a2[2 * a3];
if( a2 < v20 )
{
v21 = TotalPagesOut;
do
{
Address = MiLocateAddress(*a2);
if( Address )
{
v23 = (int)Address[2].Children[0];
if( (v23 & 0x70) == 0
&& ((v23 & 0x100000) == 0 || (v23 & 0x400000) == 0 && (v23 & 0xC0000u) < 0x80000)
&& (v23 & 0x100000) != 0
&& (HIDWORD(Address[1].Left) | ((unsigned __int64)BYTE1(Address[1].Right) << 32)) >= (*a2 + a2[1] - 1) >> 12 )
{
MiOutSwapWorkingSet(v21, (INT64)Address, *a2, *a2 + a2[1] - 1, (INT64)result);
}
}
a2 += 2;
}
while( a2 < v20 );
v11 = (UINT64)v9 + 1128;
}
v24 = Processa;
UNLOCK_ADDRESS_SPACE_SHARED(v19, (__int64)Processa);
if( v17[2] < v13 )
{
WorkingSetSwapSupport = MiReAllocateWorkingSetSwapSupport((INT64)v17);
if( WorkingSetSwapSupport )
{
ExFreePoolWithTag(v17, 0);
v17 = WorkingSetSwapSupport;
}
}
v15 = 0;
TotalPagesOut = v17[3];
*v40 = (void **)v17;
LABEL_21:
MiFreeReservationRuns((INT64)v9, (UINT64)v42);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v11, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v11);
v37 = 0;
v26 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v11) == 1 )
SessionId = MmGetSessionIdEx(*((_QWORD *)v26 + 23));
else
SessionId = -1;
--*((_WORD *)v26 + 243);
v28 = ++*((_BYTE *)v26 + 794);
v29 = (*((char *)v26 + 792) | *((char *)v26 + 870)) ^ 0x3F;
while( 1 )
{
v30 = !_BitScanReverse((unsigned int *)&v31, v29);
HIDWORD(SwapFileNumber) = v31;
if( v30 )
break;
v32 = *((_QWORD *)v26 + 100) + 96 * v31;
v29 &= ~(1 << v31);
if( (*(_BYTE *)(v32 + 26) & 1) != 0
&& (*(_DWORD *)(v32 + 32) & 1) == 0
&& (*(_QWORD *)(v32 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v11 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v32 + 40) == SessionId )
{
*(_BYTE *)(v32 + 26) &= ~1u;
if( *(_QWORD *)(v32 + 32) )
{
if( v32 )
{
*(_BYTE *)(v32 + 32) |= 2u;
if( *(__int64 *)(v32 + 32) < 0 )
KiAbEntryRemoveFromTree(v32);
v37 = *(_DWORD *)(v32 + 88) & 0x1FFFF;
*(_DWORD *)(v32 + 88) &= 0xFFFE0000;
*(_BYTE *)(v32 + 25) &= ~1u;
*(_QWORD *)(v32 + 32) = 0i64;
v33 = (__int64)(v32 - *((_QWORD *)v26 + 100)) / 96;
if( v28 == 1 )
*((_BYTE *)v26 + 792) |= 1 << v33;
else
_InterlockedOr8((volatile signed __int8 *)v26 + 870, 1 << v33);
goto LABEL_37;
}
break;
}
}
}
if( (*((_DWORD *)v26 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v26, v11, SessionId, 0i64);
LABEL_37:
--*((_BYTE *)v26 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v26, v11, (unsigned int *)&v37);
v30 = (*((_WORD *)v26 + 243))++ == 0xFFFF;
if( v30 && *((_ETHREAD **)v26 + 19) != (_ETHREAD *)((char *)v26 + 152) )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)v39);
*(_QWORD *)&v44 = TotalPagesOut;
*((_QWORD *)&v44 + 1) = v42[10];
v45 = v43;
LODWORD(v46) = v15;
EtwTraceWorkingSetSwap(v24, 0, (__int64)&v44);
return(unsigned int)v15;
}Referenced by:
SmPerformStoreSwapOperation