From 62ebdde712d17f619e69eaf73fd97fceedc84676 Mon Sep 17 00:00:00 2001 From: Dibyamartanda Samanta Date: Wed, 7 Aug 2024 16:09:29 +0200 Subject: [PATCH] [NTOSKRNL:CC] Cache Controller Pinsupport :: CcPinRead and CcPinMappedData Completely implemented CcPinRead and CcPinMappedData In future Refactor with BCB Iterator with bounds checking. --- NTOSKRNL/CC/ccpinsupport.cpp | 135 ++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/NTOSKRNL/CC/ccpinsupport.cpp b/NTOSKRNL/CC/ccpinsupport.cpp index da6aea3..898edd5 100644 --- a/NTOSKRNL/CC/ccpinsupport.cpp +++ b/NTOSKRNL/CC/ccpinsupport.cpp @@ -727,7 +727,77 @@ CcPinMappedData( IN ULONG Flags, IN OUT PCC_BCB Bcb) { - //Unimplemented + PSHARED_CACHE_MAP SharedCacheMap = nullptr; + LARGE_INTEGER LocalFileOffset = {0}; + LARGE_INTEGER BeyondLastByte ={0}; + PVOID Buffer = nullptr; + POBCB localbcb = nullptr; + PCC_BCB *localbcbptr = nullptr; + PCC_BCB *Bcbs = nullptr; + bool Result = false; + + + LocalFileOffset = *FileOffset; + + if (!(reinterpret_cast(Bcb) & 1)) + return true; + + *Bcb = reinterpret_cast(reinterpret_cast(*Bcb) - 1); + + SharedCacheMap = reinterpret_cast(FileObject->SectionObjectPointer->SharedCacheMap); + InterlockedIncrement(&SharedCacheMap->PinCount); + + if (ExAcquireSharedStarveExclusive(&((PCC_BCB)*Bcb)->BcbResource, ((Flags & 1) == 1))) + { + Result = true; + } + else + { + LARGE_INTEGER localoffset = LocalFileOffset; + ULONG RemainingLength = Length; + + while (true) + { + if (localbcb) + { + if (localbcbptr == reinterpret_cast(&localbcb)) + { + localbcb = CcAllocateObcb(FileOffset, Length, reinterpret_cast(localbcb)); + Bcbs = localbcb->Bcbs; + localbcbptr = localbcb->Bcbs; + } + RemainingLength += localoffset.LowPart - BeyondLastByte.LowPart; + localoffset = BeyondLastByte; + LocalFileOffset = BeyondLastByte; + localbcbptr = ++Bcbs; + } + + if (!CcPinFileData(FileObject,&LocalFileOffset,RemainingLength,!(SharedCacheMap->Flags & 0x200),false,Flags,localbcbptr,&Buffer,&BeyondLastByte)) + { + Result = false; + break; + } + + if ((BeyondLastByte.QuadPart - localoffset.QuadPart) >= RemainingLength) + { + CcFreeVirtualAddress(reinterpret_cast(*Bcb)); + *Bcb = localbcb; + Result = true; + break; + } + } + } + + if (!Result) + { + *Bcb = reinterpret_cast(reinterpret_cast(*Bcb) + 1); + if (localbcb) + { + CcUnpinData(localbcb); + } + } + + return Result; } BOOLEAN @@ -740,7 +810,68 @@ CcPinRead( OUT PVOID *Bcb, OUT PVOID *Buffer) { - //Unimplemented + PSHARED_CACHE_MAP SharedCacheMap = nullptr; + LARGE_INTEGER LocalFileOffset ={0}; + LARGE_INTEGER BeyondLastByte ={0}; + PVOID LocalBuffer = nullptr; + POBCB localbcb = nullptr; + PCC_BCB *localBcbPtr = nullptr; + bool Result = false; + ULONG RemainingLength = Length; + + + + LocalFileOffset = *FileOffset; + + if (Flags & 1) // 1 Signifies Pin is waiting + CcPinReadWait++; + else + CcPinReadNoWait++; + + + SharedCacheMap = reinterpret_cast(FileObject->SectionObjectPointer->SharedCacheMap); + /* Main Pinning Loop*/ + while (true) + { + if (localbcb) + { + if (localBcbPtr == reinterpret_cast(&localbcb)) + { + localbcb = CcAllocateObcb(FileOffset, RemainingLength, reinterpret_cast(localbcb)); + localBcbPtr = localbcb->Bcbs; + *Buffer = LocalBuffer; + } + RemainingLength += LocalFileOffset.LowPart - BeyondLastByte.LowPart; + LocalFileOffset = BeyondLastByte; + ++localBcbPtr; + } + + if (!CcPinFileData(FileObject,&LocalFileOffset,RemainingLength,(SharedCacheMap->Flags & 0x200) == 0,false,Flags,localBcbPtr,&LocalBuffer,&BeyondLastByte)) + { + Result = false; + break; + } + + if (BeyondLastByte.QuadPart - LocalFileOffset.QuadPart >= RemainingLength) + { + *Bcb = localbcb; + if (localBcbPtr == reinterpret_cast(&localbcb)) + { + *Buffer = LocalBuffer; + } + Result = true; + break; + } + } + + + + if (!Result && localbcb) + { + CcUnpinData(localbcb); + } + + return Result; } BOOLEAN