CcScheduleReadAheadEx

VOID __fastcall CcScheduleReadAheadEx(
        _FILE_OBJECT *FileObject,
        _LARGE_INTEGER *FileOffset,
        UINT64 Length,
        _ETHREAD *IoIssuerThread){
  UINT8 *Partition; 
  LARGE_INTEGER *PrivateCacheMap; 
  _ETHREAD *CurrentThread; 
  _SECTION_OBJECT_POINTERS *SectionObjectPointer; 
  __int64 v9; 
  _DWORD *SharedCacheMap; 
  int IoPriorityThread; 
  int v13; 
  UINT64 v14; 
  LONGLONG v15; 
  int v16; 
  unsigned __int8 v17; 
  int Pattern; 
  int ReadPattern; 
  signed __int64 QuadPart; 
  int v21; 
  unsigned int LowPart; 
  __int64 v23; 
  __int64 v24; 
  int PagePriorityThread; 
  int v26; 
  UINT64 v27; 
  __int64 v28; 
  PSLIST_ENTRY v29; 
  _LIST_ENTRY *v30; 
  int v31; 
  _LARGE_INTEGER *v32; 
  __int64 HighPart; 
  unsigned int v34; 
  unsigned __int64 v35; 
  unsigned __int8 v36; 
  unsigned __int64 v37; 
  UINT64 v38; 
  UINT64 v39; 
  __int64 v40; 
  LARGE_INTEGER v41; 
  LONGLONG v42; 
  PSLIST_ENTRY v43; 
  UINT8 *v44; 
  PKSPIN_LOCK SpinLock; 
  struct _KLOCK_QUEUE_HANDLE LockHandle; 
  unsigned __int8 v47; 
  unsigned int Lengtha; 
  _ETHREAD *Thread; 
  Thread = IoIssuerThread;
  Lengtha = Length;
  v43 = 0i64;
  Partition = 0i64;
  PrivateCacheMap = (LARGE_INTEGER *)FileObject->PrivateCacheMap;
  CurrentThread = IoIssuerThread;
  SectionObjectPointer = FileObject->SectionObjectPointer;
  memset(&LockHandle, 0, sizeof(LockHandle));
  v9 = (unsigned int)Length;
  v44 = 0i64;
  SharedCacheMap = SectionObjectPointer->SharedCacheMap;
  if( SharedCacheMap )
  {
    Partition = (UINT8 *)CcGetPartition((_QWORD *)SectionObjectPointer->SharedCacheMap);
    v44 = Partition;
  }
  if( !CurrentThread )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    Thread = CurrentThread;
  }
  IoPriorityThread = PsGetIoPriorityThread((__int64)CurrentThread);
  if( PrivateCacheMap )
  {
    if( SharedCacheMap )
    {
      v13 = SharedCacheMap[38];
      if( (v13 & 1) == 0
        && (v13 & 0x2000) == 0
        && (FileObject->Flags & 0x100000) == 0
        && IoPriorityThread >= 2
        && CcCanIWriteStreamEx(Partition, (INT64)FileObject, 0x1000000ui64, 0i64, 4, 0i64)
        && (!Partition || !Partition[352]) )
      {
        v15 = v9 + FileOffset->QuadPart;
        v40 = v9;
        v16 = ~PrivateCacheMap->HighPart & (PrivateCacheMap->HighPart + v9);
        SpinLock = (PKSPIN_LOCK)&PrivateCacheMap[10].QuadPart;
        KeAcquireSpinLockRaiseToDpc((UINT64 *)&PrivateCacheMap[10].QuadPart, v14);
        v47 = v17;
        if( (PrivateCacheMap->LowPart & 0x20000) == 0 )
          PrivateCacheMap->LowPart |= 0x20000u;
        Pattern = CcDetermineReadPattern(PrivateCacheMap, FileOffset);
        ReadPattern = Pattern;
        if( Pattern )
        {
          if( Pattern > 0 )
          {
            if( Pattern > 2 )
            {
              v32 = FileOffset;
              if( Pattern != 3 || (v42 = 2 * FileOffset->QuadPart - PrivateCacheMap[4].QuadPart, v42 < 0) )
              {
                v31 = 0;
                goto LABEL_35;
              }
              v34 = (v42 & 0xFFF) + Lengtha;
              LODWORD(v42) = v42 & 0xFFFFF000;
              Lengtha = v34;
              PrivateCacheMap[7].QuadPart = v42;
              v23 = (v34 + 4095) & 0xFFFFF000;
              goto LABEL_25;
            }
            QuadPart = PrivateCacheMap[8].QuadPart;
            if( v15 + v40 + (unsigned int)(2 * v16) >= QuadPart )
            {
              v41 = PrivateCacheMap[8];
              PrivateCacheMap[7].QuadPart = v15 & 0xFFFFFFFFFFFFF000ui64;
              if( (__int64)(v15 & 0xFFFFFFFFFFFFF000ui64) >= QuadPart )
                v41.LowPart = ~(v16 - 1) & (v16 + v15 - 1);
              ++PrivateCacheMap[6].LowPart;
              v21 = v16;
              LowPart = PrivateCacheMap[6].LowPart;
              if( Pattern == 1 || LowPart >= 3 )
                v21 = 2 * v16;
              v23 = v41.LowPart - PrivateCacheMap[7].LowPart + v21;
              if( LowPart >= 3 )
              {
                HighPart = (unsigned int)PrivateCacheMap[11].HighPart;
                if( (_DWORD)HighPart )
                {
                  v35 = HighPart * (unsigned __int64)(Lengtha * LowPart) / 0x64;
                  if( v35 > 0xFFFFFFFF )
                    v35 = 0xFFFFFFFFi64;
                  if( v35 > (unsigned int)v23 )
                    v23 = (unsigned int)v35;
                }
              }
LABEL_25:
              PrivateCacheMap[6].HighPart = v23;
              v24 = PrivateCacheMap->LowPart;
              if( (v24 & 0x10000) == 0 )
              {
                PrivateCacheMap->LowPart = v24 | 0x10000;
                PagePriorityThread = PsGetPagePriorityThread((__int64)KeGetCurrentThread());
                PrivateCacheMap->LowPart = v26 ^ (v26 ^ (PagePriorityThread << 18)) & 0x1C0000;
                KxReleaseSpinLock((UINT64 *)&PrivateCacheMap[10].QuadPart);
                __writecr8(v47);
                if( (int)CcAllocateWorkQueueEntry((INT64)Partition, &v43) < 0 )
                {
                  KeAcquireSpinLockRaiseToDpc((UINT64 *)&PrivateCacheMap[10].QuadPart, v27);
                  PrivateCacheMap->LowPart &= ~0x10000u;
                  v37 = v36;
                  KxReleaseSpinLock((UINT64 *)&PrivateCacheMap[10].QuadPart);
                  __writecr8(v37);
                }
                else
                {
                  v29 = v43;
                  if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x20000) != 0 )
                  {
                    LODWORD(v39) = 1;
                    LODWORD(v38) = v16;
                    CcPerfLogScheduleReadAhead(
                      (_WORK_QUEUE_ENTRY *)v43,
                      FileObject,
                      FileOffset,
                      Lengtha,
                      v38,
                      ReadPattern,
                      v39);
                  }
                  if( (SharedCacheMap[38] & 0x10000000) != 0 )
                    CcChargeThreadForReadAhead((__int64)FileObject, v27, v28, ReadPattern, Thread);
                  ObfReferenceObjectWithTag(FileObject, 0x746C6644u);
                  v30 = (_LIST_ENTRY *)v44;
                  KeAcquireInStackQueuedSpinLock((UINT64 *)v44 + 16, &LockHandle);
                  ++SharedCacheMap[1];
                  ++SharedCacheMap[134];
                  SharedCacheMap[38] |= 0x4000u;
                  KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
                  __writecr8(LockHandle.OldIrql);
                  PrivateCacheMap[14].QuadPart = (LONGLONG)v29;
                  *((_BYTE *)&v29[7].Next + 8) = 1;
                  v29[1].Next = (_SLIST_ENTRY *)FileObject;
                  *((_QWORD *)&v29[1].Next + 1) = 0i64;
                  IoReferenceIoAttributionFromThread(Thread, (PVOID *)&v29[1].Next + 1);
                  CcPostWorkQueue((_WORK_QUEUE_ENTRY *)v29, v30 + 15);
                }
                return;
              }
              v31 = 1;
              if( (SharedCacheMap[38] & 0x10000000) != 0 )
              {
                CcChargeThreadForReadAhead((__int64)FileObject, v24, v23, ReadPattern, Thread);
                v31 = 1;
              }
              goto LABEL_34;
            }
          }
        }
        else
        {
          PrivateCacheMap[6].LowPart = 0;
          PrivateCacheMap[8].QuadPart = 0i64;
          PrivateCacheMap[9].QuadPart = 0i64;
        }
        v31 = 0;
LABEL_34:
        v32 = FileOffset;
LABEL_35:
        if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x20000) != 0 )
        {
          LODWORD(v39) = v31;
          LODWORD(v38) = v16;
          CcPerfLogScheduleReadAhead(0i64, FileObject, v32, Lengtha, v38, ReadPattern, v39);
        }
        KxReleaseSpinLock(SpinLock);
        __writecr8(v47);
      }
    }
  }
}

Referenced by:

CcAsyncCopyRead
CcAsyncReadPrefetch
CcCopyReadEx
CcMdlRead
CcScheduleReadAhead