alcyone/NTOSKRNL/CC/ccmdlhandler.cpp
Dibyamartanda Samanta f4b0f5f446 [NTOSKRNL:CC] Catch Controller Add MDL Handler Directives
Following Functions are added,
- CcMdlReadComplete2 
- CcMdlWriteComplete2
- CcMdlRead
-CcMdlReadComplete
-CcMdlWriteAbort
-CcMdlWriteComplete
#TODO
-CcPrepareMdlWrite
2024-05-09 20:32:31 +02:00

274 lines
7.4 KiB
C++

/*
* PROJECT: Alcyone Kernel
* LICENSE: BSD Clause 3
* PURPOSE: Cache Controller:: MDL Handler
* NT KERNEL: 5.11.9360
* COPYRIGHT: 2023-2029 Dibymartanda Samanta <>
*
*/
#include <ntoskrnl.h>
#define NTDEBUG
#include <debug.h>
#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<void*>(CcGetVirtualAddress(sharedcachmap, &VACB, FOffset,(LARGE_INTEGER)&ReceivedLength, 0));
INT PagePriority = static_cast<int>(((&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<LONGLONG>(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<LONGLONG>(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);
}
}