CcSetDirtyInMask
VOID __fastcall CcSetDirtyInMask(
_SHARED_CACHE_MAP *SharedCacheMap,
_LARGE_INTEGER *FileOffset,
UINT64 Length,
_ETHREAD *IoIssuerThread){
LONGLONG QuadPart;
_SHARED_CACHE_MAP *v5;
_LARGE_INTEGER v6;
__int64 v7;
signed __int64 v8;
_CC_PARTITION *Partition;
int i;
struct _SLIST_ENTRY *v11;
_FAST_MUTEX *p_BcbLock;
_ETHREAD *CurrentThread;
__int64 v14;
char v15;
__int64 v16;
int v17;
bool v18;
unsigned __int8 CurrentIrql;
INT64 Mbcb;
__int64 BitmapRangeToDirty;
INT64 v22;
__int64 v23;
UINT8 v24;
unsigned __int8 v25;
struct _KPRCB *CurrentPrcb;
KSPIN_LOCK_QUEUE *v27;
_DWORD *v28;
int v29;
unsigned int v30;
__int64 v31;
_DWORD *v32;
int v33;
_KSPIN_LOCK_QUEUE *volatile Next;
_LARGE_INTEGER v35;
_FAST_MUTEX *v36;
unsigned __int64 OldIrql_low;
unsigned __int32 v38;
_ETHREAD *v39;
__int64 v40;
CHAR *InitializeMbcb;
PSLIST_ENTRY v42;
struct _SLIST_ENTRY *v43;
INT64 **v44;
INT64 *v45;
INT64 v46;
INT64 *v47;
INT64 **v48;
__int64 v49;
unsigned int Flags;
unsigned int v51;
unsigned int v52;
UINT8 FastScan[8];
PSLIST_ENTRY ListEntry;
__int64 v55;
struct _KLOCK_QUEUE_HANDLE LockHandle;
int v59;
QuadPart = FileOffset->QuadPart;
v5 = SharedCacheMap;
ListEntry = 0i64;
v59 = 0;
v55 = (unsigned int)Length;
v6.QuadPart = QuadPart + (unsigned int)Length;
v51 = 0;
memset(&LockHandle, 0, sizeof(LockHandle));
if( ((QuadPart ^ (v6.QuadPart - 1)) & 0xFFFFFFFFFE000000ui64) != 0 )
KeBugCheckEx(0x34u, 0xC52ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
if( (v5->Flags & 0x40000000) != 0 && v6.QuadPart <= v5->ValidDataGoal.QuadPart )
return;
v7 = QuadPart >> 12;
v8 = (v6.QuadPart - 1) >> 12;
if( v5->SectionSize.QuadPart / 4096 <= v8 )
KeBugCheckEx(0x34u, 0xC72ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
Partition = v5->Partition;
*(_QWORD *)FastScan = Partition;
if( v5->Section
&& Partition != *(_CC_PARTITION **)(MmGetControlAreaPartition(*(_QWORD *)((v5->FileObjectFastRef.Value & 0xFFFFFFFFFFFFFFF0ui64)
+ 0x28))
+ 8) )
{
KeBugCheckEx(0x34u, 0x1313ui64, 0xFFFFFFFFC0000420ui64, 0i64, 0i64);
}
if( (v5->Flags & 0x40000000) != 0 )
{
ExAcquireFastMutex(&v5->BcbLock);
LABEL_54:
v35.QuadPart = FileOffset->QuadPart + v55;
if( v35.QuadPart > v5->ValidDataGoal.QuadPart )
{
v18 = (v5->Flags & 0x40000000) == 0;
v5->ValidDataGoal = v35;
if( !v18 )
{
KeAcquireInStackQueuedSpinLock((UINT64 *)Partition + 16, &LockHandle);
Flags = v5->Flags;
if( (Flags & 0x400) == 0 )
v5->Flags = Flags | 0x400;
CcInsertIntoDirtySharedCacheMapList(v5);
CcScheduleLazyWriteScan((UINT8)Partition, 0);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
}
goto LABEL_56;
}
while( 2 )
{
for( i = v59; ; i = 0 )
{
if( v5->SectionSize.QuadPart > 0x300000ui64 )
{
++dword_140CDB3D4;
v11 = RtlpInterlockedPopEntrySList((PSLIST_HEADER)&CcBitmapLookasideList);
if( !v11 )
{
++dword_140CDB3D8;
v11 = (struct _SLIST_ENTRY *)((__int64(__fastcall *)(_QWORD, _QWORD, _QWORD))qword_140CDB3F0)(
(unsigned int)dword_140CDB3E4,
(unsigned int)dword_140CDB3EC,
(unsigned int)dword_140CDB3E8);
if( !v11 )
{
++CcDbgNumberOfFailedBitmapAllocations;
goto LABEL_103;
}
}
ListEntry = v11;
}
v52 = 0;
p_BcbLock = &v5->BcbLock;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v59 = 1;
--*((_WORD *)CurrentThread + 243);
if( ++*((_BYTE *)CurrentThread + 794) != 1 )
KeBugCheckEx(0x192u, (ULONG_PTR)CurrentThread, (ULONG_PTR)&v5->BcbLock, KeGetCurrentIrql(), 0i64);
LOBYTE(v14) = *((_BYTE *)CurrentThread + 792);
if( !(_BYTE)v14 )
{
if( !*((_BYTE *)CurrentThread + 870) )
{
v16 = 0i64;
LABEL_94:
_interlockedbittestandset((volatile signed __int32 *)CurrentThread + 30, 0x10u);
goto LABEL_17;
}
v49 = *((unsigned __int8 *)CurrentThread + 870);
*((_BYTE *)CurrentThread + 870) = 0;
LOBYTE(v14) = v49 | *((_BYTE *)CurrentThread + 792);
}
v15 = v14;
_BitScanForward((unsigned int *)&v14, (unsigned __int8)v14);
*((_BYTE *)CurrentThread + 792) = v15 & ~(1 << v14);
v16 = *((_QWORD *)CurrentThread + 100) + 96 * v14;
if( !v16 )
goto LABEL_94;
v17 = (unsigned int)MiGetSystemRegionType((UINT64)&v5->BcbLock) == 1 ? MmGetSessionIdEx(*((_QWORD *)CurrentThread
+ 23)) : -1;
*(_DWORD *)(v16 + 40) = v17;
*(_QWORD *)(v16 + 32) = (unsigned __int64)p_BcbLock & 0x7FFFFFFFFFFFFFFCi64;
LABEL_17:
--*((_BYTE *)CurrentThread + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)CurrentThread, (__int64)&v5->BcbLock, &v52);
v18 = (*((_WORD *)CurrentThread + 243))++ == 0xFFFF;
if( v18 && *((_ETHREAD **)CurrentThread + 19) != (_ETHREAD *)((char *)CurrentThread + 152) )
KiCheckForKernelApcDelivery();
CurrentIrql = KeGetCurrentIrql();
__writecr8(1ui64);
if( !_interlockedbittestandreset(&p_BcbLock->Count, 0) )
ExpAcquireFastMutexContended(&v5->BcbLock, (PVOID)v16);
if( v16 )
*(_BYTE *)(v16 + 26) |= 1u;
v5->BcbLock.Owner = KeGetCurrentThread();
v5->BcbLock.OldIrql = CurrentIrql;
Mbcb = (INT64)v5->Mbcb;
if( !Mbcb )
{
InitializeMbcb = CcAllocateInitializeMbcb();
Mbcb = (INT64)InitializeMbcb;
if( !InitializeMbcb )
goto LABEL_102;
v5->Mbcb = (_MBCB *)InitializeMbcb;
}
if( v7 == v8 && v7 == *(_QWORD *)(Mbcb + 40) )
goto LABEL_53;
if( (unsigned __int64)v8 < 0x300 || *(_WORD *)Mbcb == 761 )
break;
v42 = ListEntry;
memset((INT64)ListEntry, 0i64);
if( *(_DWORD *)(Mbcb + 80) )
{
v43 = *(struct _SLIST_ENTRY **)(Mbcb + 88);
*v42 = *v43;
v42[1] = v43[1];
v42[2] = v43[2];
v42[3] = v43[3];
v42[4] = v43[4];
v42[5] = v43[5];
memset(*(_QWORD *)(Mbcb + 88), 0i64);
}
*(_QWORD *)(Mbcb + 88) = v42;
v44 = *(INT64 ***)(Mbcb + 24);
v45 = (INT64 *)(Mbcb + 96);
ListEntry = 0i64;
v46 = Mbcb + 16;
if( *v44 != (INT64 *)(Mbcb + 16) )
goto LABEL_86;
*v45 = v46;
*(_QWORD *)(Mbcb + 104) = v44;
*v44 = v45;
*(_QWORD *)(Mbcb + 24) = v45;
v47 = (INT64 *)(Mbcb + 144);
*(_QWORD *)(Mbcb + 112) = 0x7FFFFFFFFFFFFFFFi64;
*(_DWORD *)(Mbcb + 120) = -1;
v48 = *(INT64 ***)(Mbcb + 24);
if( *v48 != (INT64 *)v46 )
LABEL_86:
__fastfail(3u);
*v47 = v46;
*(_QWORD *)(Mbcb + 152) = v48;
*v48 = v47;
*(_QWORD *)(Mbcb + 24) = v47;
*(_QWORD *)(Mbcb + 160) = 0x7FFFFFFFFFFFFFFFi64;
*(_DWORD *)(Mbcb + 168) = -1;
*(_WORD *)Mbcb = 761;
KeReleaseGuardedMutex(&v5->BcbLock);
}
BitmapRangeToDirty = CcFindBitmapRangeToDirty(Mbcb, v7, &ListEntry);
v22 = BitmapRangeToDirty;
if( BitmapRangeToDirty )
{
v23 = *(_QWORD *)(BitmapRangeToDirty + 16);
if( v7 < v23 + *(unsigned int *)(BitmapRangeToDirty + 24) )
*(_DWORD *)(BitmapRangeToDirty + 24) = v7 - v23;
if( v8 > v23 + *(unsigned int *)(BitmapRangeToDirty + 28) )
*(_DWORD *)(BitmapRangeToDirty + 28) = v8 - v23;
v24 = FastScan[0];
LockHandle.LockQueue.Next = 0i64;
LockHandle.LockQueue.Lock = (unsigned __int64 *volatile)(*(_QWORD *)FastScan + 128i64);
v25 = KeGetCurrentIrql();
__writecr8(2ui64);
LockHandle.OldIrql = v25;
CurrentPrcb = KeGetCurrentPrcb();
if( *((_QWORD *)CurrentPrcb + 4247) && *((_BYTE *)CurrentPrcb + 32) <= 1u && *((_BYTE *)CurrentPrcb + 32) == 1 )
v24 = FastScan[0];
v27 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64(
(volatile __int64 *)(*(_QWORD *)FastScan + 128i64),
(__int64)&LockHandle);
if( v27 )
{
KxWaitForLockOwnerShip(&LockHandle.LockQueue, v27);
v24 = FastScan[0];
}
if( !v5->DirtyPages && (v5->Flags & 2) == 0 )
{
CcScheduleLazyWriteScan(v24, 0);
CcInsertIntoDirtySharedCacheMapList(v5);
*(_QWORD *)(Mbcb + 32) = v7;
}
v28 = (_DWORD *)(*(_QWORD *)(v22 + 40) + 4 * ((unsigned __int64)(unsigned int)(v7 - *(_DWORD *)(v22 + 16)) >> 5));
v29 = 1 << (v7 & 0x1F);
if( v7 <= v8 )
{
v30 = v51;
v31 = v8 - v7 + 1;
v7 = v8 + 1;
do
{
v32 = v28;
if( (*v28 & v29) == 0 )
{
*v28 |= v29;
++v30;
}
v33 = 2 * v29;
v29 = 1;
if( v33 )
v29 = v33;
++v28;
if( v33 )
v28 = v32;
--v31;
}
while( v31 );
v51 = v30;
v5 = SharedCacheMap;
}
CcChargeDirtyPages((INT64)v5, Mbcb, v22, v51);
_m_prefetchw(&LockHandle);
Next = LockHandle.LockQueue.Next;
if( !LockHandle.LockQueue.Next )
{
if( (struct _KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockHandle.LockQueue.Lock,
0i64,
(signed __int64)&LockHandle) == &LockHandle )
{
LABEL_50:
__writecr8(LockHandle.OldIrql);
if( (v5->Flags & 0x10000000) != 0 && v51 )
{
v39 = IoIssuerThread;
if( !IoIssuerThread )
{
v39 = (_ETHREAD *)KeGetCurrentThread();
IoIssuerThread = v39;
}
v40 = *(_QWORD *)(*((_QWORD *)v39 + 68) + 2232i64);
if( v40 )
{
if( v51 << 12 )
_InterlockedExchangeAdd64((volatile signed __int64 *)(v40 + 8), v51 << 12);
_InterlockedExchangeAdd64((volatile signed __int64 *)(v40 + 24), 1ui64);
}
}
if( v29 )
{
*(_QWORD *)(Mbcb + 40) = v8;
LABEL_53:
Partition = *(_CC_PARTITION **)FastScan;
goto LABEL_54;
}
continue;
}
Next = KxWaitForLockChainValid(&LockHandle.LockQueue);
}
LockHandle.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_50;
}
break;
}
LABEL_102:
i = 1;
LABEL_103:
if( (v5->Flags & 0x20000) == 0 )
{
KeAcquireInStackQueuedSpinLock((UINT64 *)(*(_QWORD *)FastScan + 128i64), &LockHandle);
v5->Flags |= 0x20000u;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
if( i )
{
LABEL_56:
v36 = &v5->BcbLock;
OldIrql_low = LOBYTE(v36->OldIrql);
v36->Owner = 0i64;
v38 = _InterlockedCompareExchange(&v36->Count, 1, 0);
if( v38 )
ExpReleaseFastMutexContended(v36, v38);
__writecr8(OldIrql_low);
KeAbPostRelease(v36);
}
if( ListEntry )
{
++dword_140CDB3DC;
if( (unsigned __int16)CcBitmapLookasideList >= (unsigned __int16)word_140CDB3D0 )
{
++dword_140CDB3E0;
((void(*)(void))qword_140CDB3F8)();
}
else
{
RtlpInterlockedPushEntrySList((PSLIST_HEADER)&CcBitmapLookasideList, ListEntry);
}
}
}Referenced by:
CcMapAndCopyInToCache
CcMdlWriteComplete2
CcPurgeAndClearCacheSection
CcReleaseByteRangeFromWrite
CcSetDirtyPinnedData