[NTOSKRNL:CC] Implemented CcSetDirtyInMask

This commit is contained in:
Dibyamartanda Samanta 2024-11-08 08:58:18 +01:00 committed by CodingWorkshop Signing Team
parent d81565e7ec
commit f6620f9372
Signed by: CodingWorkshop Signing Team
GPG Key ID: 6DC88369C82795D2

View File

@ -100,28 +100,160 @@ CcFindBitmapRangeToDirty(
VOID
NTAPI
CcSetDirtyInMask(
_In_ PSHARED_CACHE_MAP SharedMap,
_In_ PSHARED_CACHE_MAP SharedCacheMap,
_In_ PLARGE_INTEGER FileOffset,
_In_ ULONG Length)
{
NT_DBGBREAK("UNIMPLEMENTED\n");
KLOCK_QUEUE_HANDLE LockHandle = {0};
LARGE_INTEGER EndOffset = {0};
ULONGLONG StartPage ={0};
ULONGLONG EndPage = {0};
ULONG CurrentPage = {0};
PMBCB Mbcb = nullptr;
PBITMAP_RANGE BitmapRange = nullptr;
PULONG Bitmap = nullptr;
PULONG VacbLevel = nullptr;
ULONG BitMask = {0};
// Calculate start and end pages
StartPage = FileOffset->QuadPart >> PAGE_SHIFT;
EndOffset.QuadPart = FileOffset->QuadPart + Length;
EndPage = (EndOffset.QuadPart - 1) >> PAGE_SHIFT;
for(;;)
{
if (SharedCacheMap->SectionSize.QuadPart > VACB_MAPPING_GRANULARITY)
{
if (!CcPrefillVacbLevelZone(1, &LockHandle, 0, 0, 0))
return;
VacbLevel = CcAllocateVacbLevel(0);
KeLowerIrql(LockHandle.OldIrql);
}
KeAcquireInStackQueuedSpinLock(&SharedCacheMap->BcbSpinLock, &LockHandle);
Mbcb = SharedCacheMap->Mbcb;
if (Mbcb == nullptr)
{
Mbcb = CcAllocateInitializeBcb();
if (Mbcb == nullptr)
goto ReleaseAndExit;
Mbcb->NodeTypeCode = CACHE_NTC_BCB;
InitializeListHead(&Mbcb->BitmapRanges);
InsertHeadList(&Mbcb->BitmapRanges, &Mbcb->BitmapRange1.Links);
Mbcb->BitmapRange1.FirstDirtyPage = (ULONG)-1;
Mbcb->BitmapRange1.Bitmap = (PULONG)&Mbcb->BitmapRange2;
SharedCacheMap->Mbcb = Mbcb;
}
if (EndPage < 512 || Mbcb->NodeTypeCode == 0x02F9)
{
BitmapRange = CcFindBitmapRangeToDirty(Mbcb, StartPage, &Bitmap);
if (BitmapRange == nullptr)
break;
if (StartPage < BitmapRange->BasePage + BitmapRange->FirstDirtyPage)
BitmapRange->FirstDirtyPage = StartPage - BitmapRange->BasePage;
if (EndPage > BitmapRange->BasePage + BitmapRange->LastDirtyPage)
BitmapRange->LastDirtyPage = EndPage - BitmapRange->BasePage;
if (SharedCacheMap->DirtyPages == 0)
{
CcScheduleLazyWriteScan(FALSE);
RemoveEntryList(&SharedCacheMap->SharedCacheMapLinks);
InsertTailList(&CcDirtySharedCacheMapList, &SharedCacheMap->SharedCacheMapLinks);
Mbcb->ResumeWritePage = StartPage;
}
Bitmap = &BitmapRange->Bitmap[(StartPage - BitmapRange->BasePage) >> 5];
BitMask = 1 << (StartPage & 0x1F);
for (CurrentPage = StartPage; CurrentPage <= EndPage; CurrentPage++)
{
if ((*Bitmap & BitMask) == 0)
{
CcTotalDirtyPages++;
Mbcb->DirtyPages++;
BitmapRange->DirtyPages++;
SharedCacheMap->DirtyPages++;
*Bitmap |= BitMask;
}
BitMask <<= 1;
if (BitMask == 0)
{
Bitmap++;
BitMask = 1;
}
}
}
else
{
// Handle large files (>2MB)
if (Mbcb->BitmapRange1.DirtyPages)
{
RtlCopyMemory(VacbLevel, Mbcb->BitmapRange1.Bitmap, (2 * sizeof(BITMAP_RANGE)));
RtlZeroMemory(Mbcb->BitmapRange1.Bitmap, (2 * sizeof(BITMAP_RANGE)));
}
Mbcb->BitmapRange1.Bitmap = VacbLevel;
// Initialize BitmapRange2
InsertTailList(&Mbcb->BitmapRanges, &Mbcb->BitmapRange2.Links);
Mbcb->BitmapRange2.BasePage = (ULONGLONG)-1;
Mbcb->BitmapRange2.FirstDirtyPage = (ULONG)-1;
// Initialize BitmapRange3
InsertTailList(&Mbcb->BitmapRanges, &Mbcb->BitmapRange3.Links);
Mbcb->BitmapRange3.BasePage = (ULONGLONG)-1;
Mbcb->BitmapRange3.FirstDirtyPage = (ULONG)-1;
VacbLevel = nullptr;
Mbcb->NodeTypeCode = 0x02F9;
KeReleaseInStackQueuedSpinLock(&LockHandle);
continue;
}
// Update ValidDataGoal if necessary
if (EndOffset.QuadPart > SharedCacheMap->ValidDataGoal.QuadPart)
{
SharedCacheMap->ValidDataGoal = EndOffset;
}
break;
}
ReleaseAndExit:
if (VacbLevel != nullptr)
{
*VacbLevel = (ULONG)CcVacbLevelFreeList;
CcVacbLevelEntries++;
CcVacbLevelFreeList = VacbLevel;
}
KeReleaseInStackQueuedSpinLock(&LockHandle);
}
BOOLEAN
NTAPI
CcMapAndCopy(
_In_ PSHARED_CACHE_MAP SharedMap,
_In_ PSHARED_CACHE_MAP SharedCacheMap,
_In_ PVOID Buffer,
_In_ PLARGE_INTEGER FileOffset,
_In_ ULONG Length,
_In_ ULONG CopyFlags,
_In_ ULONG Flags,
_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER ValidDataLength,
_In_ BOOLEAN Wait)
{
NT_DBGBREAK("UNIMPLEMENTED\n");
{
NT_DBGBREAK("UNIMPLEMENTED\n");
}
/* EXTERNAL API FUNCTIONS */
BOOLEAN
@ -132,22 +264,22 @@ CcCanIWrite(
_In_ BOOLEAN Wait,
_In_ UCHAR Retrying)
{
PFSRTL_COMMON_FCB_HEADER FsContext;
PSHARED_CACHE_MAP SharedCacheMap;
DEFERRED_WRITE DeferredWrite;
KEVENT Event;
ULONG WriteSize;
ULONG Pages;
KIRQL OldIrql;
BOOLEAN IsSmallThreshold = FALSE;
PFSRTL_COMMON_FCB_HEADER FsContext = nullptr;
PSHARED_CACHE_MAP SharedCacheMap = nullptr;
DEFERRED_WRITE DeferredWrite = {0};
KEVENT Event = {0};
ULONG WriteSize = {0};
ULONG Pages = {0};
KIRQL OldIrql = {0};
BOOLEAN IsSmallThreshold = false;
/* Quick checks for immediate return */
if (FileObject->Flags & FO_WRITE_THROUGH)
return TRUE;
return true;
if (IoIsFileOriginRemote(FileObject) && Retrying < 0xFD)
return TRUE;
return true;
/* Calculate size and pages */
WriteSize = min(BytesToWrite, 0x40000);
@ -172,7 +304,7 @@ CcCanIWrite(
{
if (SharedCacheMap->DirtyPageThreshold < (SharedCacheMap->DirtyPages + Pages))
{
IsSmallThreshold = TRUE;
IsSmallThreshold = true;
}
}
}
@ -192,7 +324,7 @@ CcCanIWrite(
MmAvailablePages > MmThrottleBottom &&
!IsSmallThreshold))
{
return TRUE;
return true;
}
}
@ -207,7 +339,7 @@ CcCanIWrite(
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
}
KeInitializeEvent(&Event, NotificationEvent, FALSE);
KeInitializeEvent(&Event, NotificationEvent, false);
DeferredWrite.NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
DeferredWrite.NodeByteSize = sizeof(DEFERRED_WRITE);
@ -238,7 +370,7 @@ CcCanIWrite(
} while (KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
false,
&CcIdleDelay) != STATUS_SUCCESS);
return TRUE;