CcMapAndCopyInToCache
UINT8 __stdcall CcMapAndCopyInToCache(
_SHARED_CACHE_MAP *SharedCacheMap,
VOID *UserBuffer,
_LARGE_INTEGER *FileOffset,
UINT64 Length,
UINT64 OptimizeFlags,
_FILE_OBJECT *FileObject,
_LARGE_INTEGER *ValidDataLength,
UINT8 Wait,
_ETHREAD *IoIssuerThread){
_SHARED_CACHE_MAP *v9;
UINT8 v10;
_LARGE_INTEGER *v11;
bool v12;
int v13;
_WORK_QUEUE_ENTRY *v14;
char v15;
__int64 v16;
__int64 v17;
_IO_PRIORITY_HINT BaseIoPriorityThread;
__int64 v19;
int v20;
__int64 v21;
__int64 v22;
_ETHREAD *v23;
UINT64 WorkOnBehalfThread;
_EPROCESS *Process;
int v26;
_VACB *v27;
__int64 v28;
int v29;
char *VirtualAddress;
unsigned int v31;
ULONG v32;
char *v33;
unsigned int v34;
int v35;
ULONG v36;
unsigned int v37;
_BOOL8 v38;
int v39;
int v40;
ULONG v41;
int v42;
int v43;
unsigned int v44;
NTSTATUS v45;
_SHARED_CACHE_MAP *v46;
_KEVENT *v47;
NTSTATUS v48;
_MDL *v49;
UINT64 v50;
bool v51;
_MMPTE *v52;
int v53;
size_t v54;
int v55;
bool v56;
INT64 v57;
INT64 v58;
int v59;
unsigned int v60;
_ETHREAD *v61;
_ETHREAD *v62;
char v63;
NTSTATUS v64;
char v65;
UINT64 v66;
int Status;
NTSTATUS v68;
char v69;
unsigned int v70;
_ETHREAD *v71;
UINT64 v73;
unsigned __int64 v74;
volatile signed __int64 *DiskIoAttribution;
unsigned __int64 v76;
_SHARED_CACHE_MAP *v77;
__int64 v78;
_WORK_QUEUE_ENTRY **v79;
_KEVENT *v80;
char v81;
NTSTATUS v82;
UINT64 RequestHighPriorityMapping;
UINT64 PerformingReadAhead;
UINT8 v85;
bool v86;
char v87;
char v88;
bool v89;
char v90;
int v91;
UINT8 ReturnResult;
bool v93;
bool v94;
char v95;
UINT8 v96;
char v97;
UINT64 Lengtha;
ULONG Offset;
int Offset_4;
unsigned int ReceivedLength;
UINT64 ReceivedLength_4;
int v103;
VOID *v104;
_VACB *Vacb;
unsigned int v106;
unsigned int v107;
unsigned int v108;
int v109;
INT64 v110;
_IO_STATUS_BLOCK IoStatus;
LONGLONG v112;
_ETHREAD *CurrentThread;
_KLOCK_QUEUE_HANDLE LockHandle;
unsigned int Flags;
_BOOL4 Flags_4;
unsigned int v117;
int v118;
NTSTATUS v119;
int v120;
unsigned int v121;
_MDL *v122;
VOID *IoAttributionContext;
_KLOCK_QUEUE_HANDLE LockQueue;
_BOOL4 v125;
NTSTATUS v126;
UINT64 v127;
__int64 v128;
__int64 v129;
_KLOCK_QUEUE_HANDLE v130;
unsigned int er8;
er8 = Length;
v108 = Length;
v9 = SharedCacheMap;
v10 = Wait;
v11 = 0i64;
ReceivedLength = 0;
LODWORD(Lengtha) = 0;
v112 = 0i64;
IoStatus = 0i64;
v12 = (FileObject->Flags & 0x10) != 0;
v85 = v12;
v118 = Length;
Offset = FileOffset->anonymous_0.LowPart & 0xFFF;
Vacb = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v13 = 0;
v91 = 0;
v95 = 0;
v88 = 0;
v14 = 0i64;
IoAttributionContext = 0i64;
ReturnResult = 1;
v87 = 0;
v90 = 0;
memset(&LockHandle, 0, sizeof(LockHandle));
memset(&LockQueue, 0, sizeof(LockQueue));
v89 = (*((_DWORD *)SharedCacheMap + 38) & 0x1000) != 0;
ReceivedLength_4 = FileOffset->QuadPart;
v107 = CurrentThread->CacheManagerActive + 4 * CurrentThread->ReadClusterSize;
v117 = v107;
v15 = v12;
v94 = v12;
v97 = v12;
if( !v12 )
{
v94 = 0;
memset(&v130, 0, sizeof(v130));
v16 = *((_QWORD *)SharedCacheMap + 66);
if( *((_QWORD *)SharedCacheMap + 21) )
{
LODWORD(v17) = MmGetControlAreaPartition(*(_QWORD *)((*((_QWORD *)SharedCacheMap + 12) & 0xFFFFFFFFFFFFFFF0ui64)
+ 0x28));
if( v16 != *(_QWORD *)(v17 + 8) )
KeBugCheckEx(0x34u, (PVOID)0x1313, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
}
if( (FileObject->Flags & 0x1000000) == 0
|| CcCanIWriteStreamEx((UINT8 *)v16, (INT64)FileObject, er8, 0i64, 0, 0i64) )
{
BaseIoPriorityThread = PsGetBaseIoPriorityThread((_ETHREAD *)KeGetCurrentThread());
if( BaseIoPriorityThread < IoPriorityNormal
&& (struct _KTHREAD *)v19 == KeGetCurrentThread()
&& *(_DWORD *)(v19 + 1360)
|| BaseIoPriorityThread > IoPriorityVeryLow
|| (FileObject->Flags & 0x8000) != 0 )
{
v13 = 0;
LABEL_8:
v97 = v15;
v12 = v85;
v10 = Wait;
goto LABEL_9;
}
v13 = 0;
}
v15 = 1;
v94 = 1;
if( (*((_DWORD *)v9 + 38) & 0x400) == 0 )
{
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v16 + 128), &v130);
*((_DWORD *)v9 + 38) |= 0x400u;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&v130);
__writecr8(v130.OldIrql);
}
goto LABEL_8;
}
LABEL_9:
if( v15 && !v10 )
return 0;
v20 = 6;
if( v10 )
v20 = 4;
Flags = v20;
v21 = *((_QWORD *)v9 + 66);
v128 = v21;
if( *((_QWORD *)v9 + 21) )
{
LODWORD(v22) = MmGetControlAreaPartition(*(_QWORD *)((*((_QWORD *)v9 + 12) & 0xFFFFFFFFFFFFFFF0ui64) + 0x28));
if( v21 != *(_QWORD *)(v22 + 8) )
KeBugCheckEx(0x34u, (PVOID)0x1313, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
}
v129 = v21;
if( v12 )
{
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v21 + 128), &LockHandle);
if( (*((_DWORD *)v9 + 38) & 0x20) != 0 )
{
LockQueue.LockQueue.Lock = (unsigned __int64 *volatile)(v21 + 192);
LockQueue.LockQueue.Next = 0i64;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, (UINT64 *)(v21 + 192));
v14 = (_WORK_QUEUE_ENTRY *)*((_QWORD *)v9 + 62);
if( !v14 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
KeReleaseInStackQueuedSpinLock(&LockHandle);
KeDelayExecutionThread(0, 0, &Cc5Milliseconds);
RtlRaiseStatus(-1073741608);
}
v78 = *(_QWORD *)v14;
v79 = (_WORK_QUEUE_ENTRY **)*((_QWORD *)v14 + 1);
if( *(_WORK_QUEUE_ENTRY **)(*(_QWORD *)v14 + 8i64) != v14 || *v79 != v14 )
__fastfail(3u);
*v79 = (_WORK_QUEUE_ENTRY *)v78;
*(_QWORD *)(v78 + 8) = v79;
*((_QWORD *)v14 + 1) = 0i64;
*(_QWORD *)v14 = 0i64;
*((_QWORD *)v9 + 62) = 0i64;
*((_DWORD *)v9 + 38) &= ~0x20u;
v88 = 1;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
}
++*((_DWORD *)v9 + 129);
v95 = 1;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
if( v14 )
CcFreeWorkQueueEntry(v14);
v23 = IoIssuerThread;
if( !IoIssuerThread )
{
v23 = (_ETHREAD *)KeGetCurrentThread();
IoIssuerThread = v23;
v13 = 0;
}
WorkOnBehalfThread = (UINT64)v23->WorkOnBehalfThread;
v109 = 0;
if( !WorkOnBehalfThread )
goto LABEL_20;
if( v23 != (_ETHREAD *)KeGetCurrentThread() )
{
v76 = (unsigned __int8)ExAcquireSpinLockShared(&PspThreadWorkOnBehalfLock);
WorkOnBehalfThread = (UINT64)v23->WorkOnBehalfThread;
if( WorkOnBehalfThread )
{
ObfReferenceObjectWithTag(v23->WorkOnBehalfThread, 0x746C6644ui64);
v109 = 1;
}
ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)&PspThreadWorkOnBehalfLock);
__writecr8(v76);
}
v13 = 0;
if( WorkOnBehalfThread )
Process = *(_EPROCESS **)(WorkOnBehalfThread + 544);
else
LABEL_20:
Process = v23->Tcb.Process;
if( Process->DiskIoAttribution )
{
v74 = (unsigned __int8)ExAcquireSpinLockShared((INT64 *)&stru_140C452E0 + 139);
DiskIoAttribution = (volatile signed __int64 *)Process->DiskIoAttribution;
if( DiskIoAttribution )
{
if( _InterlockedIncrement64(DiskIoAttribution + 4) <= 1 )
__fastfail(0xEu);
IoAttributionContext = (VOID *)DiskIoAttribution;
v13 = 0;
}
ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)&stru_140C452E0 + 278);
__writecr8(v74);
if( DiskIoAttribution )
v26 = 0;
else
v26 = -1073741275;
}
else
{
v26 = -1073741275;
}
if( v109 )
ObDereferenceObjectDeferDelete(WorkOnBehalfThread);
Offset_4 = v26;
if( v26 >= 0 )
{
MmUpdateSectionIoAttribution(FileObject->SectionObjectPointer, IoAttributionContext);
IoDiskIoAttributionDereference(IoAttributionContext);
}
v27 = Vacb;
LODWORD(v28) = Lengtha;
while( er8 )
{
if( v89 )
{
v29 = 0;
LODWORD(OptimizeFlags) = 0;
}
else
{
v29 = OptimizeFlags;
}
LODWORD(Lengtha) = 0;
LODWORD(PerformingReadAhead) = 0;
LODWORD(RequestHighPriorityMapping) = 0;
VirtualAddress = (char *)CcGetVirtualAddress(
v9,
(_LARGE_INTEGER)ReceivedLength_4,
&Vacb,
(UINT64 *)&ReceivedLength,
RequestHighPriorityMapping,
PerformingReadAhead);
v104 = VirtualAddress;
v31 = ReceivedLength;
if( ReceivedLength > er8 )
{
v31 = er8;
ReceivedLength = er8;
}
LODWORD(Lengtha) = v31;
er8 -= v31;
v32 = Offset;
v33 = &VirtualAddress[-Offset];
v104 = v33;
v34 = Offset + v31;
v106 = v34;
ReceivedLength = v34;
v35 = 1;
v103 = 1;
HIDWORD(v112) = HIDWORD(ReceivedLength_4);
v36 = ReceivedLength_4 - Offset;
LODWORD(v112) = ReceivedLength_4 - Offset;
v87 = 0;
v86 = 0;
v37 = v34;
while( 1 )
{
ReturnResult = 1;
v38 = v37 > 0x1000;
Flags_4 = v37 > 0x1000;
v125 = Flags_4;
Offset_4 = 0;
if( (v35 & v29) != 0 )
{
if( v112 >= ValidDataLength->QuadPart )
{
v13 |= 1u;
v91 = v13;
}
v39 = *((_DWORD *)v9 + 38);
if( (v39 & 0x40) != 0 )
{
v13 |= 2u;
v91 = v13;
}
if( (v39 & 0x40000000) != 0 )
{
v63 = 0;
if( v37 <= 0x1000 )
v63 = v34;
if( (((unsigned __int8)v32 | (unsigned __int8)(v63 - v32)) & 0x3F) != 0 )
{
v13 &= 0xFFFFFFF3;
v91 = v13;
v86 = 1;
}
else
{
v13 |= 4u;
v91 = v13;
if( v85 )
{
v13 |= 8u;
v91 = v13;
}
}
}
v40 = 4096;
if( v37 <= 0x1000 )
v40 = v34;
v41 = v40 - v32;
v42 = v13;
v120 = v13;
v43 = 0;
v119 = 0;
v44 = 1;
v121 = 1;
while( v44 <= 2 )
{
LODWORD(RequestHighPriorityMapping) = v42;
v45 = MmCopyToCachedPage(v33, UserBuffer, v32, v41, RequestHighPriorityMapping);
v43 = v45;
v119 = v45;
if( (v42 & 8) == 0 || v45 != -1073741670 )
{
v32 = Offset;
break;
}
v42 &= 0xFFFFFFF3;
v120 = v42;
v121 = ++v44;
v32 = Offset;
v33 = (char *)v104;
}
v93 = (v42 & 4) == 0;
Offset_4 = v43;
if( v43 < 0 )
{
FsRtlIsNtstatusExpected((unsigned int)v43);
v64 = -1073741592;
if( v65 )
v64 = v43;
RtlRaiseStatus(v64);
}
v87 = 1;
if( !v86 )
v86 = (v42 & 4) == 0;
v9 = SharedCacheMap;
}
else
{
if( v37 > 0x1000 && (v29 & 4) != 0 )
{
v62 = CurrentThread;
CurrentThread->CacheManagerActive = 1;
if( !v62->ReadClusterSize )
v62->ReadClusterSize = 1;
}
MmCheckCachedPageStates(v33, 1ui64, Flags, &ReturnResult);
v126 = v48;
if( !ReturnResult && !Wait )
{
v96 = 0;
v27 = Vacb;
v23 = IoIssuerThread;
LODWORD(v28) = Lengtha;
goto LABEL_122;
}
v49 = 0i64;
v122 = 0i64;
v50 = 0i64;
v127 = 0i64;
LODWORD(v110) = 0;
if( v48 < 0 )
RtlRaiseStatus(v48);
v51 = v89;
if( v89 )
{
v66 = v34;
if( v38 )
v66 = 4096i64;
v50 = CcLockSystemCacheBuffer(v104, &v122, v66, 1i64, &v110);
v127 = v50;
if( !v50 )
RtlRaiseStatus(v110);
v49 = v122;
v51 = v89;
}
if( v51 )
v52 = (_MMPTE *)(Offset + v50);
else
v52 = (_MMPTE *)((char *)v104 + Offset);
if( v38 )
v53 = 4096;
else
v53 = v34;
v54 = v53 - Offset;
v55 = 0;
HIDWORD(v110) = 0;
v56 = (*((_DWORD *)v9 + 38) & 0x40000000) != 0;
if( v51 )
{
if( (*((_DWORD *)v9 + 38) & 0x40000000) != 0 )
{
HviCopyMemoryNonTemporal(v52, (UINT64)UserBuffer, (_MEMORY_CACHING_TYPE)v54);
v55 = v59;
HIDWORD(v110) = v59;
}
else
{
HviCopyMemory((INT64)v52, (INT64)UserBuffer, v54);
}
}
else if( (*((_DWORD *)v9 + 38) & 0x40000000) != 0 )
{
LODWORD(RequestHighPriorityMapping) = 2;
v55 = RtlWriteNonVolatileMemory(
(PVOID)0xFFFFFFFFFFFFFFFFi64,
v52,
(UINT8 *)UserBuffer,
v54,
RequestHighPriorityMapping);
HIDWORD(v110) = v55;
}
else
{
memmove(v52, UserBuffer, v54);
}
if( v55 < 0 )
RtlRaiseStatus(v55);
v93 = !v56;
v87 = 1;
if( !v86 )
v86 = !v56;
if( v49 )
{
MmUnlockPages((INT64)v49, v57, v58);
IoFreeMdl(v49);
v122 = 0i64;
}
v60 = v107;
v61 = CurrentThread;
CurrentThread->CacheManagerActive = v107 & 3;
v61->ReadClusterSize = v60 >> 2;
v32 = Offset;
}
UserBuffer = (char *)UserBuffer + 4096 - v32;
v32 = 0;
Offset = 0;
if( !Flags_4 )
break;
v33 = (char *)v104 + 4096;
v104 = (char *)v104 + 4096;
v34 = v106 - 4096;
v106 = v34;
v37 = v34;
ReceivedLength = v34;
v36 += 4096;
LODWORD(v112) = v36;
if( er8 )
{
v35 = 2;
}
else if( v34 <= 0x1000 )
{
v35 = 4;
}
else
{
v35 = 2;
}
v103 = v35;
v29 = OptimizeFlags;
}
v87 = 0;
v46 = Vacb->SharedCacheMap;
if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)&Vacb->Overlay) )
{
v47 = (_KEVENT *)*((_QWORD *)v46 + 23);
if( v47 )
KeSetEvent(v47, 0, 0);
_InterlockedDecrement((volatile signed __int32 *)v46 + 136);
}
v27 = 0i64;
Vacb = 0i64;
v23 = IoIssuerThread;
v28 = (unsigned int)Lengtha;
CcSetDirtyInMask(v9, (_LARGE_INTEGER *)&ReceivedLength_4, (unsigned int)Lengtha, &IoIssuerThread->Tcb);
if( (*((_DWORD *)v9 + 38) & 0x40000000) == 0 && v108 - er8 > 0x1000000
|| (*((_DWORD *)v9 + 38) & 0x40000000) != 0 && v86 )
{
CcFlushCachePriv(
FileObject->SectionObjectPointer,
(_LARGE_INTEGER *)&ReceivedLength_4,
(unsigned int)v28,
0i64,
v85,
&IoStatus);
Status = IoStatus.Status;
if( IoStatus.Status < 0 )
{
FsRtlIsNtstatusExpected((unsigned int)IoStatus.Status);
v68 = -1073741591;
if( v69 )
v68 = Status;
RtlRaiseStatus(v68);
}
}
if( er8 >= 0x1000 )
{
LODWORD(OptimizeFlags) = OptimizeFlags | 1;
}
else if( (OptimizeFlags & 4) == 0 )
{
LODWORD(OptimizeFlags) = 0;
}
ReceivedLength_4 += v28;
v13 = v91;
}
v96 = 1;
LABEL_122:
v70 = v107;
v71 = CurrentThread;
CurrentThread->CacheManagerActive = v107 & 3;
v71->ReadClusterSize = v70 >> 2;
if( v27 )
{
v77 = v27->SharedCacheMap;
if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)&v27->Overlay) )
{
v80 = (_KEVENT *)*((_QWORD *)v77 + 23);
if( v80 )
KeSetEvent(v80, 0, 0);
_InterlockedDecrement((volatile signed __int32 *)v77 + 136);
}
LODWORD(v28) = Lengtha;
}
if( v87 && (_DWORD)v28 )
CcSetDirtyInMask(v9, (_LARGE_INTEGER *)&ReceivedLength_4, (unsigned int)v28, &v23->Tcb);
if( CcRemoteFileDPInlineFlushThreshold != -1
&& (FileObject->Flags & 0x1000000) != 0
&& !v85
&& *((_DWORD *)v9 + 28) >= (unsigned int)CcRemoteFileDPInlineFlushThreshold )
{
v88 = 1;
v90 = 1;
}
if( v94 || v90 )
{
IoStatus.Status = 0;
if( !v85 || (*((_DWORD *)v9 + 38) & 0x40000000) == 0 )
{
v73 = 0i64;
if( !v88 )
v73 = v108;
if( !v88 )
v11 = FileOffset;
CcFlushCachePriv(FileObject->SectionObjectPointer, v11, v73, 0i64, v85, &IoStatus);
LODWORD(v11) = IoStatus.Status;
}
if( v95 )
{
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v128 + 128), &LockHandle);
--*((_DWORD *)v9 + 129);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
LODWORD(v11) = IoStatus.Status;
}
if( (int)v11 < 0 )
{
FsRtlIsNtstatusExpected((unsigned int)v11);
v82 = -1073741591;
if( v81 )
v82 = (int)v11;
RtlRaiseStatus(v82);
}
}
return v96;
}Referenced by:
CcCopyWriteEx