CcWriteBehindInternal
VOID __fastcall CcWriteBehindInternal(INT64 a1){
INT64 v1;
__int64 v3;
INT64 Partition;
INT64 v5;
UINT64 *v6;
UINT64 *v7;
_SHARED_CACHE_MAP *v8;
unsigned int v9;
unsigned int v10;
__int64 v11;
__int64 v12;
unsigned int v13;
_SECTION_OBJECT_POINTERS *v14;
_LARGE_INTEGER *v15;
_IO_STATUS_BLOCK *v16;
unsigned int v17;
INT64 Status;
NTSTATUS valid;
INT64 v20;
bool v21;
bool v22;
_FILE_OBJECT *v23;
int v24;
bool v25;
__int64 v26;
unsigned int v27;
CHAR *v28;
char v29;
int v30;
bool v31;
_FILE_OBJECT *v32;
int v33;
struct _KLOCK_QUEUE_HANDLE LockHandle;
LARGE_INTEGER ValidDataLength;
_IO_STATUS_BLOCK *IoStatus;
__int64 v37;
KLOCK_QUEUE_HANDLE v38;
KLOCK_QUEUE_HANDLE v39;
bool v41;
char v42;
int v43;
v1 = *(_QWORD *)(a1 + 16);
v3 = *(unsigned __int8 *)(a1 + 56);
IoStatus = *(_IO_STATUS_BLOCK **)(a1 + 24);
v42 = v3;
ValidDataLength.QuadPart = 0i64;
v37 = 0i64;
memset(&v38, 0, sizeof(v38));
memset(&LockHandle, 0, sizeof(LockHandle));
memset(&v39, 0, sizeof(v39));
Partition = CcGetPartition((_QWORD *)v1);
v5 = Partition;
if( Partition != *(_QWORD *)(a1 + 128) )
KeBugCheckEx(0x34u, 0x1A98ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
v6 = (UINT64 *)(Partition + 192);
v7 = (UINT64 *)(Partition + 128);
while( 1 )
{
v41 = 0;
KeAcquireInStackQueuedSpinLock(v7, &LockHandle);
++*(_DWORD *)(v1 + 4);
++*(_DWORD *)(v1 + 536);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
LOBYTE(v8) = 1;
CcApplyLowIoPriorityToThread(v5, v8);
KeAcquireInStackQueuedSpinLock(v6, &v39);
v9 = *(_DWORD *)(v5 + 960);
v10 = *(_DWORD *)(v5 + 200);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&v39);
__writecr8(v39.OldIrql);
if( v9 >= v10 )
CcApplyLowIoPriorityToThread(v5, 0i64);
LOBYTE(v11) = 1;
if( !(**(unsigned __int8(__fastcall ***)(_QWORD, __int64))(v1 + 208))(*(_QWORD *)(v1 + 216), v11) )
break;
ExAcquireFastMutex((FAST_MUTEX *)(v1 + 280));
KeAcquireInStackQueuedSpinLock(v7, &LockHandle);
v43 = *(_DWORD *)(v1 + 152) & 0x10000;
v12 = *(_QWORD *)(v1 + 160);
if( v12 )
{
v13 = *(_DWORD *)(v12 + 8);
*(_DWORD *)(v12 + 4) = v13;
v27 = *(_DWORD *)(v5 + 496);
if( v13 > v27 )
{
*(_DWORD *)(v12 + 4) = v27;
v13 = v27;
}
}
else
{
v13 = *(_DWORD *)(v1 + 192);
}
v14 = *(_SECTION_OBJECT_POINTERS **)((*(_QWORD *)(v1 + 96) & 0xFFFFFFFFFFFFFFF0ui64) + 0x28);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
KeReleaseGuardedMutex((_FAST_MUTEX *)(v1 + 280));
_InterlockedExchangeAdd((volatile signed __int32 *)(*(_QWORD *)(v1 + 504) + 196i64), v13);
if( (*(_DWORD *)(v1 + 152) & 0x1000000) != 0
&& (_InterlockedExchangeAdd((volatile signed __int32 *)(*(_QWORD *)(v1 + 504) + 200i64), v13),
(*(_DWORD *)(v1 + 152) & 0x1000000) != 0) )
{
v15 = (_LARGE_INTEGER *)&v37;
v37 = *(_QWORD *)(*(_QWORD *)(v1 + 240) + 112i64);
}
else
{
v15 = 0i64;
}
v16 = IoStatus;
CcFlushCachePriv(v14, (_LARGE_INTEGER *)CcNoDelay, 1ui64, v15, 0, IoStatus);
CcApplyLowIoPriorityToThread(v5, 0i64);
v17 = -v13;
_InterlockedExchangeAdd((volatile signed __int32 *)(*(_QWORD *)(v1 + 504) + 196i64), v17);
if( (*(_DWORD *)(v1 + 152) & 0x1000000) != 0 )
_InterlockedExchangeAdd((volatile signed __int32 *)(*(_QWORD *)(v1 + 504) + 200i64), v17);
(*(void(__fastcall **)(_QWORD))(*(_QWORD *)(v1 + 208) + 8i64))(*(_QWORD *)(v1 + 216));
Status = (unsigned int)v16->Status;
if( (_DWORD)Status != -2147483626 && CcIsFatalWriteError(v1, Status) )
{
v32 = (_FILE_OBJECT *)CcReferenceSharedCacheMapFileObject(v1);
CcMmLogLostDelayedWriteError(v32, (unsigned int)v16->Status);
CcDereferenceSharedCacheMapFileObject(v1, (UINT64)v32);
}
valid = 0;
ExAcquireFastMutex((FAST_MUTEX *)(v1 + 280));
ValidDataLength = *(LARGE_INTEGER *)(v1 + 40);
v20 = CcGetPartition((_QWORD *)v1);
v21 = *(_DWORD *)(v1 + 4) > 1u && *(_QWORD *)(v20 + 784) != v20 + 784;
v22 = 0;
if( (*(_DWORD *)(v1 + 152) & 0x400) != 0 )
{
v26 = *(_QWORD *)(v1 + 40);
if( *(_QWORD *)(v1 + 48) >= v26 && v26 != 0x7FFFFFFFFFFFFFFFi64 && *(_QWORD *)(v1 + 8) )
v22 = 1;
}
if( !*(_DWORD *)(v1 + 516) && v22 && !v21 )
{
ValidDataLength = CcGetFlushedValidData(v14, 1u);
if( ValidDataLength.QuadPart >= *(_QWORD *)(v1 + 40) )
{
if( (*(_DWORD *)(v1 + 152) & 0x40000000) != 0
|| (KeReleaseGuardedMutex((_FAST_MUTEX *)(v1 + 280)),
v28 = CcReferenceSharedCacheMapFileObject(v1),
valid = CcSetValidData((FILE_OBJECT *)v28, &ValidDataLength),
CcDereferenceSharedCacheMapFileObject(v1, (UINT64)v28),
ExAcquireFastMutex((FAST_MUTEX *)(v1 + 280)),
valid >= 0) )
{
*(LARGE_INTEGER *)(v1 + 40) = ValidDataLength;
}
else if( valid != -1073741670 && valid != -2147483626 && valid != -1073741740 )
{
ValidDataLength = *(LARGE_INTEGER *)(v1 + 48);
}
}
}
KeReleaseGuardedMutex((_FAST_MUTEX *)(v1 + 280));
v7 = (UINT64 *)(v5 + 128);
KeAcquireInStackQueuedSpinLock((UINT64 *)(v5 + 128), &LockHandle);
--*(_DWORD *)(v1 + 4);
--*(_DWORD *)(v1 + 536);
if( !*(_DWORD *)(v1 + 4) )
{
if( valid == -1073741740 || valid == -2147483626 || valid == -1073741670 )
{
if( (*(_DWORD *)(v1 + 152) & 0x10000) != 0 )
CcCancelMmWaitForUninitializeCacheMap((_SHARED_CACHE_MAP *)v1);
if( !*(_DWORD *)(v1 + 112) )
{
CcInsertIntoDirtySharedCacheMapList((_SHARED_CACHE_MAP *)v1);
v29 = 1;
goto LABEL_51;
}
}
else
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v23 = (_FILE_OBJECT *)CcReferenceSharedCacheMapFileObject(v1);
FsRtlAcquireFileExclusive(v23);
KeAcquireInStackQueuedSpinLock(&CcMasterLock, &v38);
KeAcquireInStackQueuedSpinLock((UINT64 *)(v5 + 128), &LockHandle);
v24 = *(_DWORD *)(v1 + 4);
if( !v24
&& (!*(_DWORD *)(v1 + 112)
&& (*(_QWORD *)(v1 + 40) == 0x7FFFFFFFFFFFFFFFi64
|| (*(_DWORD *)(v1 + 152) & 0x400) == 0
|| ValidDataLength.QuadPart >= *(_QWORD *)(v1 + 48))
|| !*(_QWORD *)(v1 + 8) && (*(_DWORD *)(v1 + 152) & 4) == 0) )
{
CcDeleteSharedCacheMap((CHAR *)v1, &v38, &LockHandle, 1i64, v23);
IoStatus->Information = 0i64;
LABEL_28:
v25 = v42 == 0;
goto LABEL_29;
}
if( *(_DWORD *)(v1 + 112) )
{
if( (*(_DWORD *)(v1 + 152) & 0x10000) != 0 )
CcCancelMmWaitForUninitializeCacheMap((_SHARED_CACHE_MAP *)v1);
}
else
{
v31 = v24 == 0;
if( !v24 )
{
CcInsertIntoDirtySharedCacheMapList((_SHARED_CACHE_MAP *)v1);
v31 = v33 == 0;
}
v41 = v31;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&v38);
__writecr8(v38.OldIrql);
FsRtlReleaseFile(v23);
CcDereferenceSharedCacheMapFileObject(v1, (UINT64)v23);
KeAcquireInStackQueuedSpinLock((UINT64 *)(v5 + 128), &LockHandle);
}
}
v29 = v41;
LABEL_51:
v30 = *(_DWORD *)(v1 + 152);
if( (v30 & 0x10000) == 0 || v43 )
{
if( IoStatus->Information != 35422 )
*(_DWORD *)(v1 + 152) = v30 & 0xFFFFFFDF;
if( v29 )
{
*(_BYTE *)(v5 + 633) = 1;
CcScheduleLazyWriteScan(v5, (*(_DWORD *)(v1 + 152) & 0x10000) != 0);
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
goto LABEL_28;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v6 = (UINT64 *)(v5 + 192);
}
CcApplyLowIoPriorityToThread(v5, 0i64);
KeAcquireInStackQueuedSpinLock(v7, &LockHandle);
*(_DWORD *)(v1 + 152) &= ~0x20u;
if( (*(_DWORD *)(v1 + 152) & 0x10000) != 0 )
CcCancelMmWaitForUninitializeCacheMap((_SHARED_CACHE_MAP *)v1);
CcDecrementOpenCount(v1);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v25 = v42 == 0;
IoStatus->Status = -1073741740;
LABEL_29:
if( !v25 )
KeSetEvent((PRKEVENT)(a1 + 32), 0);
}Referenced by:
CcWriteBehind