MiTrimOrAgeWorkingSet

VOID __fastcall MiTrimOrAgeWorkingSet(
        _MMSUPPORT_INSTANCE *VmSupport,
        _MMWS_TRIM_CRITERIA *TrimCriteria,
        UINT64 WorkingSetRequestFlags){
  __int16 v3; 
  __int8 bf_0; 
  __int64 v6; 
  char v7; 
  char *v8; 
  void *v9; 
  _ETHREAD *CurrentThread; 
  struct _KPRCB *CurrentPrcb; 
  $A184FAFDEBB902F1E6D1F235B14D565F *v12; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *v14; 
  struct _KPRCB *v15; 
  _EPROCESS *Process; 
  unsigned __int64 GroupIndex; 
  __int64 v18; 
  unsigned __int64 v19; 
  unsigned __int64 v20; 
  _MMSUPPORT_INSTANCE *v21; 
  unsigned __int8 v22; 
  _MMSUPPORT_INSTANCE *v23; 
  UINT8 v24; 
  int v25; 
  unsigned int v26; 
  int v27; 
  NTSTATUS v28; 
  _MMWS_TRIM_CRITERIA *v29; 
  volatile unsigned __int64 TickCountQuad; 
  char v31; 
  UINT8 v32; 
  char v33; 
  _MMSUPPORT_INSTANCE *v34; 
  _MMSUPPORT_INSTANCE *v35; 
  volatile __int64 *v36; 
  struct _KPRCB *v37; 
  _MM_PAGE_ACCESS_INFO_HEADER *v38; 
  _SINGLE_LIST_ENTRY *Next; 
  _SINGLE_LIST_ENTRY *i; 
  _KSPIN_LOCK_QUEUE *v41; 
  _MMSUPPORT_FLAGS Flags; 
  char v43; 
  _MM_PAGE_ACCESS_INFO_HEADER *v44; 
  UINT64 v45; 
  NTSTATUS v46; 
  NTSTATUS v47; 
  _MM_PAGE_ACCESS_INFO_HEADER *v48; 
  _DWORD *SchedulerAssist; 
  _LIST_ENTRY *Blink; 
  _LIST_ENTRY *v51; 
  unsigned __int64 v52; 
  unsigned __int64 v53; 
  UINT64 v54; 
  __int64 v55; 
  PVOID BugCheckParameter4; 
  UINT8 CurrentIrql; 
  UINT8 v59; 
  _EPROCESS *v60; 
  INT64 v61[2]; 
  __int64 v62; 
  UINT64 SpinCount; 
  __int64 v64; 
  _KAPC_STATE SavedApcState; 

  v3 = WorkingSetRequestFlags;
  if( VmSupport->Flags.MemoryPriority == 2 && (VmSupport->Flags._bf_0 & 7) == 0 )
    PfLogForegroundProcess(VmSupport);
  bf_0 = VmSupport->Flags._bf_0;
  v6 = *(_QWORD *)(*(_QWORD *)(*(&stru_140C4DB30 + 267) + 8i64 * VmSupport->PartitionId) + 6848i64);
  v64 = v6;
  v7 = bf_0 & 7;
  if( v7 )
  {
    if( v7 == 1 )
      MiAttachSession((_MM_SESSION_SPACE *)&VmSupport[-2].WorkingSetLeafPrivateSize);
  }
  else
  {
    v8 = (char *)&VmSupport[-9].AgeDistribution[3];
    if( (unsigned __int64 *)KeGetCurrentThread()->Process != &VmSupport[-9].AgeDistribution[3] )
    {
      memset(&SavedApcState, 0, sizeof(SavedApcState));
      WorkingSetRequestFlags = (UINT64)KeGetCurrentThread();
      v9 = (void *)*(unsigned __int8 *)(WorkingSetRequestFlags + 586);
      if( (_BYTE)v9 )
        KeBugCheckEx(5u, &VmSupport[-9].AgeDistribution[3], *(PVOID *)(WorkingSetRequestFlags + 184), v9, 0i64);
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      if( (KeGetPcr()->Prcb._bf_0 & 0x10001) != 0 || (*((_DWORD *)v8 + 158) & 0x400) != 0 )
        KeBugCheckEx(
          5u,
          &VmSupport[-9].AgeDistribution[3],
          CurrentThread->Tcb.ApcState.Process,
          (PVOID)CurrentThread->Tcb.ApcStateIndex,
          (PVOID)(KeGetPcr()->Prcb._bf_0 & 0x10001));
      if( (char *)CurrentThread->Tcb.ApcState.Process == v8 )
      {
        SavedApcState.Process = (_EPROCESS *)1;
      }
      else
      {
        CurrentIrql = KeGetCurrentIrql();
        __writecr8(2ui64);
        CurrentPrcb = KeGetCurrentPrcb();
        LODWORD(SpinCount) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->Tcb.ThreadLock, 0i64) )
        {
          do
            KeYieldProcessorEx(&SpinCount);
          while( CurrentThread->Tcb.ThreadLock );
          SchedulerAssist = CurrentPrcb->SchedulerAssist;
          if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
            ++SchedulerAssist[6];
        }
        if( CurrentThread->Tcb.ApcStateIndex )
        {
          KiAttachProcess(
            &CurrentThread->Tcb,
            (_KPROCESS *)&VmSupport[-9].AgeDistribution[3],
            CurrentIrql,
            1ui64,
            &SavedApcState);
        }
        else
        {
          v12 = &CurrentThread->Tcb.600;
          CurrentThread->Tcb.SavedApcState.Process = CurrentThread->Tcb.ApcState.Process;
          CurrentThread->Tcb.SavedApcState.InProgressFlags = CurrentThread->Tcb.ApcState.InProgressFlags;
          CurrentThread->Tcb.SavedApcState.KernelApcPending = CurrentThread->Tcb.ApcState.KernelApcPending;
          CurrentThread->Tcb.SavedApcState.UserApcPendingAll = CurrentThread->Tcb.ApcState.UserApcPendingAll;
          Flink = CurrentThread->Tcb.ApcState.ApcListHead[0].Flink;
          if( Flink == (_LIST_ENTRY *)&CurrentThread->Tcb.152 )
          {
            CurrentThread->Tcb.SavedApcState.ApcListHead[0].Blink = CurrentThread->Tcb.SavedApcState.ApcListHead;
            v12->SavedApcState.ApcListHead[0].Flink = (_LIST_ENTRY *)v12;
            CurrentThread->Tcb.SavedApcState.KernelApcPending = 0;
          }
          else
          {
            Blink = CurrentThread->Tcb.ApcState.ApcListHead[0].Blink;
            v12->SavedApcState.ApcListHead[0].Flink = Flink;
            CurrentThread->Tcb.SavedApcState.ApcListHead[0].Blink = Blink;
            Flink->Blink = (_LIST_ENTRY *)v12;
            Blink->Flink = (_LIST_ENTRY *)v12;
          }
          WorkingSetRequestFlags = (UINT64)CurrentThread->Tcb.ApcState.ApcListHead[1].Flink;
          v14 = &CurrentThread->Tcb.SavedApcState.ApcListHead[1];
          if( (unsigned __int8 *)WorkingSetRequestFlags == &CurrentThread->Tcb.ApcStateFill[16] )
          {
            CurrentThread->Tcb.SavedApcState.ApcListHead[1].Blink = &CurrentThread->Tcb.SavedApcState.ApcListHead[1];
            v14->Flink = v14;
            CurrentThread->Tcb.SavedApcState.UserApcPendingAll = 0;
          }
          else
          {
            v51 = CurrentThread->Tcb.ApcState.ApcListHead[1].Blink;
            v14->Flink = (_LIST_ENTRY *)WorkingSetRequestFlags;
            CurrentThread->Tcb.SavedApcState.ApcListHead[1].Blink = v51;
            *(_QWORD *)(WorkingSetRequestFlags + 8) = v14;
            v51->Flink = v14;
          }
          CurrentThread->Tcb.ApcState.ApcListHead[0].Blink = CurrentThread->Tcb.ApcState.ApcListHead;
          CurrentThread->Tcb.ApcState.ApcListHead[1].Blink = &CurrentThread->Tcb.ApcState.ApcListHead[1];
          CurrentThread->Tcb.ApcState.ApcListHead[1].Flink = &CurrentThread->Tcb.ApcState.ApcListHead[1];
          CurrentThread->Tcb.ApcState.ApcListHead[0].Flink = CurrentThread->Tcb.ApcState.ApcListHead;
          CurrentThread->Tcb._bf_0 |= 0x800u;
          CurrentThread->Tcb.ApcStateIndex = 1;
          *(_WORD *)&CurrentThread->Tcb.ApcStateFill[40] = 0;
          CurrentThread->Tcb.ApcState.UserApcPendingAll = 0;
          CurrentThread->Tcb.ApcState.Process = (_EPROCESS *)v8;
          CurrentThread->Tcb.ThreadLock = 0i64;
          v15 = KeGetCurrentPrcb();
          Process = CurrentThread->Tcb.SavedApcState.Process;
          v60 = Process;
          GroupIndex = v15->GroupIndex;
          v18 = 8i64 * v15->Group + 376;
          _interlockedbittestandset64((volatile signed __int32 *)&v8[v18], GroupIndex);
          v19 = *((_QWORD *)v8 + 5);
          if( KiKvaShadow )
          {
            v20 = *((_QWORD *)v8 + 5);
            if( (v19 & 2) != 0 )
              v20 = v19 | 0x8000000000000000ui64;
            __writegsqword(0x9000u, v20);
            KiSetAddressPolicy(v8[912]);
            Process = v60;
          }
          __writecr3(v19);
          if( !KiFlushPcid && KiKvaShadow )
          {
            v52 = __readcr4();
            if( (v52 & 0x20080) != 0 )
            {
              __writecr4(v52 ^ 0x80);
              __writecr4(v52);
            }
            else
            {
              v53 = __readcr3();
              __writecr3(v53);
            }
          }
          _interlockedbittestandreset64((volatile signed __int32 *)&Process->Pcb.gap0[v18], GroupIndex);
          CurrentThread->Tcb._bf_0 &= ~0x800u;
          __writecr8(CurrentIrql);
          v6 = v64;
        }
      }
    }
  }
  if( (v3 & 4) != 0 )
    MiEmptyWorkingSetInitiate((INT64)VmSupport, 0, 0i64, -1i64);
  v21 = (_MMSUPPORT_INSTANCE *)((char *)&stru_140C4DB30 + 6544);
  v22 = VmSupport->Flags._bf_0 & 7;
  if( v22 >= 6u )
  {
    v24 = KeGetCurrentIrql();
    v59 = v24;
    __writecr8(2ui64);
  }
  else
  {
    if( v22 == 2 )
      v23 = (_MMSUPPORT_INSTANCE *)((char *)&stru_140C4DB30 + 6544);
    else
      v23 = VmSupport + 1;
    v24 = KeGetCurrentIrql();
    __writecr8(2ui64);
    _m_prefetchw(v23);
    v25 = v23->NextPageColor & 0x7FFFFFFF;
    if( v25 != _InterlockedCompareExchange((volatile signed __int32 *)v23, v25 + 1, v25) )
    {
      KiSetVpThreadSpinLockCount();
      ExpWaitForSpinLockSharedAndAcquire((INT64 *)v23, v24);
    }
    if( v23->PageFaultCount )
      _InterlockedExchange((volatile __int32 *)&v23->PageFaultCount, 0);
    v59 = v24;
  }
  if( (v3 & 0x20) != 0 && (VmSupport->Flags._bf_0 & 7) == 0 )
  {
    LODWORD(BugCheckParameter4) = 2;
    MiTrimWorkingSet(VmSupport, VmSupport->WorkingSetSize, v24, 0i64, (UINT64)BugCheckParameter4);
  }
  if( (v3 & 0x100) != 0 )
  {
    LODWORD(BugCheckParameter4) = 4;
    MiTrimWorkingSet(VmSupport, VmSupport->WorkingSetSize, v24, 0i64, (UINT64)BugCheckParameter4);
  }
  v26 = *(unsigned __int16 *)(v6 + 2346);
  v27 = 0;
  v28 = 0;
  if( (v3 & 1) == 0 )
  {
    if( (v3 & 2) != 0 )
    {
      v27 = 1;
      v28 = MiAgeWorkingSet(VmSupport, v24, 1ui64, v26);
      if( !v28 && *(_BYTE *)(v64 + 55) == 1 && v26 - 1 <= 8 )
        v28 = MiAgeWorkingSet(VmSupport, v24, 2ui64, 0xAui64);
      v29 = TrimCriteria;
      goto LABEL_41;
    }
    if( (v3 & 0x40) != 0 )
    {
      v47 = MiAgeWorkingSet(VmSupport, v24, 1ui64, v26);
      v29 = TrimCriteria;
      v28 = v47;
      v27 = 1;
      goto LABEL_41;
    }
    if( (v3 & 0x80u) == 0 )
    {
      v29 = TrimCriteria;
      goto LABEL_41;
    }
    v45 = 2i64;
LABEL_84:
    v46 = MiAgeWorkingSet(VmSupport, v24, v45, v26);
    v29 = TrimCriteria;
    v27 = 1;
    v28 = v46;
    goto LABEL_41;
  }
  TrimCriteria->TrimAge = *((_BYTE *)MiTrimPassToAge + (TrimCriteria->_bf_0 & 0x7F));
  LODWORD(v54) = MiComputeTrimAmount(TrimCriteria, VmSupport, WorkingSetRequestFlags);
  if( v54 )
  {
    LODWORD(BugCheckParameter4) = 17;
    LODWORD(v55) = MiTrimWorkingSet(VmSupport, v54, v24, TrimCriteria->TrimAge, (UINT64)BugCheckParameter4);
    v29 = TrimCriteria;
    *(_QWORD *)&TrimCriteria[1].PagesToTrim += v55;
  }
  else
  {
    v29 = TrimCriteria;
  }
  v45 = 0i64;
  if( ((v29->_bf_0 & 0x7F) == 0 && v29->_bf_0 >= 0 || (v29->_bf_0 & 0x7F) == 4) && *(_WORD *)(v64 + 2346) )
    v45 = 1i64;
  if( v29->AgingPolicy == 1 )
    goto LABEL_84;
LABEL_41:
  TickCountQuad = 0i64;
  if( v28 == 1 )
  {
    v32 = v59;
  }
  else
  {
    if( v27 == 1 )
    {
      v31 = 3;
      if( VmSupport->Flags.MemoryPriority != 2 )
        v31 = 1;
      *(_QWORD *)v29->ClaimDistribution += VmSupport->AgeDistribution[0] >> v31;
      *(_QWORD *)&v29->ClaimDistribution[2] += VmSupport->AgeDistribution[1] >> v31;
      *(_QWORD *)&v29->ClaimDistribution[4] += VmSupport->AgeDistribution[2] >> v31;
      *(_QWORD *)&v29->ClaimDistribution[6] += VmSupport->AgeDistribution[3] >> v31;
      *(_QWORD *)&v29->PagesToTrim += VmSupport->AgeDistribution[4] >> v31;
      *(_QWORD *)&v29->PagesTrimmed += VmSupport->AgeDistribution[5] >> v31;
      *(_QWORD *)&v29[1]._bf_0 += VmSupport->AgeDistribution[6] >> v31;
      *(_QWORD *)v29[1].ClaimDistribution += VmSupport->AgeDistribution[7] >> v31;
    }
    if( (v3 & 0x10) != 0 || (v3 & 8) != 0 )
    {
      v32 = v59;
      MiCaptureAndResetWorkingSetAccessBits(VmSupport, v59);
    }
    else
    {
      v32 = v59;
    }
    TickCountQuad = KUSER_SHARED_DATA.TickCountQuad;
    v33 = VmSupport->Flags._bf_0 & 7;
    v62 = 0i64;
    v34 = VmSupport + 1;
    *(_OWORD *)v61 = 0i64;
    if( v33 == 2 )
      v35 = (_MMSUPPORT_INSTANCE *)((char *)&stru_140C4DB30 + 6544);
    else
      v35 = VmSupport + 1;
    if( v35->AgeDistribution[0] )
    {
      v61[0] = 0i64;
      if( v33 == 2 )
        v34 = (_MMSUPPORT_INSTANCE *)((char *)&stru_140C4DB30 + 6544);
      v36 = (volatile __int64 *)&v34->AgeDistribution[3];
      v61[1] = (INT64)&v34->AgeDistribution[3];
      v37 = KeGetCurrentPrcb();
      if( v37->SchedulerAssist && v37->NestingLevel <= 1u && v37->NestingLevel == 1 )
        v36 = (volatile __int64 *)&v34->AgeDistribution[3];
      if( _InterlockedExchange64(v36, (__int64)v61) )
        KxWaitForLockOwnerShip((INT64)v61);
      v38 = (_MM_PAGE_ACCESS_INFO_HEADER *)v35->AgeDistribution[0];
      if( v38 )
      {
        Next = v38->Link.Next;
        for( i = (_SINGLE_LIST_ENTRY *)v35->AgeDistribution[0]; Next; Next = Next->Next )
          i = Next;
        if( TickCountQuad - (unsigned __int64)i[2].Next > PfKernelGlobals.AccessBufferAgeThreshold )
        {
          MiEmptyPageAccessLog(v38);
          v35->AgeDistribution[0] = 0i64;
        }
      }
      _m_prefetchw(v61);
      v41 = (_KSPIN_LOCK_QUEUE *)v61[0];
      if( !v61[0] )
      {
        if( (INT64 *)_InterlockedCompareExchange64((volatile signed __int64 *)v61[1], 0i64, (signed __int64)v61) == v61 )
          goto LABEL_63;
        v41 = KxWaitForLockChainValid((_KSPIN_LOCK_QUEUE *)v61);
      }
      v61[0] = 0i64;
      _InterlockedXor64((volatile signed __int64 *)&v41->Lock, 1ui64);
    }
  }
LABEL_63:
  if( (VmSupport->Flags._bf_0 & 7u) < 6 )
  {
    Flags = VmSupport->Flags;
    if( (Flags.$2436257948A9E417F8C1432C685A007E::$56A022E0416FA8F0D143F219D5D8FA21::_bf_0 & 8) != 0
      || (Flags.$2436257948A9E417F8C1432C685A007E::$56A022E0416FA8F0D143F219D5D8FA21::_bf_0 & 4) != 0
      || (Flags.$2436257948A9E417F8C1432C685A007E::$56A022E0416FA8F0D143F219D5D8FA21::_bf_0 & 0x10) != 0 )
    {
      MiPreUnlockWorkingSetShared(VmSupport, v32);
      Flags.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 = VmSupport->Flags._bf_0;
    }
    if( (Flags.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 & 7) != 2 )
      v21 = VmSupport + 1;
    MiCheckProcessShadow();
    _InterlockedAnd((volatile signed __int32 *)v21, 0xBFFFFFFF);
    _InterlockedDecrement((volatile signed __int32 *)v21);
  }
  __writecr8(v32);
  v43 = VmSupport->Flags._bf_0 & 7;
  if( v43 )
  {
    if( v43 == 1 )
      MiDetachProcessFromSession(1ui64);
  }
  else if( (unsigned __int64 *)KeGetCurrentThread()->Process != &VmSupport[-9].AgeDistribution[3] )
  {
    KiDetachProcess(&KeGetCurrentThread()->SavedApcState, 1ui64);
  }
  if( !v28 )
  {
    if( *(&stru_140C4DB30 + 322) )
    {
      v44 = (_MM_PAGE_ACCESS_INFO_HEADER *)_InterlockedExchange64((_QWORD *)&stru_140C4DB30 + 322, 0i64);
      if( v44 )
      {
        if( TickCountQuad - v44->CreateTime > PfKernelGlobals.AccessBufferAgeThreshold || (v3 & 0x18) != 0 )
        {
          v48 = v44;
        }
        else
        {
          if( !*(&stru_140C4DB30 + 322)
            && !_InterlockedCompareExchange64((_QWORD *)&stru_140C4DB30 + 322, (signed __int64)v44, 0i64) )
          {
            return;
          }
          v48 = v44;
          if( (_MM_PAGE_ACCESS_INFO_HEADER *)v44->PageEntry == &v44[1] )
          {
            MmFreeAccessPfnBuffer(v44, 1u);
            return;
          }
        }
        MiQueuePageAccessLog(v48);
      }
    }
  }
}

Referenced by:

MiProcessWorkingSets