/* * 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); } }