MmOutSwapWorkingSet
__int64 __fastcall MmOutSwapWorkingSet(_EPROCESS *Process, int a2){
char *v2;
unsigned int v5;
INT64 v6;
int v7;
unsigned int SessionId;
unsigned int BestOutswapPagefile;
INT64 v10;
INT64 v11;
INT64 *v12;
unsigned __int64 v13;
INT64 WorkingSetSwapSupport;
INT64 v15;
__int64 v16;
unsigned int a5;
unsigned __int64 v18;
__int64 v19;
unsigned __int64 v20;
_EPROCESS *v21;
bool v22;
_ETHREAD *v23;
_QWORD *v24;
unsigned __int64 v25;
_QWORD *v26;
INT64 v27;
unsigned __int64 v28;
UINT8 **v29;
INT64 v30;
int v31;
INT64 *v32;
unsigned __int64 v33;
INT64 v34;
INT64 *SharedVm;
ULONG_PTR v36;
UINT64 v37;
_ETHREAD *v38;
char v39;
int v40;
__int64 v41;
unsigned __int64 v42;
__int64 v43;
PVOID v44;
__int64 v46;
int v47;
int v48;
UINT8 **v49;
int v50;
UINT64 ExtendPages;
UINT64 SwapFileNumber;
__int64 v53;
INT64 v54;
_ETHREAD *CurrentThread;
PEX_SPIN_LOCK SpinLock;
PVOID P;
_EPROCESS *Processa;
INT64 result[4];
int v60;
UINT64 v61[11];
__int128 v62;
int v63;
__int128 v64;
__int128 v65;
__int64 v66;
LODWORD(SwapFileNumber) = 0;
v2 = (char *)Process + 1664;
Processa = Process;
v66 = 0i64;
v64 = 0i64;
v65 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
ExtendPages = 0i64;
v5 = 0;
P = 0i64;
memset((INT64)result, 0i64);
v6 = *(_QWORD *)(qword_140C4E388 + 8i64 * *((unsigned __int16 *)v2 + 87));
v7 = v64;
if( a2 )
v7 = 1;
v54 = *(_QWORD *)(qword_140C4E388 + 8i64 * *((unsigned __int16 *)v2 + 87));
LODWORD(v64) = v7;
result[3] = v6;
SessionId = -1;
v50 = -1;
if( SmStoreExistsForProcess((__int64)Process) )
{
LODWORD(v64) = v64 | 4;
v5 = 2;
v60 = -1;
}
EtwTraceWorkingSetSwap(Process, 2, (__int64)&v64);
BestOutswapPagefile = MiFindBestOutswapPagefile((_MI_PARTITION *)v6, &SwapFileNumber);
if( BestOutswapPagefile == 16 )
{
v31 = -1073741497;
}
else
{
LODWORD(v10) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
v11 = v10;
if( v10 )
{
v5 |= 1u;
--*((_WORD *)CurrentThread + 243);
ExAcquirePushLockExclusiveEx(v6 + 1128, 0i64);
v12 = (INT64 *)(v6 + 1136);
SpinLock = (PEX_SPIN_LOCK)(v6 + 1136);
v13 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)(v6 + 1136));
WorkingSetSwapSupport = MiGetWorkingSetSwapSupport((INT64)v2);
if( WorkingSetSwapSupport )
{
if( WorkingSetSwapSupport == 1 )
{
v31 = -1073740682;
}
else
{
v31 = -1073741791;
if( WorkingSetSwapSupport == 2 )
v31 = -1073741558;
}
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)SpinLock);
__writecr8(v13);
v6 = v54;
}
else
{
MiGetSharedVm(v15)[3] = 1i64;
ExReleaseSpinLockExclusiveFromDpcLevel(v12);
__writecr8(v13);
a5 = SwapFileNumber;
while( 1 )
{
v18 = *((_QWORD *)v2 + 16);
ExtendPages = v18;
if( !v18 )
{
v31 = -1073741779;
goto LABEL_37;
}
if( v60 == -1 )
break;
v31 = MiReserveWorkingSetSwapSpace(v54, v61, v16, BestOutswapPagefile, a5, v18);
if( v31 >= 0 )
{
v18 = ExtendPages;
break;
}
if( a5 < 0x10 )
{
BestOutswapPagefile = a5;
v31 = MiExtendWorkingSetSwapPagefile((_MI_PARTITION *)v54, ExtendPages, a5);
if( v31 >= 0 )
continue;
}
goto LABEL_37;
}
LODWORD(v19) = MiAllocateWorkingSetSwapSupport(v18);
*(_QWORD *)v11 = v19;
if( !v19 )
goto LABEL_85;
if( v60 != -1 )
*(_DWORD *)(v19 + 32) |= 1u;
v20 = 0i64;
if( !a2 )
goto LABEL_15;
v20 = *((_QWORD *)v2 + 17);
if( v20 - *((_QWORD *)v2 + 18) <= v20 )
v20 = *((_QWORD *)v2 + 17) - *((_QWORD *)v2 + 18);
if( v20 && (LODWORD(v46) = MiAllocateWorkingSetSwapSupport(v20), (*(_QWORD *)(v11 + 8) = v46) == 0i64) )
{
LABEL_85:
v31 = -1073741670;
}
else
{
LABEL_15:
v21 = Processa;
result[0] = *(_QWORD *)v11;
result[1] = *(_QWORD *)(v11 + 8);
v22 = *((_QWORD *)Processa + 286) == 0i64;
result[2] = (INT64)v2;
if( !v22 )
{
v47 = VmCheckLargePageInswap((INT64)Processa);
v48 = v63;
if( v47 )
v48 = 1;
v63 = v48;
}
v23 = CurrentThread;
--*((_WORD *)CurrentThread + 243);
ExAcquirePushLockSharedEx((UINT64)v21 + 1224, 0i64);
*((_BYTE *)v23 + 1304) |= 2u;
if( (*((_DWORD *)v21 + 281) & 0x20) != 0 )
{
UNLOCK_ADDRESS_SPACE_SHARED((__int64)v23, (__int64)v21);
v31 = -1073741558;
}
else
{
v24 = (_QWORD *)*((_QWORD *)v21 + 251);
v25 = 0i64;
while( v24 )
{
v25 = (unsigned __int64)v24;
v24 = (_QWORD *)*v24;
}
while( v25 )
{
if( !MiVadMapsLargeImage(v25) && MiVadSupportsPrivateCommit(v27) )
MiOutSwapWorkingSet(
(INT64)v2,
v25,
(*(unsigned int *)(v25 + 24) | ((unsigned __int64)*(unsigned __int8 *)(v25 + 32) << 32)) << 12,
((*(unsigned int *)(v25 + 28) | ((unsigned __int64)*(unsigned __int8 *)(v25 + 33) << 32)) << 12) | 0xFFF,
(INT64)result);
v26 = *(_QWORD **)(v25 + 8);
v28 = v25;
if( v26 )
{
do
{
v25 = (unsigned __int64)v26;
v26 = (_QWORD *)*v26;
}
while( v26 );
}
else
{
while( 1 )
{
v25 = *(_QWORD *)(v25 + 16) & 0xFFFFFFFFFFFFFFFCui64;
if( !v25 || *(_QWORD *)v25 == v28 )
break;
v28 = v25;
}
}
}
UNLOCK_ADDRESS_SPACE_SHARED((__int64)v23, (__int64)v21);
if( *(_QWORD *)(*(_QWORD *)v11 + 16i64) < ExtendPages )
{
v29 = MiReAllocateWorkingSetSwapSupport(*(_QWORD *)v11);
if( v29 )
{
ExFreePoolWithTag(*(PVOID *)v11, 0);
*(_QWORD *)v11 = v29;
}
}
v30 = *(_QWORD *)(v11 + 8);
if( v30 )
{
if( *(_QWORD *)(v30 + 16) < v20 )
{
v49 = MiReAllocateWorkingSetSwapSupport(v30);
if( v49 )
{
ExFreePoolWithTag(*(PVOID *)(v11 + 8), 0);
*(_QWORD *)(v11 + 8) = v49;
}
}
}
ExtendPages = *(_QWORD *)(*(_QWORD *)v11 + 24i64);
MiGetKernelStackSwapSupport(v11, (INT64)v21);
if( v5 >= 2 )
P = MiReAllocateWorkingSetSwapSupport(*(_QWORD *)v11);
v5 |= 4u;
v31 = 0;
}
}
LABEL_37:
v32 = (INT64 *)SpinLock;
v33 = ExAcquireSpinLockExclusive(SpinLock);
if( MiGetWorkingSetSwapSupport((INT64)v2) == 1 )
{
SharedVm = MiGetSharedVm(v34);
if( v5 < 4 )
{
SharedVm[3] = 0i64;
}
else
{
SharedVm[3] = v11;
v11 = 0i64;
v31 = 0;
}
}
else
{
v31 = -1073741558;
}
ExReleaseSpinLockExclusiveFromDpcLevel(v32);
__writecr8(v33);
v6 = v54;
MiFreeReservationRuns(v54, (UINT64)v61);
}
if( v11 )
MiFreeWorkingSetSwapContext((_MI_PARTITION *)v6, (PVOID)v11);
}
else
{
v31 = -1073741670;
}
SessionId = -1;
}
if( (v5 & 1) != 0 )
{
v36 = v6 + 1128;
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v6 + 1128), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v6 + 1128));
LODWORD(v53) = 0;
v37 = v6 + 1128;
v38 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v37) == 1 )
{
SessionId = MmGetSessionIdEx(*((_QWORD *)v38 + 23));
v50 = SessionId;
}
--*((_WORD *)v38 + 243);
v39 = ++*((_BYTE *)v38 + 794);
v40 = (*((char *)v38 + 792) | *((char *)v38 + 870)) ^ 0x3F;
v22 = !_BitScanReverse((unsigned int *)&v41, v40);
HIDWORD(SwapFileNumber) = v41;
if( v22 )
{
LABEL_71:
if( (*((_DWORD *)v38 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v38, v36, SessionId, 0i64);
}
else
{
while( 1 )
{
v42 = *((_QWORD *)v38 + 100) + 96 * v41;
v40 &= ~(1 << v41);
if( (*(_BYTE *)(v42 + 26) & 1) != 0
&& (*(_DWORD *)(v42 + 32) & 1) == 0
&& (*(_QWORD *)(v42 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v36 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v42 + 40) == v50 )
{
*(_BYTE *)(v42 + 26) &= ~1u;
if( *(_QWORD *)(v42 + 32) )
break;
}
v22 = !_BitScanReverse((unsigned int *)&v41, v40);
HIDWORD(SwapFileNumber) = v41;
if( v22 )
goto LABEL_70;
}
if( !v42 )
{
LABEL_70:
SessionId = v50;
goto LABEL_71;
}
*(_BYTE *)(v42 + 32) |= 2u;
if( *(__int64 *)(v42 + 32) < 0 )
KiAbEntryRemoveFromTree(v42);
LODWORD(v53) = *(_DWORD *)(v42 + 88) & 0x1FFFF;
*(_DWORD *)(v42 + 88) &= 0xFFFE0000;
*(_BYTE *)(v42 + 25) &= ~1u;
*(_QWORD *)(v42 + 32) = 0i64;
v43 = (__int64)(v42 - *((_QWORD *)v38 + 100)) / 96;
if( v39 == 1 )
*((_BYTE *)v38 + 792) |= 1 << v43;
else
_InterlockedOr8((volatile signed __int8 *)v38 + 870, 1 << v43);
}
--*((_BYTE *)v38 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v38, v36, (unsigned int *)&v53);
v22 = (*((_WORD *)v38 + 243))++ == 0xFFFF;
if( v22 && *((_ETHREAD **)v38 + 19) != (_ETHREAD *)((char *)v38 + 152) )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
}
v44 = P;
if( P )
{
if( v5 >= 4 )
SmStoreSetProcessVaRanges(*(VOID **)P, *((_QWORD *)P + 2));
ExFreePoolWithTag(v44, 0);
}
*(_QWORD *)&v64 = ExtendPages;
*((_QWORD *)&v64 + 1) = v61[10];
v65 = v62;
LODWORD(v66) = v31;
EtwTraceWorkingSetSwap(Processa, 0, (__int64)&v64);
return(unsigned int)v31;
}Referenced by:
PspChangeProcessExecutionState