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