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