CcMapAndCopyInToCache
INT64 __fastcall CcMapAndCopyInToCache(
_SHARED_CACHE_MAP *SharedCacheMap,
VOID *UserBuffer,
_LARGE_INTEGER *FileOffset,
UINT64 Length,
UINT64 OptimizeFlags,
_FILE_OBJECT *FileObject,
_LARGE_INTEGER *ValidDataLength,
INT64 Wait,
_ETHREAD *IoIssuerThread){
_SHARED_CACHE_MAP *v9;
char v10;
_LARGE_INTEGER *v11;
bool v12;
int v13;
_QWORD *WriteBehindWorkQueueEntry;
INT64 result;
char v16;
_CC_PARTITION *Partition;
KDPC *v18;
__int64 v19;
int v20;
_CC_PARTITION *v21;
_ETHREAD *v22;
_QWORD *v23;
__int64 v24;
int v25;
_VACB *v26;
__int64 v27;
int v28;
char *v29;
unsigned int v30;
ULONG v31;
char *v32;
unsigned int v33;
int v34;
ULONG v35;
unsigned int v36;
_BOOL8 v37;
unsigned int v38;
int v39;
ULONG v40;
int v41;
int v42;
unsigned int v43;
NTSTATUS v44;
__int64 v45;
struct _KEVENT *v46;
NTSTATUS v47;
_MDL *v48;
void(__fastcall *v49)(void *, void *, _IO_WORKITEM *);
bool v50;
char *v51;
int v52;
ULONG v53;
NTSTATUS v54;
bool v55;
unsigned int v56;
_ETHREAD *v57;
_ETHREAD *v58;
char v59;
NTSTATUS v60;
char v61;
UINT64 v62;
NTSTATUS v63;
NTSTATUS v64;
char v65;
unsigned int v66;
_ETHREAD *v67;
UINT64 v68;
WORK_QUEUE_TYPE v69;
void *v70;
unsigned __int64 v71;
volatile signed __int64 *v72;
unsigned __int64 v73;
__int64 v74;
__int64 v75;
_QWORD *v76;
struct _KEVENT *v77;
char v78;
NTSTATUS v79;
ULONG_PTR BugCheckParameter4;
UINT64 PerformingReadAhead;
UINT8 v82;
bool v83;
char v84;
char v85;
bool v86;
char v87;
int v88;
UINT8 ReturnResult;
bool v90;
bool v91;
char v92;
unsigned __int8 v93;
char v94;
UINT64 Lengtha;
ULONG Offset;
int Offset_4;
unsigned int ReceivedLength;
UINT64 ReceivedLength_4;
int v100;
VOID *v101;
_VACB *Vacb;
unsigned int v103;
unsigned int v104;
unsigned int v105;
int v106;
INT64 Status;
NTSTATUS v108[4];
LONGLONG v109;
_ETHREAD *CurrentThread;
struct _KLOCK_QUEUE_HANDLE LockHandle;
unsigned int Flags;
BOOL Flags_4;
int v114;
int v115;
NTSTATUS v116;
int v117;
unsigned int v118;
MDL *v119;
VOID *IoAttributionContext;
struct _IO_WORKITEM v121;
unsigned int er8;
er8 = Length;
v105 = Length;
v9 = SharedCacheMap;
v10 = Wait;
v11 = 0i64;
ReceivedLength = 0;
LODWORD(Lengtha) = 0;
v109 = 0i64;
*(_OWORD *)v108 = 0i64;
v12 = (FileObject->Flags & 0x10) != 0;
v82 = v12;
v115 = Length;
Offset = FileOffset->LowPart & 0xFFF;
Vacb = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v13 = 0;
v88 = 0;
v92 = 0;
v85 = 0;
WriteBehindWorkQueueEntry = 0i64;
IoAttributionContext = 0i64;
ReturnResult = 1;
v84 = 0;
v87 = 0;
memset(&LockHandle, 0, sizeof(LockHandle));
memset(&v121, 0, 24);
v86 = (SharedCacheMap->Flags & 0x1000) != 0;
ReceivedLength_4 = FileOffset->QuadPart;
result = (unsigned int)*((unsigned __int8 *)CurrentThread + 1308) + 4 * *((_DWORD *)CurrentThread + 322);
v104 = result;
v114 = result;
v16 = v12;
v91 = v12;
v94 = v12;
if( !v12 )
{
v91 = 0;
memset(&v121.WorkOnBehalfThread, 0, 24);
Partition = SharedCacheMap->Partition;
if( SharedCacheMap->Section
&& Partition != *(_CC_PARTITION **)(MmGetControlAreaPartition(*(_QWORD *)((SharedCacheMap->FileObjectFastRef.Value & 0xFFFFFFFFFFFFFFF0ui64)
+ 0x28))
+ 8) )
{
KeBugCheckEx(0x34u, 0x1313ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
}
if( (FileObject->Flags & 0x1000000) == 0
|| (LODWORD(result) = CcCanIWriteStreamEx((UINT8 *)Partition, (INT64)FileObject, er8, 0i64, 0, 0i64), (_BYTE)result) )
{
v18 = (KDPC *)KeGetCurrentThread();
PsGetBaseIoPriorityThread(v18, v18, FileOffset, (PVOID)Length);
if( (int)result < 2 && (struct _KTHREAD *)v19 == KeGetCurrentThread() && *(_DWORD *)(v19 + 1360)
|| (int)result > 0
|| (FileObject->Flags & 0x8000) != 0 )
{
v13 = 0;
LABEL_8:
v94 = v16;
v12 = v82;
v10 = Wait;
goto LABEL_9;
}
v13 = 0;
}
v16 = 1;
v91 = 1;
if( (v9->Flags & 0x400) == 0 )
{
KeAcquireInStackQueuedSpinLock((UINT64 *)Partition + 16, (KLOCK_QUEUE_HANDLE *)&v121.WorkOnBehalfThread);
v9->Flags |= 0x400u;
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&v121.WorkOnBehalfThread);
result = (unsigned int)KiIrqlFlags;
__writecr8(LOBYTE(v121.ActivityId.Data2));
}
goto LABEL_8;
}
LABEL_9:
if( !v16 || v10 )
{
v20 = 6;
if( v10 )
v20 = 4;
Flags = v20;
v21 = v9->Partition;
v121.IoObject = v21;
if( v9->Section
&& v21 != *(_CC_PARTITION **)(MmGetControlAreaPartition(*(_QWORD *)((v9->FileObjectFastRef.Value & 0xFFFFFFFFFFFFFFF0ui64)
+ 0x28))
+ 8) )
{
KeBugCheckEx(0x34u, 0x1313ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
}
v121.Context = v21;
if( v12 )
{
KeAcquireInStackQueuedSpinLock((UINT64 *)v21 + 16, &LockHandle);
if( (v9->Flags & 0x20) != 0 )
{
v121.WorkItem.List.Blink = (_LIST_ENTRY *)((char *)v21 + 192);
v121.WorkItem.List.Flink = 0i64;
KxAcquireQueuedSpinLock(&v121, (PIO_WORKITEM_ROUTINE)((char *)v21 + 192), v69, v70);
WriteBehindWorkQueueEntry = v9->WriteBehindWorkQueueEntry;
if( !WriteBehindWorkQueueEntry )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&v121);
KeReleaseInStackQueuedSpinLock(&LockHandle);
KeDelayExecutionThread(0, 0, &Cc5Milliseconds);
RtlRaiseStatus(-1073741608);
}
v75 = *WriteBehindWorkQueueEntry;
v76 = (_QWORD *)WriteBehindWorkQueueEntry[1];
if( *(_QWORD **)(*WriteBehindWorkQueueEntry + 8i64) != WriteBehindWorkQueueEntry
|| (_QWORD *)*v76 != WriteBehindWorkQueueEntry )
{
__fastfail(3u);
}
*v76 = v75;
*(_QWORD *)(v75 + 8) = v76;
WriteBehindWorkQueueEntry[1] = 0i64;
*WriteBehindWorkQueueEntry = 0i64;
v9->WriteBehindWorkQueueEntry = 0i64;
v9->Flags &= ~0x20u;
v85 = 1;
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&v121);
}
++v9->WritesInProgress;
v92 = 1;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
if( WriteBehindWorkQueueEntry )
CcFreeWorkQueueEntry((INT64)WriteBehindWorkQueueEntry);
v22 = IoIssuerThread;
if( !IoIssuerThread )
{
v22 = (_ETHREAD *)KeGetCurrentThread();
IoIssuerThread = v22;
v13 = 0;
}
v23 = (_QWORD *)*((_QWORD *)v22 + 184);
v106 = 0;
if( !v23 )
goto LABEL_20;
if( v22 != (_ETHREAD *)KeGetCurrentThread() )
{
v73 = ExAcquireSpinLockShared((PEX_SPIN_LOCK)PspThreadWorkOnBehalfLock);
v23 = (_QWORD *)*((_QWORD *)v22 + 184);
if( v23 )
{
ObfReferenceObjectWithTag(*((PVOID *)v22 + 184), 0x746C6644u);
v106 = 1;
}
ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)PspThreadWorkOnBehalfLock);
__writecr8(v73);
}
v13 = 0;
if( v23 )
v24 = v23[68];
else
LABEL_20:
v24 = *((_QWORD *)v22 + 68);
if( *(_QWORD *)(v24 + 2392) )
{
v71 = ExAcquireSpinLockShared(&IopDiskIoAttributionLock);
v72 = *(volatile signed __int64 **)(v24 + 2392);
if( v72 )
{
if( _InterlockedIncrement64(v72 + 4) <= 1 )
__fastfail(0xEu);
IoAttributionContext = (VOID *)v72;
v13 = 0;
}
ExReleaseSpinLockSharedFromDpcLevel(&IopDiskIoAttributionLock);
__writecr8(v71);
if( v72 )
v25 = 0;
else
v25 = -1073741275;
}
else
{
v25 = -1073741275;
}
if( v106 )
ObDereferenceObjectDeferDelete(v23);
Offset_4 = v25;
if( v25 >= 0 )
{
MmUpdateSectionIoAttribution(FileObject->SectionObjectPointer, IoAttributionContext);
IoDiskIoAttributionDereference(IoAttributionContext);
}
v26 = Vacb;
LODWORD(v27) = Lengtha;
while( er8 )
{
if( v86 )
{
v28 = 0;
LODWORD(OptimizeFlags) = 0;
}
else
{
v28 = OptimizeFlags;
}
LODWORD(Lengtha) = 0;
LODWORD(PerformingReadAhead) = 0;
LODWORD(BugCheckParameter4) = 0;
LODWORD(v29) = CcGetVirtualAddress(
v9,
(_LARGE_INTEGER)ReceivedLength_4,
&Vacb,
(UINT64 *)&ReceivedLength,
BugCheckParameter4,
PerformingReadAhead);
v101 = v29;
v30 = ReceivedLength;
if( ReceivedLength > er8 )
{
v30 = er8;
ReceivedLength = er8;
}
LODWORD(Lengtha) = v30;
er8 -= v30;
v31 = Offset;
v32 = &v29[-Offset];
v101 = v32;
v33 = Offset + v30;
v103 = v33;
ReceivedLength = v33;
v34 = 1;
v100 = 1;
HIDWORD(v109) = HIDWORD(ReceivedLength_4);
v35 = ReceivedLength_4 - Offset;
LODWORD(v109) = ReceivedLength_4 - Offset;
v84 = 0;
v83 = 0;
v36 = v33;
while( 1 )
{
ReturnResult = 1;
v37 = v36 > 0x1000;
Flags_4 = v36 > 0x1000;
LODWORD(v121.WorkItem.Parameter) = Flags_4;
Offset_4 = 0;
if( (v34 & v28) != 0 )
{
if( v109 >= ValidDataLength->QuadPart )
{
v13 |= 1u;
v88 = v13;
}
v38 = v9->Flags;
if( (v38 & 0x40) != 0 )
{
v13 |= 2u;
v88 = v13;
}
if( (v38 & 0x40000000) != 0 )
{
v59 = 0;
if( v36 <= 0x1000 )
v59 = v33;
if( (((unsigned __int8)v31 | (unsigned __int8)(v59 - v31)) & 0x3F) != 0 )
{
v13 &= 0xFFFFFFF3;
v88 = v13;
v83 = 1;
}
else
{
v13 |= 4u;
v88 = v13;
if( v82 )
{
v13 |= 8u;
v88 = v13;
}
}
}
v39 = 4096;
if( v36 <= 0x1000 )
v39 = v33;
v40 = v39 - v31;
v41 = v13;
v117 = v13;
v42 = 0;
v116 = 0;
v43 = 1;
v118 = 1;
while( v43 <= 2 )
{
LODWORD(BugCheckParameter4) = v41;
v44 = MmCopyToCachedPage(v32, UserBuffer, v31, v40, BugCheckParameter4);
v42 = v44;
v116 = v44;
if( (v41 & 8) == 0 || v44 != -1073741670 )
{
v31 = Offset;
break;
}
v41 &= 0xFFFFFFF3;
v117 = v41;
v118 = ++v43;
v31 = Offset;
v32 = (char *)v101;
}
v90 = (v41 & 4) == 0;
Offset_4 = v42;
if( v42 < 0 )
{
FsRtlIsNtstatusExpected((unsigned int)v42);
v60 = -1073741592;
if( v61 )
v60 = v42;
RtlRaiseStatus(v60);
}
v84 = 1;
if( !v83 )
v83 = (v41 & 4) == 0;
v9 = SharedCacheMap;
}
else
{
if( v36 > 0x1000 && (v28 & 4) != 0 )
{
v58 = CurrentThread;
*((_BYTE *)CurrentThread + 1308) = 1;
if( !*((_DWORD *)v58 + 322) )
*((_DWORD *)v58 + 322) = 1;
}
MmCheckCachedPageStates(v32, 1ui64, Flags, &ReturnResult);
HIDWORD(v121.WorkItem.Parameter) = v47;
if( !ReturnResult && !(_BYTE)Wait )
{
v93 = 0;
v26 = Vacb;
v22 = IoIssuerThread;
LODWORD(v27) = Lengtha;
goto LABEL_122;
}
v48 = 0i64;
v119 = 0i64;
v49 = 0i64;
v121.Routine = 0i64;
LODWORD(Status) = 0;
if( v47 < 0 )
RtlRaiseStatus(v47);
v50 = v86;
if( v86 )
{
v62 = v33;
if( v37 )
v62 = 4096i64;
v49 = (void(__fastcall *)(void *, void *, _IO_WORKITEM *))CcLockSystemCacheBuffer(
v101,
&v119,
v62,
1i64,
&Status);
v121.Routine = v49;
if( !v49 )
RtlRaiseStatus(Status);
v48 = v119;
v50 = v86;
}
if( v50 )
v51 = (char *)v49 + Offset;
else
v51 = (char *)v101 + Offset;
if( v37 )
v52 = 4096;
else
v52 = v33;
v53 = v52 - Offset;
v54 = 0;
HIDWORD(Status) = 0;
v55 = (v9->Flags & 0x40000000) != 0;
if( v50 )
{
if( (v9->Flags & 0x40000000) != 0 )
{
v54 = HviCopyMemoryNonTemporal((INT64)v51, (INT64)UserBuffer, v53);
HIDWORD(Status) = v54;
}
else
{
HviCopyMemory((INT64)v51, (INT64)UserBuffer, v53);
}
}
else if( (v9->Flags & 0x40000000) != 0 )
{
LODWORD(BugCheckParameter4) = 2;
v54 = RtlWriteNonVolatileMemory(
(PVOID)0xFFFFFFFFFFFFFFFFi64,
v51,
(UINT8 *)UserBuffer,
v53,
BugCheckParameter4);
HIDWORD(Status) = v54;
}
else
{
memmove((UINT8 *)v51, (UINT8 *)UserBuffer, v53);
}
if( v54 < 0 )
RtlRaiseStatus(v54);
v90 = !v55;
v84 = 1;
if( !v83 )
v83 = !v55;
if( v48 )
{
MmUnlockPages(v48);
IoFreeMdl(v48);
v119 = 0i64;
}
v56 = v104;
v57 = CurrentThread;
*((_BYTE *)CurrentThread + 1308) = v104 & 3;
*((_DWORD *)v57 + 322) = v56 >> 2;
v31 = Offset;
}
UserBuffer = (char *)UserBuffer + 4096 - v31;
v31 = 0;
Offset = 0;
if( !Flags_4 )
break;
v32 = (char *)v101 + 4096;
v101 = (char *)v101 + 4096;
v33 = v103 - 4096;
v103 = v33;
v36 = v33;
ReceivedLength = v33;
v35 += 4096;
LODWORD(v109) = v35;
if( er8 )
{
v34 = 2;
}
else if( v33 <= 0x1000 )
{
v34 = 4;
}
else
{
v34 = 2;
}
v100 = v34;
v28 = OptimizeFlags;
}
v84 = 0;
v45 = *((_QWORD *)Vacb + 1);
if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)Vacb + 4) )
{
v46 = *(struct _KEVENT **)(v45 + 184);
if( v46 )
KeSetEvent(v46, 0);
_InterlockedDecrement((volatile signed __int32 *)(v45 + 544));
}
v26 = 0i64;
Vacb = 0i64;
v22 = IoIssuerThread;
v27 = (unsigned int)Lengtha;
CcSetDirtyInMask(v9, (_LARGE_INTEGER *)&ReceivedLength_4, (unsigned int)Lengtha, IoIssuerThread);
if( (v9->Flags & 0x40000000) == 0 && v105 - er8 > 0x1000000 || (v9->Flags & 0x40000000) != 0 && v83 )
{
CcFlushCachePriv(
FileObject->SectionObjectPointer,
(_LARGE_INTEGER *)&ReceivedLength_4,
(unsigned int)v27,
0i64,
v82,
(_IO_STATUS_BLOCK *)v108);
v63 = v108[0];
if( v108[0] < 0 )
{
FsRtlIsNtstatusExpected((unsigned int)v108[0]);
v64 = -1073741591;
if( v65 )
v64 = v63;
RtlRaiseStatus(v64);
}
}
if( er8 >= 0x1000 )
{
LODWORD(OptimizeFlags) = OptimizeFlags | 1;
}
else if( (OptimizeFlags & 4) == 0 )
{
LODWORD(OptimizeFlags) = 0;
}
ReceivedLength_4 += v27;
v13 = v88;
}
v93 = 1;
LABEL_122:
v66 = v104;
v67 = CurrentThread;
*((_BYTE *)CurrentThread + 1308) = v104 & 3;
*((_DWORD *)v67 + 322) = v66 >> 2;
if( v26 )
{
v74 = *((_QWORD *)v26 + 1);
if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)v26 + 4) )
{
v77 = *(struct _KEVENT **)(v74 + 184);
if( v77 )
KeSetEvent(v77, 0);
_InterlockedDecrement((volatile signed __int32 *)(v74 + 544));
}
LODWORD(v27) = Lengtha;
}
if( v84 && (_DWORD)v27 )
CcSetDirtyInMask(v9, (_LARGE_INTEGER *)&ReceivedLength_4, (unsigned int)v27, v22);
if( CcRemoteFileDPInlineFlushThreshold != -1
&& (FileObject->Flags & 0x1000000) != 0
&& !v82
&& v9->DirtyPages >= CcRemoteFileDPInlineFlushThreshold )
{
v85 = 1;
v87 = 1;
}
if( v91 || v87 )
{
v108[0] = 0;
if( !v82 || (v9->Flags & 0x40000000) == 0 )
{
v68 = 0i64;
if( !v85 )
v68 = v105;
if( !v85 )
v11 = FileOffset;
CcFlushCachePriv(FileObject->SectionObjectPointer, v11, v68, 0i64, v82, (_IO_STATUS_BLOCK *)v108);
LODWORD(v11) = v108[0];
}
if( v92 )
{
KeAcquireInStackQueuedSpinLock((UINT64 *)v121.IoObject + 16, &LockHandle);
--v9->WritesInProgress;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
LODWORD(v11) = v108[0];
}
if( (int)v11 < 0 )
{
FsRtlIsNtstatusExpected((unsigned int)v11);
v79 = -1073741591;
if( v78 )
v79 = (int)v11;
RtlRaiseStatus(v79);
}
}
return v93;
}
else
{
LOBYTE(result) = 0;
}
return result;
}Referenced by:
CcCopyWriteEx