CcSetDirtyInMask

VOID __stdcall CcSetDirtyInMask(
        _SHARED_CACHE_MAP *SharedCacheMap,
        _LARGE_INTEGER *FileOffset,
        UINT64 Length,
        _ETHREAD *IoIssuerThread){
  LONGLONG QuadPart; 
  _SHARED_CACHE_MAP *v5; 
  LONGLONG v6; 
  __int64 v7; 
  signed __int64 v8; 
  __int64 v9; 
  __int64 v10; 
  int i; 
  UINT64 *v12; 
  volatile signed __int32 *v13; 
  _ETHREAD *CurrentThread; 
  __int64 v15; 
  char v16; 
  __int64 v17; 
  NTSTATUS v18; 
  bool v19; 
  unsigned __int8 CurrentIrql; 
  _MBCB *v21; 
  _BITMAP_RANGE *BitmapRangeToDirty; 
  _BITMAP_RANGE *v23; 
  __int64 BasePage; 
  UINT8 v25; 
  unsigned __int8 v26; 
  struct _KPRCB *CurrentPrcb; 
  unsigned int *v28; 
  int v29; 
  unsigned int v30; 
  __int64 v31; 
  unsigned int *v32; 
  int v33; 
  _KSPIN_LOCK_QUEUE *volatile Next; 
  LONGLONG v35; 
  char *v36; 
  unsigned __int64 v37; 
  unsigned __int32 v38; 
  _ETHREAD *v39; 
  _PROCESS_DISK_COUNTERS *DiskCounters; 
  _MBCB *InitializeMbcb; 
  UINT64 *v42; 
  unsigned int *Bitmap; 
  _LIST_ENTRY *Blink; 
  _BITMAP_RANGE *p_BitmapRange2; 
  _LIST_ENTRY *p_BitmapRanges; 
  _BITMAP_RANGE *p_BitmapRange3; 
  _LIST_ENTRY *v48; 
  __int64 AbOrphanedEntrySummary; 
  int v50; 
  unsigned int NumberOfPages; 
  UINT64 a3; 
  UINT8 FastScan[8]; 
  UINT64 *FreePageForSetting; 
  __int64 v55; 
  _KLOCK_QUEUE_HANDLE LockQueue; 
  int v59; 

  QuadPart = FileOffset->QuadPart;
  v5 = SharedCacheMap;
  FreePageForSetting = 0i64;
  v59 = 0;
  v55 = (unsigned int)Length;
  v6 = QuadPart + (unsigned int)Length;
  NumberOfPages = 0;
  memset(&LockQueue, 0, sizeof(LockQueue));
  if( ((QuadPart ^ (v6 - 1)) & 0xFFFFFFFFFE000000ui64) != 0 )
    KeBugCheckEx(0x34u, (PVOID)0xC52, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
  if( (*((_DWORD *)v5 + 38) & 0x40000000) != 0 && v6 <= *((_QWORD *)v5 + 6) )
    return;
  v7 = QuadPart >> 12;
  v8 = (v6 - 1) >> 12;
  if( *((_QWORD *)v5 + 4) / 4096i64 <= v8 )
    KeBugCheckEx(0x34u, (PVOID)0xC72, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
  v9 = *((_QWORD *)v5 + 66);
  *(_QWORD *)FastScan = v9;
  if( *((_QWORD *)v5 + 21) )
  {
    LODWORD(v10) = MmGetControlAreaPartition(*(_QWORD *)((*((_QWORD *)v5 + 12) & 0xFFFFFFFFFFFFFFF0ui64) + 0x28));
    if( v9 != *(_QWORD *)(v10 + 8) )
      KeBugCheckEx(0x34u, (PVOID)0x1313, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
  }
  if( (*((_DWORD *)v5 + 38) & 0x40000000) != 0 )
  {
    ExAcquireFastMutex((PFAST_MUTEX)v5 + 5);
LABEL_54:
    v35 = FileOffset->QuadPart + v55;
    if( v35 > *((_QWORD *)v5 + 6) )
    {
      v19 = (*((_DWORD *)v5 + 38) & 0x40000000) == 0;
      *((_QWORD *)v5 + 6) = v35;
      if( !v19 )
      {
        KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v9 + 128), &LockQueue);
        v50 = *((_DWORD *)v5 + 38);
        if( (v50 & 0x400) == 0 )
          *((_DWORD *)v5 + 38) = v50 | 0x400;
        CcInsertIntoDirtySharedCacheMapList(v5);
        CcScheduleLazyWriteScan(v9, 0);
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
        __writecr8(LockQueue.OldIrql);
      }
    }
    goto LABEL_56;
  }
  while( 2 )
  {
    for( i = v59; ; i = 0 )
    {
      if( *((_QWORD *)v5 + 4) > 0x300000ui64 )
      {
        ++*(&WheapErrorSourceTable + 351);
        v12 = (UINT64 *)RtlpInterlockedPopEntrySList((PSLIST_HEADER)((char *)&WheapErrorSourceTable + 1384));
        if( !v12 )
        {
          ++*(&WheapErrorSourceTable + 352);
          v12 = (UINT64 *)(*(&WheapErrorSourceTable + 179))(
                            *(&WheapErrorSourceTable + 355),
                            *(&WheapErrorSourceTable + 357),
                            *(&WheapErrorSourceTable + 356));
          if( !v12 )
          {
            ++*(&CmpDummyThreadEvent + 769);
            goto LABEL_103;
          }
        }
        FreePageForSetting = v12;
      }
      LODWORD(a3) = 0;
      v13 = (volatile signed __int32 *)((char *)v5 + 280);
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      v59 = 1;
      --CurrentThread->Tcb.SpecialApcDisable;
      if( ++CurrentThread->Tcb.AbAllocationRegionCount != 1 )
        KeBugCheckEx(0x192u, CurrentThread, (char *)v5 + 280, (PVOID)KeGetCurrentIrql(), 0i64);
      LOBYTE(v15) = CurrentThread->Tcb.AbEntrySummary;
      if( !(_BYTE)v15 )
      {
        if( !CurrentThread->Tcb.AbOrphanedEntrySummary )
        {
          v17 = 0i64;
LABEL_94:
          _interlockedbittestandset((volatile signed __int32 *)&CurrentThread->Tcb.116 + 1, 0x10u);
          goto LABEL_17;
        }
        AbOrphanedEntrySummary = CurrentThread->Tcb.AbOrphanedEntrySummary;
        CurrentThread->Tcb.AbOrphanedEntrySummary = 0;
        LOBYTE(v15) = AbOrphanedEntrySummary | CurrentThread->Tcb.AbEntrySummary;
      }
      v16 = v15;
      _BitScanForward((unsigned int *)&v15, (unsigned __int8)v15);
      CurrentThread->Tcb.AbEntrySummary = v16 & ~(1 << v15);
      v17 = (__int64)&CurrentThread->Tcb.LockEntries[v15];
      if( !v17 )
        goto LABEL_94;
      v18 = MiGetSystemRegionType((UINT64)v5 + 280) == 1 ? MmGetSessionIdEx(CurrentThread->Tcb.ApcState.Process) : -1;
      *(_DWORD *)(v17 + 40) = v18;
      *(_QWORD *)(v17 + 32) = (unsigned __int64)v13 & 0x7FFFFFFFFFFFFFFCi64;
LABEL_17:
      --CurrentThread->Tcb.AbAllocationRegionCount;
      KiAbThreadRemoveBoosts(&CurrentThread->Tcb, (char *)v5 + 280, &a3);
      v19 = CurrentThread->Tcb.SpecialApcDisable++ == -1;
      if( v19
        && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152 )
      {
        KiCheckForKernelApcDelivery();
      }
      CurrentIrql = KeGetCurrentIrql();
      __writecr8(1ui64);
      if( !_interlockedbittestandreset(v13, 0) )
        ExpAcquireFastMutexContended((_FAST_MUTEX *)v5 + 5, (VOID *)v17);
      if( v17 )
        *(_BYTE *)(v17 + 26) |= 1u;
      *((_QWORD *)v5 + 36) = KeGetCurrentThread();
      *((_DWORD *)v5 + 82) = CurrentIrql;
      v21 = (_MBCB *)*((_QWORD *)v5 + 20);
      if( !v21 )
      {
        InitializeMbcb = CcAllocateInitializeMbcb();
        v21 = InitializeMbcb;
        if( !InitializeMbcb )
          goto LABEL_102;
        *((_QWORD *)v5 + 20) = InitializeMbcb;
      }
      if( v7 == v8 && v7 == v21->MostRecentlyDirtiedPage )
        goto LABEL_53;
      if( (unsigned __int64)v8 < 0x300 || v21->NodeTypeCode == 761 )
        break;
      v42 = FreePageForSetting;
      memset(FreePageForSetting, 0i64, 0x400u);
      if( v21->BitmapRange1.DirtyPages )
      {
        Bitmap = v21->BitmapRange1.Bitmap;
        *(_OWORD *)v42 = *(_OWORD *)Bitmap;
        *((_OWORD *)v42 + 1) = *((_OWORD *)Bitmap + 1);
        *((_OWORD *)v42 + 2) = *((_OWORD *)Bitmap + 2);
        *((_OWORD *)v42 + 3) = *((_OWORD *)Bitmap + 3);
        *((_OWORD *)v42 + 4) = *((_OWORD *)Bitmap + 4);
        *((_OWORD *)v42 + 5) = *((_OWORD *)Bitmap + 5);
        memset(v21->BitmapRange1.Bitmap, 0i64, 0x60u);
      }
      v21->BitmapRange1.Bitmap = (unsigned int *)v42;
      Blink = v21->BitmapRanges.Blink;
      p_BitmapRange2 = &v21->BitmapRange2;
      FreePageForSetting = 0i64;
      p_BitmapRanges = &v21->BitmapRanges;
      if( Blink->Flink != &v21->BitmapRanges )
        goto LABEL_86;
      p_BitmapRange2->Links.Flink = p_BitmapRanges;
      v21->BitmapRange2.Links.Blink = Blink;
      Blink->Flink = &p_BitmapRange2->Links;
      v21->BitmapRanges.Blink = &p_BitmapRange2->Links;
      p_BitmapRange3 = &v21->BitmapRange3;
      v21->BitmapRange2.BasePage = 0x7FFFFFFFFFFFFFFFi64;
      v21->BitmapRange2.FirstDirtyPage = -1;
      v48 = v21->BitmapRanges.Blink;
      if( v48->Flink != p_BitmapRanges )
LABEL_86:
        __fastfail(3u);
      p_BitmapRange3->Links.Flink = p_BitmapRanges;
      v21->BitmapRange3.Links.Blink = v48;
      v48->Flink = &p_BitmapRange3->Links;
      v21->BitmapRanges.Blink = &p_BitmapRange3->Links;
      v21->BitmapRange3.BasePage = 0x7FFFFFFFFFFFFFFFi64;
      v21->BitmapRange3.FirstDirtyPage = -1;
      v21->NodeTypeCode = 761;
      KeReleaseGuardedMutex((PKGUARDED_MUTEX)v5 + 5);
    }
    BitmapRangeToDirty = CcFindBitmapRangeToDirty(v21, v7, &FreePageForSetting);
    v23 = BitmapRangeToDirty;
    if( BitmapRangeToDirty )
    {
      BasePage = BitmapRangeToDirty->BasePage;
      if( v7 < BasePage + BitmapRangeToDirty->FirstDirtyPage )
        BitmapRangeToDirty->FirstDirtyPage = v7 - BasePage;
      if( v8 > BasePage + BitmapRangeToDirty->LastDirtyPage )
        BitmapRangeToDirty->LastDirtyPage = v8 - BasePage;
      v25 = FastScan[0];
      LockQueue.LockQueue.Next = 0i64;
      LockQueue.LockQueue.Lock = (unsigned __int64 *volatile)(*(_QWORD *)FastScan + 128i64);
      v26 = KeGetCurrentIrql();
      __writecr8(2ui64);
      LockQueue.OldIrql = v26;
      CurrentPrcb = KeGetCurrentPrcb();
      if( CurrentPrcb->SchedulerAssist && CurrentPrcb->NestingLevel <= 1u && CurrentPrcb->NestingLevel == 1 )
        v25 = FastScan[0];
      if( _InterlockedExchange64((volatile __int64 *)(*(_QWORD *)FastScan + 128i64), (__int64)&LockQueue) )
      {
        KxWaitForLockOwnerShip((INT64)&LockQueue);
        v25 = FastScan[0];
      }
      if( !*((_DWORD *)v5 + 28) && (*((_DWORD *)v5 + 38) & 2) == 0 )
      {
        CcScheduleLazyWriteScan(v25, 0);
        CcInsertIntoDirtySharedCacheMapList(v5);
        v21->ResumeWritePage = v7;
      }
      v28 = &v23->Bitmap[(unsigned __int64)(unsigned int)(v7 - LODWORD(v23->BasePage)) >> 5];
      v29 = 1 << (v7 & 0x1F);
      if( v7 <= v8 )
      {
        v30 = NumberOfPages;
        v31 = v8 - v7 + 1;
        v7 = v8 + 1;
        do
        {
          v32 = v28;
          if( (*v28 & v29) == 0 )
          {
            *v28 |= v29;
            ++v30;
          }
          v33 = 2 * v29;
          v29 = 1;
          if( v33 )
            v29 = v33;
          ++v28;
          if( v33 )
            v28 = v32;
          --v31;
        }
        while( v31 );
        NumberOfPages = v30;
        v5 = SharedCacheMap;
      }
      CcChargeDirtyPages(v5, v21, v23, NumberOfPages);
      _m_prefetchw(&LockQueue);
      Next = LockQueue.LockQueue.Next;
      if( !LockQueue.LockQueue.Next )
      {
        if( (_KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
                                      (volatile signed __int64 *)LockQueue.LockQueue.Lock,
                                      0i64,
                                      (signed __int64)&LockQueue) == &LockQueue )
        {
LABEL_50:
          __writecr8(LockQueue.OldIrql);
          if( (*((_DWORD *)v5 + 38) & 0x10000000) != 0 && NumberOfPages )
          {
            v39 = IoIssuerThread;
            if( !IoIssuerThread )
            {
              v39 = (_ETHREAD *)KeGetCurrentThread();
              IoIssuerThread = v39;
            }
            DiskCounters = v39->Tcb.Process->DiskCounters;
            if( DiskCounters )
            {
              if( NumberOfPages << 12 )
                _InterlockedExchangeAdd64((volatile signed __int64 *)&DiskCounters->BytesWritten, NumberOfPages << 12);
              _InterlockedExchangeAdd64((volatile signed __int64 *)&DiskCounters->WriteOperationCount, 1ui64);
            }
          }
          if( v29 )
          {
            v21->MostRecentlyDirtiedPage = v8;
LABEL_53:
            v9 = *(_QWORD *)FastScan;
            goto LABEL_54;
          }
          continue;
        }
        Next = KxWaitForLockChainValid(&LockQueue.LockQueue);
      }
      LockQueue.LockQueue.Next = 0i64;
      _InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
      goto LABEL_50;
    }
    break;
  }
LABEL_102:
  i = 1;
LABEL_103:
  if( (*((_DWORD *)v5 + 38) & 0x20000) == 0 )
  {
    KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(*(_QWORD *)FastScan + 128i64), &LockQueue);
    *((_DWORD *)v5 + 38) |= 0x20000u;
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
    __writecr8(LockQueue.OldIrql);
  }
  if( i )
  {
LABEL_56:
    v36 = (char *)v5 + 280;
    v37 = (unsigned __int8)v36[48];
    *((_QWORD *)v36 + 1) = 0i64;
    v38 = _InterlockedCompareExchange((volatile signed __int32 *)v36, 1, 0);
    if( v38 )
      ExpReleaseFastMutexContended((_FAST_MUTEX *)v36, v38);
    __writecr8(v37);
    KeAbPostRelease(v36);
  }
  if( FreePageForSetting )
  {
    ++*(&WheapErrorSourceTable + 353);
    if( *(&WheapErrorSourceTable + 692) >= *(&WheapErrorSourceTable + 700) )
    {
      ++*(&WheapErrorSourceTable + 354);
      (*(&WheapErrorSourceTable + 180))();
    }
    else
    {
      RtlpInterlockedPushEntrySList(
        (PSLIST_HEADER)((char *)&WheapErrorSourceTable + 1384),
        (PSLIST_ENTRY)FreePageForSetting);
    }
  }
}

Referenced by:

CcMapAndCopyInToCache
CcMdlWriteComplete2
CcPurgeAndClearCacheSection
CcReleaseByteRangeFromWrite
CcSetDirtyPinnedData