From f4b0f5f446d35dfdeeee46439f158a58247f90de Mon Sep 17 00:00:00 2001 From: Dibyamartanda Samanta Date: Thu, 9 May 2024 20:32:31 +0200 Subject: [PATCH] [NTOSKRNL:CC] Catch Controller Add MDL Handler Directives Following Functions are added, - CcMdlReadComplete2 - CcMdlWriteComplete2 - CcMdlRead -CcMdlReadComplete -CcMdlWriteAbort -CcMdlWriteComplete #TODO -CcPrepareMdlWrite --- NTOSKRNL/CC/ccmdlhandler.cpp | 273 +++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 NTOSKRNL/CC/ccmdlhandler.cpp diff --git a/NTOSKRNL/CC/ccmdlhandler.cpp b/NTOSKRNL/CC/ccmdlhandler.cpp new file mode 100644 index 0000000..71bdf21 --- /dev/null +++ b/NTOSKRNL/CC/ccmdlhandler.cpp @@ -0,0 +1,273 @@ +/* +* PROJECT: Alcyone Kernel +* LICENSE: BSD Clause 3 +* PURPOSE: Cache Controller:: MDL Handler +* NT KERNEL: 5.11.9360 +* COPYRIGHT: 2023-2029 Dibymartanda Samanta <> +* +*/ +#include +#define NTDEBUG +#include +#include "ccinternal.hpp" +#include "ccmdl.hpp" + + +extern "C" + +/*Internal Function*/ + +VOID +NTAPI +CcMdlReadComplete2 ( + IN PFILE_OBJECT FileObject, + IN PMDL MdlChain +) +{ + /* Check if MDL Chain is Valid */ + if (MdlChain) + { + /*Iterate Through the MDL CHain*/ + for( auto it = begin(MdlChain); it != end(MdlChain);++it) + { + /*Unlock the memory pages associated with the MDL*/ + MmUnlockPages(*it); + /*Free The MDL */ + IoFreeMdl(*it); + } + } +} +CcMdlWriteComplete2(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain) +{ + +PLARGE_INTEGER FOffset = nullptr; +KIRQL CurrentIrql = NULL; +NTSTATUS Exception = NULL; +PIO_STATUS_BLOCK IoStatus = nullptr; + + +for( auto it = begin(MdlChain); it != end(MdlChain);++it) +{ + + if (!(MdlChain->MdlFlags & 2) == 0) ) + { + MmUnlockPages(*it); + + } + if ( (FileObject->Flags & 16) != 0 ) + { + MmFlushSection((*it)->ByteCount, SharedCacheMap, &IoStatus, 1); + if ( !NTSTATUS(IoStatus.Status) ) + Exception = IoStatus.Status; + } + else + { + CcSetDirtyInMask(SharedCacheMap, &FOffset, (*it)->ByteCount); + } + FOffset.QuadPart += (*it)->ByteCount; +} + + if (!(MdlChain->MdlFlags & 2) == 0)) + { + CurrentIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock); + CcDecrementOpenCount(SharedCacheMap); + KeReleaseQueuedSpinLock(LockQueueMasterLock,CurrentIrql); + } + if (!NT_SUCCESS(Exception)) + { + RtlRaiseStatus(FsRtlNormalizeNtstatus(Exception, WRITE_EXCEPTION)); + } + /* Write Operation is COmplete, Now Free the MDL Chain*/ +for( auto it = begin(MdlChain); it != end(MdlChain);++it) + { + /*Free The MDL */ + IoFreeMdl(*it); + } +} + +/* External Function */ +VOID +NTAPI +CcMdlRead ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + OUT PMDL * MdlChain, + OUT PIO_STATUS_BLOCK IoStatus) +{ + + ULONG LENGTH_FINAL = Length; + PVOID VirtualAddress = nullptr; + PVACB VACB = nullptr; + ULONG ReceivedLength = NULL; + ULONG Information = NULL; + PMDL Allocated = NULL; + LARGE_INTEGER FOffset = FileOffset; + PSHARED_CACHE_MAP sharedcachmap = FileObject->SectionObjectPointer->SharedCacheMap; + PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap; + PVOID VirtualAddress = nullptr; + LARGE_INTEGER Offset_Lenghth = NULL; + + +_try +{ + +/* Iterate until it is final length is null*/ + while(Length != NULL) + { + + VirtualAddress = static_cast(CcGetVirtualAddress(sharedcachmap, &VACB, FOffset,(LARGE_INTEGER)&ReceivedLength, 0)); + INT PagePriority = static_cast(((&sharedcachmap->NodeTypeCode >> 18) & 7)); + + if ((sharedcachmap->Flags & 8)== null ) + { + /* Our Memory Manager doesn't support prefetching yet, will be added in 2025*/ + //CcFetchDataForRead(FileObject,&FOffset,Length,Wait_Type_MDL_Read,&FaultedData,&VACB,PagePriority,MDL_READTYPE_DiskIoAttribution); // Return + } + + if ( ReceivedLength > Length ) + { + ReceivedLength = Length; + } + + + Offset_Lenghth = FOffset.QuadPart + static_cast(ReceivedLength); + + + /* Allocate the MDL ,it is not associated with Specific IRP*/ + Allocated = IoAllocateMdl(VirtualAddress,ReceivedLength , false, false, optional_irp); + + /* Assign the MDL to MmProbeAndLockPages to prevent Page Fault/ Data Corruption */ + MmProbeAndLockPages(Allocated, KernelMode, IoReadAccess); + /* Free the VACB */ + CcFreeVirtualAddress(VACB); + + /* Now Update the MDL Chain with allocated one */ + +/* Check if Valid MDL Chain already exist, if so update it with allocated one else assign MDL Chain with one we allocated */ + if ( *MdlChain != NULL) + { for( auto it = begin(MdlChain); it != end(MdlChain);++it) + { + *it = Allocated; + } + } + else + { + *MdlChain = Allocated; + } + + + + FOffset.QuadPart = Offset_Lenghth.QuadPart; + + /* Update the IOSTATUS Information FLag */ + Information += ReceivedLength; + /* Adjust the length , else you will be in mess of a infinite nonsensical loop fighting with Exception Handler */ + Length -= ReceivedLength; +} + +} + +_finally{ + + if ( (FileObject->Flags & 0x100000) = = 0 ||(&PrivateCacheMap->NodeType_UlongFlags & 0x20000 == 0) && FaultedData ) + { + CcScheduleReadAheadEx(FileObject, FileOffset,Length,NULL); + _InterlockedOr(&PrivateCacheMap->NodeType_UlongFlags, FLAG_UPDATE_READAHEAD); + + } + + +/* No mater What , Catch History must be updated even if Aliens Invasion Happens that day*/ +/* UPDATE CATCH HISTORY */ +InterlockedExchange64(&PrivateCachemap->FileOffset1,PrivateCachemap->FileOffset2); +InterlockedExchange64(&PrivateCachemap->BeyondLastByte1,PrivateCachemap->BeyondLastByte2); +InterlockedExchange64(&PrivateCachemap->FileOffset2,*FileOffset); +LONG LONG FinalLength =FileOffset->QuadPart+ static_cast(Length); +InterlockedExchange64(&PrivateCachemap->BeyondLastByte2.Quadpart,FinalLength); + +/* Update Shared Cachemap Flags */ +if ( (SharedCacheMap->Flags & 8) != 0 ) +{ + KIRQL LAST_IRQL = KeAcquireQueuedSpinLock(LockQueueMasterLock); + SharedCacheMap->Flags &= ~8; + KeReleaseQueuedSpinLock(LockQueueMasterLock, LAST_IRQL); +} + +/* Update IRP Bytes */ +IoStatus->Status = Status_Sucess; +IoStatus->Information = Information; +} +} + +VOID +NTAPI +CcMdlReadComplete(IN PFILE_OBJECT FileObject, + IN PMDL MdlChain) +{ + PDEVICE_OBJECT RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject); + FAST_IO_DISPATCH FastIoDispatch = RelatedDeviceObject->DriverObject->FastIoDispatch; + /* Start Faster MDL Operator if Suceeds , don't execute slower CcMdlReadComplete2*/ + BOOL MdlReadComplete_FLag = (*PFAST_IO_MDL_READ_COMPLETE) ( FileObject, MdlChain, RelatedDeviceObject); + + if ( !FastIoDispatch|| FastIoDispatch->SizeOfFastIoDispatch <= MAXIO_DISPATCH|| (MdlReadComplete_FLag = FastIoDispatch->MdlReadComplete) == 0|| !MdlReadComplete_FLag ) + { + CcMdlReadComplete2(NULL,MdlChain); + } +} + +VOID +NTAPI +CcMdlWriteAbort(IN PFILE_OBJECT FileObject, + IN PMDL MdlChain) +{ + + + + KIRQL CurrentIrql = null; + PSHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; + + +for( auto it = begin(MdlChain); it != end(MdlChain);++it) +{ + if ((MdlChain->MdlFlags & 2) != 0 ) + { + MmUnlockPages(*it); + } + + IoFreeMdl(*it); + +} + + if ( (MdlChain->MdlFlags & 2) != 0 ) + { + CurrentIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock); + CcDecrementOpenCount(SharedCacheMap); + KeReleaseQueuedSpinLock(LockQueueMasterLock, CurrentIrql); + } +} + +VOID +NTAPI +CcMdlWriteComplete(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain) +{ + + DEVICE_OBJECT RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject); + FAST_IO_DISPATCH FastIoDispatch = RelatedDeviceObject->DriverObject->FastIoDispatch; + + BOOL MdlWriteComplete_FLag = (*PFAST_IO_MDL_WRITE_COMPLETE) ( FileObject, FileOffset, MdlChain, RelatedDeviceObject); + /* Start Faster MDL Operator if Suceeds , don't execute slower CcMdlReadComplete2*/ + + + if (!FastIoDispatch|| FastIoDispatch->SizeOfFastIoDispatch <= MAXIO_DISPATCH|| (MdlWriteComplete_FLag = FastIoDispatch->MdlWriteComplete) == 0|| !MdlWriteComplete_FLag) + { + CcMdlWriteComplete2(FileObject,FileOffset,MdlChain); + } +} + + +