CcScheduleReadAheadEx

VOID __stdcall CcScheduleReadAheadEx(
        VOID *FileObject,
        _LARGE_INTEGER *FileOffset,
        UINT64 Length,
        _ETHREAD *IoIssuerThread){
  UINT8 *Partition; 
  PRIVATE_CACHE_MAP *v5; 
  _ETHREAD *CurrentThread; 
  __int64 v7; 
  __int64 v9; 
  _DWORD *v11; 
  _IO_PRIORITY_HINT IoPriorityThread; 
  int v13; 
  LONGLONG v14; 
  int v15; 
  _CC_READ_PATTERN Pattern; 
  _CC_READ_PATTERN ReadPattern; 
  signed __int64 QuadPart; 
  int v19; 
  unsigned int SequentialReadCount; 
  UINT64 v21; 
  _LARGE_INTEGER *v22; 
  int PagePriorityThread; 
  int v24; 
  _LARGE_INTEGER *v25; 
  UINT64 v26; 
  _WORK_QUEUE_ENTRY *v27; 
  _LIST_ENTRY *v28; 
  int v29; 
  _LARGE_INTEGER *v30; 
  __int64 ReadAheadGrowth; 
  unsigned int v32; 
  unsigned __int64 v33; 
  unsigned __int8 v34; 
  unsigned __int64 v35; 
  UINT64 v36; 
  UINT64 v37; 
  __int64 v38; 
  _LARGE_INTEGER ReadAheadBeyondLastByte; 
  LONGLONG v40; 
  _WORK_QUEUE_ENTRY *WorkQueueEntry; 
  UINT8 *v42; 
  UINT64 *SpinLock; 
  _KLOCK_QUEUE_HANDLE LockHandle; 
  unsigned __int8 v45; 
  unsigned int Lengtha; 
  _ETHREAD *IoIssuerThreada; 

  IoIssuerThreada = IoIssuerThread;
  Lengtha = Length;
  WorkQueueEntry = 0i64;
  Partition = 0i64;
  v5 = (PRIVATE_CACHE_MAP *)*((_QWORD *)FileObject + 6);
  CurrentThread = IoIssuerThread;
  v7 = *((_QWORD *)FileObject + 5);
  memset(&LockHandle, 0, sizeof(LockHandle));
  v9 = (unsigned int)Length;
  v42 = 0i64;
  v11 = *(_DWORD **)(v7 + 8);
  if( v11 )
  {
    Partition = (UINT8 *)CcGetPartition(*(_QWORD **)(v7 + 8));
    v42 = Partition;
  }
  if( !CurrentThread )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    IoIssuerThreada = CurrentThread;
  }
  IoPriorityThread = PsGetIoPriorityThread(CurrentThread);
  if( v5 )
  {
    if( v11 )
    {
      v13 = v11[38];
      if( (v13 & 1) == 0
        && (v13 & 0x2000) == 0
        && (*((_DWORD *)FileObject + 20) & 0x100000) == 0
        && IoPriorityThread >= IoPriorityNormal
        && CcCanIWriteStreamEx(Partition, (INT64)FileObject, 0x1000000ui64, 0i64, 4, 0i64)
        && (!Partition || !Partition[352]) )
      {
        v14 = v9 + FileOffset->QuadPart;
        v38 = v9;
        v15 = ~v5->ReadAheadMask & (v5->ReadAheadMask + v9);
        SpinLock = &v5->ReadAheadSpinLock;
        v45 = KeAcquireSpinLockRaiseToDpc(&v5->ReadAheadSpinLock);
        if( (*(_DWORD *)&v5->0 & 0x20000) == 0 )
          *(_DWORD *)&v5->0 |= 0x20000u;
        Pattern = CcDetermineReadPattern(v5, FileOffset);
        ReadPattern = Pattern;
        if( Pattern )
        {
          if( Pattern > NoPattern )
          {
            if( Pattern > DetectedSequential )
            {
              v30 = FileOffset;
              if( Pattern != Strided || (v40 = 2 * FileOffset->QuadPart - v5->FileOffset2.QuadPart, v40 < 0) )
              {
                v29 = 0;
                goto LABEL_35;
              }
              v32 = (v40 & 0xFFF) + Lengtha;
              LODWORD(v40) = v40 & 0xFFFFF000;
              Lengtha = v32;
              v5->ReadAheadOffset.QuadPart = v40;
              v21 = (v32 + 4095) & 0xFFFFF000;
              goto LABEL_25;
            }
            QuadPart = v5->ReadAheadBeyondLastByte.QuadPart;
            if( v14 + v38 + (unsigned int)(2 * v15) >= QuadPart )
            {
              ReadAheadBeyondLastByte = v5->ReadAheadBeyondLastByte;
              v5->ReadAheadOffset.QuadPart = v14 & 0xFFFFFFFFFFFFF000ui64;
              if( (__int64)(v14 & 0xFFFFFFFFFFFFF000ui64) >= QuadPart )
                ReadAheadBeyondLastByte.anonymous_0.LowPart = ~(v15 - 1) & (v15 + v14 - 1);
              ++v5->SequentialReadCount;
              v19 = v15;
              SequentialReadCount = v5->SequentialReadCount;
              if( Pattern == Sequential || SequentialReadCount >= 3 )
                v19 = 2 * v15;
              v21 = ReadAheadBeyondLastByte.anonymous_0.LowPart - v5->ReadAheadOffset.anonymous_0.LowPart + v19;
              if( SequentialReadCount >= 3 )
              {
                ReadAheadGrowth = v5->ReadAheadGrowth;
                if( (_DWORD)ReadAheadGrowth )
                {
                  v33 = ReadAheadGrowth * (unsigned __int64)(Lengtha * SequentialReadCount) / 0x64;
                  if( v33 > 0xFFFFFFFF )
                    v33 = 0xFFFFFFFFi64;
                  if( v33 > (unsigned int)v21 )
                    v21 = (unsigned int)v33;
                }
              }
LABEL_25:
              v5->ReadAheadLength = v21;
              v22 = (_LARGE_INTEGER *)(unsigned int)v5->0;
              if( ((unsigned int)v22 & 0x10000) == 0 )
              {
                v5->Flags = (_PRIVATE_CACHE_MAP_FLAGS)((unsigned int)v22 | 0x10000);
                PagePriorityThread = PsGetPagePriorityThread((_ETHREAD *)KeGetCurrentThread());
                v5->Flags = (_PRIVATE_CACHE_MAP_FLAGS)(v24 ^ (v24 ^ (PagePriorityThread << 18)) & 0x1C0000);
                KxReleaseSpinLock(&v5->ReadAheadSpinLock);
                __writecr8(v45);
                if( (int)CcAllocateWorkQueueEntry((__int64)Partition, (PSLIST_ENTRY *)&WorkQueueEntry) < 0 )
                {
                  v34 = KeAcquireSpinLockRaiseToDpc(&v5->ReadAheadSpinLock);
                  *(_DWORD *)&v5->0 &= ~0x10000u;
                  v35 = v34;
                  KxReleaseSpinLock(&v5->ReadAheadSpinLock);
                  __writecr8(v35);
                }
                else
                {
                  v27 = WorkQueueEntry;
                  if( (xmmword_140CFB490 & 0x20000) != 0 )
                  {
                    LODWORD(v37) = 1;
                    LODWORD(v36) = v15;
                    CcPerfLogScheduleReadAhead(
                      WorkQueueEntry,
                      (_FILE_OBJECT *)FileObject,
                      FileOffset,
                      Lengtha,
                      v36,
                      ReadPattern,
                      v37);
                  }
                  if( (v11[38] & 0x10000000) != 0 )
                    CcChargeThreadForReadAhead((_FILE_OBJECT *)FileObject, v25, v26, ReadPattern, IoIssuerThreada);
                  ObfReferenceObjectWithTag(FileObject, 0x746C6644ui64);
                  v28 = (_LIST_ENTRY *)v42;
                  KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)v42 + 16, &LockHandle);
                  ++v11[1];
                  ++v11[134];
                  v11[38] |= 0x4000u;
                  KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
                  __writecr8(LockHandle.OldIrql);
                  v5->ReadAheadWorkItem = v27;
                  *((_BYTE *)v27 + 120) = 1;
                  *((_QWORD *)v27 + 2) = FileObject;
                  *((_QWORD *)v27 + 3) = 0i64;
                  IoReferenceIoAttributionFromThread(IoIssuerThreada, (PVOID *)v27 + 3);
                  CcPostWorkQueue(v27, v28 + 15);
                }
                return;
              }
              v29 = 1;
              if( (v11[38] & 0x10000000) != 0 )
              {
                CcChargeThreadForReadAhead((_FILE_OBJECT *)FileObject, v22, v21, ReadPattern, IoIssuerThreada);
                v29 = 1;
              }
              goto LABEL_34;
            }
          }
        }
        else
        {
          v5->SequentialReadCount = 0;
          v5->ReadAheadBeyondLastByte.QuadPart = 0i64;
          v5->PrevReadAheadBeyondLastByte = 0i64;
        }
        v29 = 0;
LABEL_34:
        v30 = FileOffset;
LABEL_35:
        if( (xmmword_140CFB490 & 0x20000) != 0 )
        {
          LODWORD(v37) = v29;
          LODWORD(v36) = v15;
          CcPerfLogScheduleReadAhead(0i64, (_FILE_OBJECT *)FileObject, v30, Lengtha, v36, ReadPattern, v37);
        }
        KxReleaseSpinLock(SpinLock);
        __writecr8(v45);
      }
    }
  }
}

Referenced by:

CcAsyncCopyRead
CcAsyncReadPrefetch
CcCopyReadEx
CcMdlRead
CcScheduleReadAhead