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