CcSetDirtyInMask

VOID __fastcall CcSetDirtyInMask(
        _SHARED_CACHE_MAP *SharedCacheMap,
        _LARGE_INTEGER *FileOffset,
        UINT64 Length,
        _ETHREAD *IoIssuerThread){
  LONGLONG QuadPart; 
  _SHARED_CACHE_MAP *v5; 
  _LARGE_INTEGER v6; 
  __int64 v7; 
  signed __int64 v8; 
  _CC_PARTITION *Partition; 
  int i; 
  struct _SLIST_ENTRY *v11; 
  _FAST_MUTEX *p_BcbLock; 
  _ETHREAD *CurrentThread; 
  __int64 v14; 
  char v15; 
  __int64 v16; 
  int v17; 
  bool v18; 
  unsigned __int8 CurrentIrql; 
  INT64 Mbcb; 
  __int64 BitmapRangeToDirty; 
  INT64 v22; 
  __int64 v23; 
  UINT8 v24; 
  unsigned __int8 v25; 
  struct _KPRCB *CurrentPrcb; 
  KSPIN_LOCK_QUEUE *v27; 
  _DWORD *v28; 
  int v29; 
  unsigned int v30; 
  __int64 v31; 
  _DWORD *v32; 
  int v33; 
  _KSPIN_LOCK_QUEUE *volatile Next; 
  _LARGE_INTEGER v35; 
  _FAST_MUTEX *v36; 
  unsigned __int64 OldIrql_low; 
  unsigned __int32 v38; 
  _ETHREAD *v39; 
  __int64 v40; 
  CHAR *InitializeMbcb; 
  PSLIST_ENTRY v42; 
  struct _SLIST_ENTRY *v43; 
  INT64 **v44; 
  INT64 *v45; 
  INT64 v46; 
  INT64 *v47; 
  INT64 **v48; 
  __int64 v49; 
  unsigned int Flags; 
  unsigned int v51; 
  unsigned int v52; 
  UINT8 FastScan[8]; 
  PSLIST_ENTRY ListEntry; 
  __int64 v55; 
  struct _KLOCK_QUEUE_HANDLE LockHandle; 
  int v59; 
  QuadPart = FileOffset->QuadPart;
  v5 = SharedCacheMap;
  ListEntry = 0i64;
  v59 = 0;
  v55 = (unsigned int)Length;
  v6.QuadPart = QuadPart + (unsigned int)Length;
  v51 = 0;
  memset(&LockHandle, 0, sizeof(LockHandle));
  if( ((QuadPart ^ (v6.QuadPart - 1)) & 0xFFFFFFFFFE000000ui64) != 0 )
    KeBugCheckEx(0x34u, 0xC52ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
  if( (v5->Flags & 0x40000000) != 0 && v6.QuadPart <= v5->ValidDataGoal.QuadPart )
    return;
  v7 = QuadPart >> 12;
  v8 = (v6.QuadPart - 1) >> 12;
  if( v5->SectionSize.QuadPart / 4096 <= v8 )
    KeBugCheckEx(0x34u, 0xC72ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
  Partition = v5->Partition;
  *(_QWORD *)FastScan = Partition;
  if( v5->Section
    && Partition != *(_CC_PARTITION **)(MmGetControlAreaPartition(*(_QWORD *)((v5->FileObjectFastRef.Value & 0xFFFFFFFFFFFFFFF0ui64)
                                                                            + 0x28))
                                      + 8) )
  {
    KeBugCheckEx(0x34u, 0x1313ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
  }
  if( (v5->Flags & 0x40000000) != 0 )
  {
    ExAcquireFastMutex(&v5->BcbLock);
LABEL_54:
    v35.QuadPart = FileOffset->QuadPart + v55;
    if( v35.QuadPart > v5->ValidDataGoal.QuadPart )
    {
      v18 = (v5->Flags & 0x40000000) == 0;
      v5->ValidDataGoal = v35;
      if( !v18 )
      {
        KeAcquireInStackQueuedSpinLock((UINT64 *)Partition + 16, &LockHandle);
        Flags = v5->Flags;
        if( (Flags & 0x400) == 0 )
          v5->Flags = Flags | 0x400;
        CcInsertIntoDirtySharedCacheMapList(v5);
        CcScheduleLazyWriteScan((UINT8)Partition, 0);
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(LockHandle.OldIrql);
      }
    }
    goto LABEL_56;
  }
  while( 2 )
  {
    for( i = v59; ; i = 0 )
    {
      if( v5->SectionSize.QuadPart > 0x300000ui64 )
      {
        ++dword_140CDB3D4;
        v11 = RtlpInterlockedPopEntrySList((PSLIST_HEADER)&CcBitmapLookasideList);
        if( !v11 )
        {
          ++dword_140CDB3D8;
          v11 = (struct _SLIST_ENTRY *)((__int64(__fastcall *)(_QWORD, _QWORD, _QWORD))qword_140CDB3F0)(
                                         (unsigned int)dword_140CDB3E4,
                                         (unsigned int)dword_140CDB3EC,
                                         (unsigned int)dword_140CDB3E8);
          if( !v11 )
          {
            ++CcDbgNumberOfFailedBitmapAllocations;
            goto LABEL_103;
          }
        }
        ListEntry = v11;
      }
      v52 = 0;
      p_BcbLock = &v5->BcbLock;
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      v59 = 1;
      --*((_WORD *)CurrentThread + 243);
      if( ++*((_BYTE *)CurrentThread + 794) != 1 )
        KeBugCheckEx(0x192u, (ULONG_PTR)CurrentThread, (ULONG_PTR)&v5->BcbLock, KeGetCurrentIrql(), 0i64);
      LOBYTE(v14) = *((_BYTE *)CurrentThread + 792);
      if( !(_BYTE)v14 )
      {
        if( !*((_BYTE *)CurrentThread + 870) )
        {
          v16 = 0i64;
LABEL_94:
          _interlockedbittestandset((volatile signed __int32 *)CurrentThread + 30, 0x10u);
          goto LABEL_17;
        }
        v49 = *((unsigned __int8 *)CurrentThread + 870);
        *((_BYTE *)CurrentThread + 870) = 0;
        LOBYTE(v14) = v49 | *((_BYTE *)CurrentThread + 792);
      }
      v15 = v14;
      _BitScanForward((unsigned int *)&v14, (unsigned __int8)v14);
      *((_BYTE *)CurrentThread + 792) = v15 & ~(1 << v14);
      v16 = *((_QWORD *)CurrentThread + 100) + 96 * v14;
      if( !v16 )
        goto LABEL_94;
      v17 = (unsigned int)MiGetSystemRegionType((UINT64)&v5->BcbLock) == 1 ? MmGetSessionIdEx(*((_QWORD *)CurrentThread
                                                                                              + 23)) : -1;
      *(_DWORD *)(v16 + 40) = v17;
      *(_QWORD *)(v16 + 32) = (unsigned __int64)p_BcbLock & 0x7FFFFFFFFFFFFFFCi64;
LABEL_17:
      --*((_BYTE *)CurrentThread + 794);
      KiAbThreadRemoveBoosts((ULONG_PTR)CurrentThread, (__int64)&v5->BcbLock, &v52);
      v18 = (*((_WORD *)CurrentThread + 243))++ == 0xFFFF;
      if( v18 && *((_ETHREAD **)CurrentThread + 19) != (_ETHREAD *)((char *)CurrentThread + 152) )
        KiCheckForKernelApcDelivery();
      CurrentIrql = KeGetCurrentIrql();
      __writecr8(1ui64);
      if( !_interlockedbittestandreset(&p_BcbLock->Count, 0) )
        ExpAcquireFastMutexContended(&v5->BcbLock, (PVOID)v16);
      if( v16 )
        *(_BYTE *)(v16 + 26) |= 1u;
      v5->BcbLock.Owner = KeGetCurrentThread();
      v5->BcbLock.OldIrql = CurrentIrql;
      Mbcb = (INT64)v5->Mbcb;
      if( !Mbcb )
      {
        InitializeMbcb = CcAllocateInitializeMbcb();
        Mbcb = (INT64)InitializeMbcb;
        if( !InitializeMbcb )
          goto LABEL_102;
        v5->Mbcb = (_MBCB *)InitializeMbcb;
      }
      if( v7 == v8 && v7 == *(_QWORD *)(Mbcb + 40) )
        goto LABEL_53;
      if( (unsigned __int64)v8 < 0x300 || *(_WORD *)Mbcb == 761 )
        break;
      v42 = ListEntry;
      memset((INT64)ListEntry, 0i64);
      if( *(_DWORD *)(Mbcb + 80) )
      {
        v43 = *(struct _SLIST_ENTRY **)(Mbcb + 88);
        *v42 = *v43;
        v42[1] = v43[1];
        v42[2] = v43[2];
        v42[3] = v43[3];
        v42[4] = v43[4];
        v42[5] = v43[5];
        memset(*(_QWORD *)(Mbcb + 88), 0i64);
      }
      *(_QWORD *)(Mbcb + 88) = v42;
      v44 = *(INT64 ***)(Mbcb + 24);
      v45 = (INT64 *)(Mbcb + 96);
      ListEntry = 0i64;
      v46 = Mbcb + 16;
      if( *v44 != (INT64 *)(Mbcb + 16) )
        goto LABEL_86;
      *v45 = v46;
      *(_QWORD *)(Mbcb + 104) = v44;
      *v44 = v45;
      *(_QWORD *)(Mbcb + 24) = v45;
      v47 = (INT64 *)(Mbcb + 144);
      *(_QWORD *)(Mbcb + 112) = 0x7FFFFFFFFFFFFFFFi64;
      *(_DWORD *)(Mbcb + 120) = -1;
      v48 = *(INT64 ***)(Mbcb + 24);
      if( *v48 != (INT64 *)v46 )
LABEL_86:
        __fastfail(3u);
      *v47 = v46;
      *(_QWORD *)(Mbcb + 152) = v48;
      *v48 = v47;
      *(_QWORD *)(Mbcb + 24) = v47;
      *(_QWORD *)(Mbcb + 160) = 0x7FFFFFFFFFFFFFFFi64;
      *(_DWORD *)(Mbcb + 168) = -1;
      *(_WORD *)Mbcb = 761;
      KeReleaseGuardedMutex(&v5->BcbLock);
    }
    BitmapRangeToDirty = CcFindBitmapRangeToDirty(Mbcb, v7, &ListEntry);
    v22 = BitmapRangeToDirty;
    if( BitmapRangeToDirty )
    {
      v23 = *(_QWORD *)(BitmapRangeToDirty + 16);
      if( v7 < v23 + *(unsigned int *)(BitmapRangeToDirty + 24) )
        *(_DWORD *)(BitmapRangeToDirty + 24) = v7 - v23;
      if( v8 > v23 + *(unsigned int *)(BitmapRangeToDirty + 28) )
        *(_DWORD *)(BitmapRangeToDirty + 28) = v8 - v23;
      v24 = FastScan[0];
      LockHandle.LockQueue.Next = 0i64;
      LockHandle.LockQueue.Lock = (unsigned __int64 *volatile)(*(_QWORD *)FastScan + 128i64);
      v25 = KeGetCurrentIrql();
      __writecr8(2ui64);
      LockHandle.OldIrql = v25;
      CurrentPrcb = KeGetCurrentPrcb();
      if( *((_QWORD *)CurrentPrcb + 4247) && *((_BYTE *)CurrentPrcb + 32) <= 1u && *((_BYTE *)CurrentPrcb + 32) == 1 )
        v24 = FastScan[0];
      v27 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64(
                                  (volatile __int64 *)(*(_QWORD *)FastScan + 128i64),
                                  (__int64)&LockHandle);
      if( v27 )
      {
        KxWaitForLockOwnerShip(&LockHandle.LockQueue, v27);
        v24 = FastScan[0];
      }
      if( !v5->DirtyPages && (v5->Flags & 2) == 0 )
      {
        CcScheduleLazyWriteScan(v24, 0);
        CcInsertIntoDirtySharedCacheMapList(v5);
        *(_QWORD *)(Mbcb + 32) = v7;
      }
      v28 = (_DWORD *)(*(_QWORD *)(v22 + 40) + 4 * ((unsigned __int64)(unsigned int)(v7 - *(_DWORD *)(v22 + 16)) >> 5));
      v29 = 1 << (v7 & 0x1F);
      if( v7 <= v8 )
      {
        v30 = v51;
        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 );
        v51 = v30;
        v5 = SharedCacheMap;
      }
      CcChargeDirtyPages((INT64)v5, Mbcb, v22, v51);
      _m_prefetchw(&LockHandle);
      Next = LockHandle.LockQueue.Next;
      if( !LockHandle.LockQueue.Next )
      {
        if( (struct _KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
                                             (volatile signed __int64 *)LockHandle.LockQueue.Lock,
                                             0i64,
                                             (signed __int64)&LockHandle) == &LockHandle )
        {
LABEL_50:
          __writecr8(LockHandle.OldIrql);
          if( (v5->Flags & 0x10000000) != 0 && v51 )
          {
            v39 = IoIssuerThread;
            if( !IoIssuerThread )
            {
              v39 = (_ETHREAD *)KeGetCurrentThread();
              IoIssuerThread = v39;
            }
            v40 = *(_QWORD *)(*((_QWORD *)v39 + 68) + 2232i64);
            if( v40 )
            {
              if( v51 << 12 )
                _InterlockedExchangeAdd64((volatile signed __int64 *)(v40 + 8), v51 << 12);
              _InterlockedExchangeAdd64((volatile signed __int64 *)(v40 + 24), 1ui64);
            }
          }
          if( v29 )
          {
            *(_QWORD *)(Mbcb + 40) = v8;
LABEL_53:
            Partition = *(_CC_PARTITION **)FastScan;
            goto LABEL_54;
          }
          continue;
        }
        Next = KxWaitForLockChainValid(&LockHandle.LockQueue);
      }
      LockHandle.LockQueue.Next = 0i64;
      _InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
      goto LABEL_50;
    }
    break;
  }
LABEL_102:
  i = 1;
LABEL_103:
  if( (v5->Flags & 0x20000) == 0 )
  {
    KeAcquireInStackQueuedSpinLock((UINT64 *)(*(_QWORD *)FastScan + 128i64), &LockHandle);
    v5->Flags |= 0x20000u;
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
    __writecr8(LockHandle.OldIrql);
  }
  if( i )
  {
LABEL_56:
    v36 = &v5->BcbLock;
    OldIrql_low = LOBYTE(v36->OldIrql);
    v36->Owner = 0i64;
    v38 = _InterlockedCompareExchange(&v36->Count, 1, 0);
    if( v38 )
      ExpReleaseFastMutexContended(v36, v38);
    __writecr8(OldIrql_low);
    KeAbPostRelease(v36);
  }
  if( ListEntry )
  {
    ++dword_140CDB3DC;
    if( (unsigned __int16)CcBitmapLookasideList >= (unsigned __int16)word_140CDB3D0 )
    {
      ++dword_140CDB3E0;
      ((void(*)(void))qword_140CDB3F8)();
    }
    else
    {
      RtlpInterlockedPushEntrySList((PSLIST_HEADER)&CcBitmapLookasideList, ListEntry);
    }
  }
}

Referenced by:

CcMapAndCopyInToCache
CcMdlWriteComplete2
CcPurgeAndClearCacheSection
CcReleaseByteRangeFromWrite
CcSetDirtyPinnedData