MmOutSwapProcess
VOID __stdcall MmOutSwapProcess(_EPROCESS *Process){
_MMSUPPORT_SHARED *p_Shared;
__int64 v2;
__int8 bf_0;
char v5;
_LIST_ENTRY *p_WorkingSetExpansionLinks;
_LIST_ENTRY *Flink;
_LIST_ENTRY *Blink;
_MM_PAGE_ACCESS_INFO_HEADER *AccessLog;
CHAR v10;
unsigned __int64 v11;
_MMPFN *v12;
unsigned __int64 *v13;
unsigned __int64 v14;
unsigned __int64 v15;
unsigned __int64 v16;
int v17;
unsigned __int64 v18;
_KLOCK_QUEUE_HANDLE LockHandle;
__int16 v20;
char v21;
char v22;
int v23;
__int64 v24[2];
UINT8 OldIrql;
UINT64 SpinCount;
UINT64 v27;
p_Shared = (_MMSUPPORT_SHARED *)((char *)&stru_140C4DB30 + 6544);
v2 = Process->Vm.Instance.Flags._bf_0 & 7;
v22 = 0;
OldIrql = 0;
memset(&LockHandle, 0, sizeof(LockHandle));
if( (_BYTE)v2 != 2 )
p_Shared = &Process->Vm.Shared;
_InterlockedOr((volatile signed __int32 *)&Process->1124, 0x40u);
bf_0 = Process->Vm.Instance.Flags._bf_0;
if( (bf_0 & 0x60) == 32 )
{
MiReleaseOutSwappedProcessCommit(Process);
}
else if( (bf_0 & 0x60) == 64 && *((_QWORD *)p_Shared->CommitReleaseContext + 5) )
{
MiReleaseCommitForResetPages(Process);
}
if( Process->Vm.Instance.WorkingSetSize == 1 && (Process->Vm.Instance.Flags._bf_0 & 2) == 0 )
{
v20 = 263;
v24[1] = (__int64)v24;
v21 = 6;
v24[0] = (__int64)v24;
v23 = 0;
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)&stru_140C4DB30 + 522, &LockHandle);
while( 1 )
{
v5 = (unsigned __int8)Process->Vm.Instance.Flags._bf_1 >> 4;
if( (Process->Vm.Instance.Flags._bf_1 & 6) == 0 && !v5 )
break;
if( v5 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
v18 = LockHandle.OldIrql;
goto LABEL_35;
}
Process->Vm.Instance.ExitOutswapGate = (_KGATE *)&v20;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
KeWaitForGate((_KGATE *)&v20, WrVirtualMemory, v10);
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)&stru_140C4DB30 + 522, &LockHandle);
Process->Vm.Instance.ExitOutswapGate = 0i64;
}
_InterlockedOr((volatile signed __int32 *)&Process->1124, 0x80u);
p_WorkingSetExpansionLinks = &Process->Vm.Instance.WorkingSetExpansionLinks;
Flink = Process->Vm.Instance.WorkingSetExpansionLinks.Flink;
Blink = Process->Vm.Instance.WorkingSetExpansionLinks.Blink;
if( Flink->Blink != &Process->Vm.Instance.WorkingSetExpansionLinks || Blink->Flink != p_WorkingSetExpansionLinks )
__fastfail(3u);
Blink->Flink = Flink;
Flink->Blink = Blink;
p_WorkingSetExpansionLinks->Flink = 0i64;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
AccessLog = (_MM_PAGE_ACCESS_INFO_HEADER *)p_Shared->AccessLog;
if( AccessLog )
{
MiEmptyPageAccessLog(AccessLog);
p_Shared->AccessLog = 0i64;
}
LODWORD(SpinCount) = 0;
while( !KeIsEmptyAffinityEx(&Process->Pcb.ActiveProcessors.Count) )
KeYieldProcessorEx(&SpinCount);
KeFlushProcessTb(Process->Pcb.DirectoryTableBase);
if( Process->Vm.Shared.ShadowMapping )
KeFlushProcessTb(Process->Pcb.UserDirectoryTableBase);
v11 = Process->Pcb.DirectoryTableBase >> 12;
v12 = &MmGetPfnDb()[v11];
v13 = (unsigned __int64 *)((char *)MiMapPageInHyperSpaceWorker(v11, &OldIrql, 0x80000000ui64)
+ 8 * ((LODWORD(v12->PteLong) >> 3) & 0x1FF));
LODWORD(v14) = MiMakeTransitionPte(v11, 4);
v15 = v14;
v16 = v14;
LOBYTE(v17) = MiPteInShadowRange((UINT64)v13);
if( v17 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v15 & 1) != 0 )
v16 |= 0x8000000000000000ui64;
*v13 = v16;
MiUnmapPageInHyperSpaceWorker(v13, OldIrql, 0x80000000ui64);
MiLockAndDecrementShareCount(v12, 0i64);
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)&stru_140C4DB30 + 522, &LockHandle);
LODWORD(v27) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v12->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v27);
while( v12->u2._bf_0 < 0 );
}
v12->PteLong = (unsigned __int64)&Process->PageDirectoryPte;
Process->PageDirectoryPte = v15;
Process->Vm.Instance.WorkingSetLeafSize = 0i64;
Process->Vm.Instance.WorkingSetLeafPrivateSize = 0i64;
Process->Vm.Instance.WorkingSetSize = 0i64;
Process->Vm.Instance.WorkingSetPrivateSize = 0i64;
MiDecrementShareCount(v12);
_InterlockedAnd64(&v12->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
v18 = LockHandle.OldIrql;
LABEL_35:
__writecr8(v18);
}
}Referenced by:
KiOutSwapProcesses