MmPurgeSection

UINT8 __stdcall MmPurgeSection(
        _SECTION_OBJECT_POINTERS *FsSectionObjectPointer,
        _LARGE_INTEGER *Offset,
        UINT64 RegionSize,
        UINT64 PurgeFlags,
        UINT8 *ExtentPagesActive){
  char v5; 
  _LARGE_INTEGER *v7; 
  __int64 v8; 
  _CONTROL_AREA *v9; 
  UINT8 v10; 
  INT64 v11; 
  UINT64 SubsectionBase; 
  UINT8 v14; 
  char v15; 
  _SUBSECTION *NextSubsection; 
  _MMPTE **p_SubsectionBase; 
  int v18; 
  int v19; 
  __int64 v20; 
  _MMPFN *v21; 
  union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v22; 
  _MMPTE v23; 
  _MMPFN *v24; 
  void *v25; 
  unsigned __int8 v26; 
  bool v27; 
  _MSUBSECTION *v28; 
  UINT64 v29; 
  UINT8 v30; 
  __int64 v31; 
  __int64 v32; 
  __int64 v33; 
  UINT64 v34; 
  _MI_CROSS_PARTITION_CHARGES *v35; 
  __int64 v36; 
  UINT8 *EntryIrql; 
  char v38; 
  ULONG_PTR ProtoPagePfn; 
  _MSUBSECTION *MappedSubsection; 
  __int64 v41; 
  UINT64 SpinCount; 
  LONGLONG QuadPart; 
  _MI_FLUSH_RANGE FlushRange[4]; 
  _SUBSECTION *LastSubsection[2]; 
  __int128 FirstSubsection; 
  char v47[32]; 
  __int64 v48; 
  UINT8 PageIrql; 
  UINT8 v50; 
  int v51; 

  v51 = PurgeFlags;
  v50 = 0;
  v48 = 0i64;
  PageIrql = 0;
  QuadPart = 0i64;
  v5 = PurgeFlags;
  v7 = Offset;
  *ExtentPagesActive = 0;
  *(_OWORD *)FlushRange = 0i64;
  *(_OWORD *)LastSubsection = 0i64;
  FirstSubsection = 0i64;
  memset(v47, 0, sizeof(v47));
  if( Offset )
  {
    v7 = (_LARGE_INTEGER *)&QuadPart;
    QuadPart = Offset->QuadPart;
  }
  v41 = 0i64;
  v8 = 0i64;
  v9 = MiCanFileBeTruncatedInternal(
         (_MI_SECTION_OBJECT_POINTERS *)FsSectionObjectPointer,
         v7,
         1ui64,
         ((unsigned int)PurgeFlags >> 1) & 1,
         &v50);
  v10 = v50;
  v11 = (INT64)v9;
  if( v50 == 17 )
    return 0;
  if( !v9 )
    return 1;
  if( (v5 & 1) == 0 && v9->u2.NumberOfSystemCacheViews || !v9->FilePointer.Value )
  {
    ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&v9->ControlAreaLock);
    __writecr8(v10);
    return 0;
  }
  v9->u.LongFlags |= 0x8000u;
  LODWORD(EntryIrql) = 1;
  if( !MiComputeDataFlushRange(v9, v10, v7, RegionSize, (UINT64)EntryIrql, FlushRange) )
    return 1;
  SubsectionBase = *(_QWORD *)&FlushRange[2];
  v14 = 17;
  v15 = 1;
  NextSubsection = LastSubsection[1];
  v50 = 17;
  v38 = 1;
LABEL_11:
  MappedSubsection = (_MSUBSECTION *)NextSubsection;
  if( v14 == 17 )
  {
    v14 = ExAcquireSpinLockExclusive((INT64 *)(v11 + 72));
    v50 = v14;
  }
  if( (_SUBSECTION *)FirstSubsection == NextSubsection )
    p_SubsectionBase = &LastSubsection[0]->SubsectionBase;
  else
    p_SubsectionBase = (_MMPTE **)&NextSubsection->SubsectionBase[NextSubsection->PtesInSubsection
                                                                - (NextSubsection->_bf_34 & 0x3FFFFFFF)];
  LOBYTE(v18) = MiControlAreaUsingExtents(v11);
  v19 = v18;
  if( v20 )
  {
    if( MappedSubsection->LargeViews )
    {
      v30 = 0;
      goto LABEL_49;
    }
    MiIncrementSubsectionViewCount(MappedSubsection, 0i64);
    if( (MappedSubsection->Core.u.SubsectionFlags._bf_2 & 8) != 0 )
      MiRemoveUnusedSubsection(MappedSubsection);
    MappedSubsection->Core.u.SubsectionFlags._bf_0 |= 1u;
    ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v11 + 72));
    __writecr8(v14);
    LODWORD(v21) = 0;
    PageIrql = 17;
    ProtoPagePfn = 0;
    if( v19 )
    {
      MiChangingSubsectionProtos((ULONG_PTR)MappedSubsection);
      LODWORD(v21) = 0;
    }
    if( SubsectionBase >= (unsigned __int64)p_SubsectionBase )
      goto LABEL_43;
    while( 1 )
    {
      if( (SubsectionBase & 0xFFF) != 0 )
      {
        if( PageIrql != 17 )
          goto LABEL_24;
      }
      else if( PageIrql != 17 )
      {
        MiUnlockProtoPoolPage((ULONG_PTR)v21, PageIrql);
      }
      v21 = MiCheckProtoPtePageState((VOID *)SubsectionBase, &PageIrql);
      ProtoPagePfn = (unsigned int)v21;
      if( v21 )
        break;
      SubsectionBase = (SubsectionBase & 0xFFFFFFFFFFFFF000ui64) + 4096;
LABEL_60:
      if( SubsectionBase >= (unsigned __int64)p_SubsectionBase )
        goto LABEL_61;
    }
    while( 1 )
    {
LABEL_24:
      while( 1 )
      {
        v22.Long = *(unsigned __int64 *)SubsectionBase;
        v23.u.Long = *(_QWORD *)SubsectionBase;
        if( (*(_QWORD *)SubsectionBase & 1) == 0 )
          break;
LABEL_32:
        if( (MmGetPfnDb()[(v23.u.Long >> 12) & 0xFFFFFFFFFi64].u4._bf_0 & 0x4000000000000i64) != 0 )
        {
          v24 = &MmGetPfnDb()[(v23.u.Long >> 12) & 0xFFFFFFFFFi64];
          LODWORD(SpinCount) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)&v24->u2, 0x3Fui64) )
          {
            do
              KeYieldProcessorEx(&SpinCount);
            while( v24->u2._bf_0 < 0 );
          }
          if( *(_QWORD *)SubsectionBase == v22.Long )
          {
            if( !v24 )
            {
LABEL_54:
              SubsectionBase += 8i64;
LABEL_59:
              LODWORD(v21) = ProtoPagePfn;
              goto LABEL_60;
            }
            v25 = *(void **)SubsectionBase;
            MiPteInShadowRange(SubsectionBase);
            if( ((unsigned __int8)v25 & 1) != 0 )
              goto LABEL_40;
            if( (*(_DWORD *)(&v24->3 + 1) & 0x401) != 1024i64
              || (v24->PteLong | 0x8000000000000000ui64) != SubsectionBase )
            {
              KeBugCheckEx(0xDEu, (PVOID)2, (PVOID)SubsectionBase, v24->ListEntry.Blink, v25);
            }
            v26 = *((_BYTE *)&v24->u3 + 2);
            if( (((v51 & 2) != 0) & (v26 >> 4)) != 0 )
            {
LABEL_40:
              _InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
              v15 = 0;
              v38 = 0;
              goto LABEL_41;
            }
            if( (v26 & 8) != 0 )
            {
              MiWaitForPageWriteCompletion(v24, (_CONTROL_AREA *)v11, ProtoPagePfn, PageIrql);
              PageIrql = 17;
              goto LABEL_59;
            }
            if( v19 && v24->u3.ReferenceCount )
              *ExtentPagesActive = 1;
            MiDeleteTransitionPte((_MMPTE *)SubsectionBase, v24, 0x11u, 1ui64);
            if( *(_QWORD *)(v11 + 32) )
            {
              SubsectionBase += 8i64;
              if( (SubsectionBase & 0x78) == 0 && (unsigned int)KeShouldYieldProcessor() )
              {
                MiUnlockProtoPoolPage(ProtoPagePfn, PageIrql);
                PageIrql = 17;
              }
              goto LABEL_59;
            }
LABEL_61:
            v15 = v38;
LABEL_41:
            if( PageIrql != 17 )
              MiUnlockProtoPoolPage(ProtoPagePfn, PageIrql);
LABEL_43:
            v27 = v19 == 0;
            v28 = MappedSubsection;
            if( !v27 )
              MiSubsectionProtosCreated(&MappedSubsection->Core, (_MI_CONTROL_AREA_WAIT_BLOCK *)v47);
            v50 = ExAcquireSpinLockExclusive((INT64 *)(v11 + 72));
            v14 = v50;
            MiDecrementSubsectionViewCount(MappedSubsection);
            if( MappedSubsection->NumberOfMappedViews || (MappedSubsection->Core.u.SubsectionFlags._bf_2 & 1) != 0 )
            {
              v8 = v41;
            }
            else
            {
              LODWORD(v36) = MiInsertUnusedSubsection(MappedSubsection, v29);
              v8 = v36 + v41;
              v41 += v36;
            }
LABEL_47:
            if( v28 == (_MSUBSECTION *)FirstSubsection || !v15 )
              goto LABEL_48;
            NextSubsection = v28->Core.NextSubsection;
            SubsectionBase = (UINT64)NextSubsection->SubsectionBase;
            goto LABEL_11;
          }
          _InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
        }
      }
      if( (*(_QWORD *)SubsectionBase & 0xC00i64) != 2048 )
        goto LABEL_54;
      if( !v22.Long || !*(&stru_140C4DB30 + 42) || (v22.Long & *(&stru_140C4DB30 + 42)) != 0 )
      {
        v23.u.Long = *(_QWORD *)SubsectionBase;
        if( *(&stru_140C4DB30 + 42) && (v22.Long & 0x10) == 0 )
          v23.u.Long = v22.Long & ~*(&stru_140C4DB30 + 42);
        goto LABEL_32;
      }
    }
  }
  v28 = MappedSubsection;
  if( MappedSubsection != (_MSUBSECTION *)FirstSubsection )
    goto LABEL_47;
LABEL_48:
  v30 = v38;
LABEL_49:
  LODWORD(v31) = MiDecrementSubsections(LastSubsection[1], LastSubsection[1], 0i64);
  v32 = v31 + v8;
  LODWORD(v33) = MiDecrementSubsections((_SUBSECTION *)FirstSubsection, (_SUBSECTION *)FirstSubsection, 0i64);
  --*(_QWORD *)(v11 + 40);
  *(_DWORD *)(v11 + 56) &= ~4u;
  v34 = v33 + v32;
  if( v34 )
    v35 = *(_MI_CROSS_PARTITION_CHARGES **)(*(&stru_140C4DB30 + 267) + 8i64 * (*(_WORD *)(v11 + 60) & 0x3FF));
  else
    v35 = 0i64;
  MiCheckControlArea((_CONTROL_AREA *)v11, v14);
  if( v34 )
    MiReturnCrossPartitionSectionCharges(v35, 1i64, v34);
  return v30;
}

Referenced by:

CcPurgeCacheSection