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