CcSetDirtyInMask
VOID __stdcall CcSetDirtyInMask(
_SHARED_CACHE_MAP *SharedCacheMap,
_LARGE_INTEGER *FileOffset,
UINT64 Length,
_ETHREAD *IoIssuerThread){
LONGLONG QuadPart;
_SHARED_CACHE_MAP *v5;
LONGLONG v6;
__int64 v7;
signed __int64 v8;
__int64 v9;
__int64 v10;
int i;
UINT64 *v12;
volatile signed __int32 *v13;
_ETHREAD *CurrentThread;
__int64 v15;
char v16;
__int64 v17;
NTSTATUS v18;
bool v19;
unsigned __int8 CurrentIrql;
_MBCB *v21;
_BITMAP_RANGE *BitmapRangeToDirty;
_BITMAP_RANGE *v23;
__int64 BasePage;
UINT8 v25;
unsigned __int8 v26;
struct _KPRCB *CurrentPrcb;
unsigned int *v28;
int v29;
unsigned int v30;
__int64 v31;
unsigned int *v32;
int v33;
_KSPIN_LOCK_QUEUE *volatile Next;
LONGLONG v35;
char *v36;
unsigned __int64 v37;
unsigned __int32 v38;
_ETHREAD *v39;
_PROCESS_DISK_COUNTERS *DiskCounters;
_MBCB *InitializeMbcb;
UINT64 *v42;
unsigned int *Bitmap;
_LIST_ENTRY *Blink;
_BITMAP_RANGE *p_BitmapRange2;
_LIST_ENTRY *p_BitmapRanges;
_BITMAP_RANGE *p_BitmapRange3;
_LIST_ENTRY *v48;
__int64 AbOrphanedEntrySummary;
int v50;
unsigned int NumberOfPages;
UINT64 a3;
UINT8 FastScan[8];
UINT64 *FreePageForSetting;
__int64 v55;
_KLOCK_QUEUE_HANDLE LockQueue;
int v59;
QuadPart = FileOffset->QuadPart;
v5 = SharedCacheMap;
FreePageForSetting = 0i64;
v59 = 0;
v55 = (unsigned int)Length;
v6 = QuadPart + (unsigned int)Length;
NumberOfPages = 0;
memset(&LockQueue, 0, sizeof(LockQueue));
if( ((QuadPart ^ (v6 - 1)) & 0xFFFFFFFFFE000000ui64) != 0 )
KeBugCheckEx(0x34u, (PVOID)0xC52, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
if( (*((_DWORD *)v5 + 38) & 0x40000000) != 0 && v6 <= *((_QWORD *)v5 + 6) )
return;
v7 = QuadPart >> 12;
v8 = (v6 - 1) >> 12;
if( *((_QWORD *)v5 + 4) / 4096i64 <= v8 )
KeBugCheckEx(0x34u, (PVOID)0xC72, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
v9 = *((_QWORD *)v5 + 66);
*(_QWORD *)FastScan = v9;
if( *((_QWORD *)v5 + 21) )
{
LODWORD(v10) = MmGetControlAreaPartition(*(_QWORD *)((*((_QWORD *)v5 + 12) & 0xFFFFFFFFFFFFFFF0ui64) + 0x28));
if( v9 != *(_QWORD *)(v10 + 8) )
KeBugCheckEx(0x34u, (PVOID)0x1313, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
}
if( (*((_DWORD *)v5 + 38) & 0x40000000) != 0 )
{
ExAcquireFastMutex((PFAST_MUTEX)v5 + 5);
LABEL_54:
v35 = FileOffset->QuadPart + v55;
if( v35 > *((_QWORD *)v5 + 6) )
{
v19 = (*((_DWORD *)v5 + 38) & 0x40000000) == 0;
*((_QWORD *)v5 + 6) = v35;
if( !v19 )
{
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v9 + 128), &LockQueue);
v50 = *((_DWORD *)v5 + 38);
if( (v50 & 0x400) == 0 )
*((_DWORD *)v5 + 38) = v50 | 0x400;
CcInsertIntoDirtySharedCacheMapList(v5);
CcScheduleLazyWriteScan(v9, 0);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
__writecr8(LockQueue.OldIrql);
}
}
goto LABEL_56;
}
while( 2 )
{
for( i = v59; ; i = 0 )
{
if( *((_QWORD *)v5 + 4) > 0x300000ui64 )
{
++*(&WheapErrorSourceTable + 351);
v12 = (UINT64 *)RtlpInterlockedPopEntrySList((PSLIST_HEADER)((char *)&WheapErrorSourceTable + 1384));
if( !v12 )
{
++*(&WheapErrorSourceTable + 352);
v12 = (UINT64 *)(*(&WheapErrorSourceTable + 179))(
*(&WheapErrorSourceTable + 355),
*(&WheapErrorSourceTable + 357),
*(&WheapErrorSourceTable + 356));
if( !v12 )
{
++*(&CmpDummyThreadEvent + 769);
goto LABEL_103;
}
}
FreePageForSetting = v12;
}
LODWORD(a3) = 0;
v13 = (volatile signed __int32 *)((char *)v5 + 280);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v59 = 1;
--CurrentThread->Tcb.SpecialApcDisable;
if( ++CurrentThread->Tcb.AbAllocationRegionCount != 1 )
KeBugCheckEx(0x192u, CurrentThread, (char *)v5 + 280, (PVOID)KeGetCurrentIrql(), 0i64);
LOBYTE(v15) = CurrentThread->Tcb.AbEntrySummary;
if( !(_BYTE)v15 )
{
if( !CurrentThread->Tcb.AbOrphanedEntrySummary )
{
v17 = 0i64;
LABEL_94:
_interlockedbittestandset((volatile signed __int32 *)&CurrentThread->Tcb.116 + 1, 0x10u);
goto LABEL_17;
}
AbOrphanedEntrySummary = CurrentThread->Tcb.AbOrphanedEntrySummary;
CurrentThread->Tcb.AbOrphanedEntrySummary = 0;
LOBYTE(v15) = AbOrphanedEntrySummary | CurrentThread->Tcb.AbEntrySummary;
}
v16 = v15;
_BitScanForward((unsigned int *)&v15, (unsigned __int8)v15);
CurrentThread->Tcb.AbEntrySummary = v16 & ~(1 << v15);
v17 = (__int64)&CurrentThread->Tcb.LockEntries[v15];
if( !v17 )
goto LABEL_94;
v18 = MiGetSystemRegionType((UINT64)v5 + 280) == 1 ? MmGetSessionIdEx(CurrentThread->Tcb.ApcState.Process) : -1;
*(_DWORD *)(v17 + 40) = v18;
*(_QWORD *)(v17 + 32) = (unsigned __int64)v13 & 0x7FFFFFFFFFFFFFFCi64;
LABEL_17:
--CurrentThread->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&CurrentThread->Tcb, (char *)v5 + 280, &a3);
v19 = CurrentThread->Tcb.SpecialApcDisable++ == -1;
if( v19
&& ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152 )
{
KiCheckForKernelApcDelivery();
}
CurrentIrql = KeGetCurrentIrql();
__writecr8(1ui64);
if( !_interlockedbittestandreset(v13, 0) )
ExpAcquireFastMutexContended((_FAST_MUTEX *)v5 + 5, (VOID *)v17);
if( v17 )
*(_BYTE *)(v17 + 26) |= 1u;
*((_QWORD *)v5 + 36) = KeGetCurrentThread();
*((_DWORD *)v5 + 82) = CurrentIrql;
v21 = (_MBCB *)*((_QWORD *)v5 + 20);
if( !v21 )
{
InitializeMbcb = CcAllocateInitializeMbcb();
v21 = InitializeMbcb;
if( !InitializeMbcb )
goto LABEL_102;
*((_QWORD *)v5 + 20) = InitializeMbcb;
}
if( v7 == v8 && v7 == v21->MostRecentlyDirtiedPage )
goto LABEL_53;
if( (unsigned __int64)v8 < 0x300 || v21->NodeTypeCode == 761 )
break;
v42 = FreePageForSetting;
memset(FreePageForSetting, 0i64, 0x400u);
if( v21->BitmapRange1.DirtyPages )
{
Bitmap = v21->BitmapRange1.Bitmap;
*(_OWORD *)v42 = *(_OWORD *)Bitmap;
*((_OWORD *)v42 + 1) = *((_OWORD *)Bitmap + 1);
*((_OWORD *)v42 + 2) = *((_OWORD *)Bitmap + 2);
*((_OWORD *)v42 + 3) = *((_OWORD *)Bitmap + 3);
*((_OWORD *)v42 + 4) = *((_OWORD *)Bitmap + 4);
*((_OWORD *)v42 + 5) = *((_OWORD *)Bitmap + 5);
memset(v21->BitmapRange1.Bitmap, 0i64, 0x60u);
}
v21->BitmapRange1.Bitmap = (unsigned int *)v42;
Blink = v21->BitmapRanges.Blink;
p_BitmapRange2 = &v21->BitmapRange2;
FreePageForSetting = 0i64;
p_BitmapRanges = &v21->BitmapRanges;
if( Blink->Flink != &v21->BitmapRanges )
goto LABEL_86;
p_BitmapRange2->Links.Flink = p_BitmapRanges;
v21->BitmapRange2.Links.Blink = Blink;
Blink->Flink = &p_BitmapRange2->Links;
v21->BitmapRanges.Blink = &p_BitmapRange2->Links;
p_BitmapRange3 = &v21->BitmapRange3;
v21->BitmapRange2.BasePage = 0x7FFFFFFFFFFFFFFFi64;
v21->BitmapRange2.FirstDirtyPage = -1;
v48 = v21->BitmapRanges.Blink;
if( v48->Flink != p_BitmapRanges )
LABEL_86:
__fastfail(3u);
p_BitmapRange3->Links.Flink = p_BitmapRanges;
v21->BitmapRange3.Links.Blink = v48;
v48->Flink = &p_BitmapRange3->Links;
v21->BitmapRanges.Blink = &p_BitmapRange3->Links;
v21->BitmapRange3.BasePage = 0x7FFFFFFFFFFFFFFFi64;
v21->BitmapRange3.FirstDirtyPage = -1;
v21->NodeTypeCode = 761;
KeReleaseGuardedMutex((PKGUARDED_MUTEX)v5 + 5);
}
BitmapRangeToDirty = CcFindBitmapRangeToDirty(v21, v7, &FreePageForSetting);
v23 = BitmapRangeToDirty;
if( BitmapRangeToDirty )
{
BasePage = BitmapRangeToDirty->BasePage;
if( v7 < BasePage + BitmapRangeToDirty->FirstDirtyPage )
BitmapRangeToDirty->FirstDirtyPage = v7 - BasePage;
if( v8 > BasePage + BitmapRangeToDirty->LastDirtyPage )
BitmapRangeToDirty->LastDirtyPage = v8 - BasePage;
v25 = FastScan[0];
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = (unsigned __int64 *volatile)(*(_QWORD *)FastScan + 128i64);
v26 = KeGetCurrentIrql();
__writecr8(2ui64);
LockQueue.OldIrql = v26;
CurrentPrcb = KeGetCurrentPrcb();
if( CurrentPrcb->SchedulerAssist && CurrentPrcb->NestingLevel <= 1u && CurrentPrcb->NestingLevel == 1 )
v25 = FastScan[0];
if( _InterlockedExchange64((volatile __int64 *)(*(_QWORD *)FastScan + 128i64), (__int64)&LockQueue) )
{
KxWaitForLockOwnerShip((INT64)&LockQueue);
v25 = FastScan[0];
}
if( !*((_DWORD *)v5 + 28) && (*((_DWORD *)v5 + 38) & 2) == 0 )
{
CcScheduleLazyWriteScan(v25, 0);
CcInsertIntoDirtySharedCacheMapList(v5);
v21->ResumeWritePage = v7;
}
v28 = &v23->Bitmap[(unsigned __int64)(unsigned int)(v7 - LODWORD(v23->BasePage)) >> 5];
v29 = 1 << (v7 & 0x1F);
if( v7 <= v8 )
{
v30 = NumberOfPages;
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 );
NumberOfPages = v30;
v5 = SharedCacheMap;
}
CcChargeDirtyPages(v5, v21, v23, NumberOfPages);
_m_prefetchw(&LockQueue);
Next = LockQueue.LockQueue.Next;
if( !LockQueue.LockQueue.Next )
{
if( (_KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.LockQueue.Lock,
0i64,
(signed __int64)&LockQueue) == &LockQueue )
{
LABEL_50:
__writecr8(LockQueue.OldIrql);
if( (*((_DWORD *)v5 + 38) & 0x10000000) != 0 && NumberOfPages )
{
v39 = IoIssuerThread;
if( !IoIssuerThread )
{
v39 = (_ETHREAD *)KeGetCurrentThread();
IoIssuerThread = v39;
}
DiskCounters = v39->Tcb.Process->DiskCounters;
if( DiskCounters )
{
if( NumberOfPages << 12 )
_InterlockedExchangeAdd64((volatile signed __int64 *)&DiskCounters->BytesWritten, NumberOfPages << 12);
_InterlockedExchangeAdd64((volatile signed __int64 *)&DiskCounters->WriteOperationCount, 1ui64);
}
}
if( v29 )
{
v21->MostRecentlyDirtiedPage = v8;
LABEL_53:
v9 = *(_QWORD *)FastScan;
goto LABEL_54;
}
continue;
}
Next = KxWaitForLockChainValid(&LockQueue.LockQueue);
}
LockQueue.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_50;
}
break;
}
LABEL_102:
i = 1;
LABEL_103:
if( (*((_DWORD *)v5 + 38) & 0x20000) == 0 )
{
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(*(_QWORD *)FastScan + 128i64), &LockQueue);
*((_DWORD *)v5 + 38) |= 0x20000u;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
__writecr8(LockQueue.OldIrql);
}
if( i )
{
LABEL_56:
v36 = (char *)v5 + 280;
v37 = (unsigned __int8)v36[48];
*((_QWORD *)v36 + 1) = 0i64;
v38 = _InterlockedCompareExchange((volatile signed __int32 *)v36, 1, 0);
if( v38 )
ExpReleaseFastMutexContended((_FAST_MUTEX *)v36, v38);
__writecr8(v37);
KeAbPostRelease(v36);
}
if( FreePageForSetting )
{
++*(&WheapErrorSourceTable + 353);
if( *(&WheapErrorSourceTable + 692) >= *(&WheapErrorSourceTable + 700) )
{
++*(&WheapErrorSourceTable + 354);
(*(&WheapErrorSourceTable + 180))();
}
else
{
RtlpInterlockedPushEntrySList(
(PSLIST_HEADER)((char *)&WheapErrorSourceTable + 1384),
(PSLIST_ENTRY)FreePageForSetting);
}
}
}Referenced by:
CcMapAndCopyInToCache
CcMdlWriteComplete2
CcPurgeAndClearCacheSection
CcReleaseByteRangeFromWrite
CcSetDirtyPinnedData