diff --git a/NTOSKRNL/CC/ccmdlhandler.cpp b/NTOSKRNL/CC/ccmdlhandler.cpp index 71bdf21..004e35f 100644 --- a/NTOSKRNL/CC/ccmdlhandler.cpp +++ b/NTOSKRNL/CC/ccmdlhandler.cpp @@ -223,11 +223,8 @@ NTAPI CcMdlWriteAbort(IN PFILE_OBJECT FileObject, IN PMDL MdlChain) { - - - - KIRQL CurrentIrql = null; - PSHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; +KIRQL CurrentIrql = null; +PSHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; for( auto it = begin(MdlChain); it != end(MdlChain);++it) @@ -236,17 +233,14 @@ for( auto it = begin(MdlChain); it != end(MdlChain);++it) { MmUnlockPages(*it); } - IoFreeMdl(*it); - } - - if ( (MdlChain->MdlFlags & 2) != 0 ) - { +if ( (MdlChain->MdlFlags & 2) != 0 ) +{ CurrentIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock); CcDecrementOpenCount(SharedCacheMap); KeReleaseQueuedSpinLock(LockQueueMasterLock, CurrentIrql); - } +} } VOID @@ -258,16 +252,136 @@ CcMdlWriteComplete(IN PFILE_OBJECT FileObject, 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); } } +VOID +NTAPI +CcPrepareMdlWrite(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus) +{ + PMDL Mdl = nullptr; + PVOID VirtualAddress = nullptr; + PSHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; + PLARGE_INTEGER FOffset = nullptr; + PLARGE_INTEGER ReadAheadLenghth = nullptr; + LARGE_INTEGER Final_Length = nullptr; + LARGE_INTEGER ReadAhead_Length = NULL; + LARGE_INTEGER Information = NULL; + ULONG ReceivedLength = NULL; + ULONG SavedState = NULL; + ULONG ZeroOpsFlags = NULL; + PVACB Vacb = nullptr; + BOOL MapFlag = false; + if ((FileObject->Flags & 0x10) == 0) + { + if (IoIsFileOriginRemote(FileObject) && !CcCanIWriteStream(FileObject, Length, 0, 0)) + RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES ); + } + _try{ + + while (Length != NULL) + { + VirtualAddress = CcGetVirtualAddress(SharedCacheMap, &ReceivedLength, &Vacb, 0, FOffset, ReadAheadLenghth); + + /* Should not exceed PageLimit */ + if (ReceivedLength > Length) + ReceivedLength = Length; + Final_Length.QuadPart = FileOffset->QuadPart; + ReadAhead_Length = (ReadAheadLenghth->QuadPart) + (FileOffset->QuadPart); + ZeroOpsFlags = 2; + /* Set the flags for CcMapAndRead */ + if ((FOffset->Lowpart & 0xFFF) == 0 && ReceivedLength >= 0x1000) + { + ZeroOpsFlags = 3; + } + if ((Final_Length & 0xFFF) == 0) + { + ZeroOpsFlags |= 4; + } + KeAcquireInStackQueuedSpinLock(&SharedCacheMap->BcbSpinLock, &LockHandle); + LONGLONG ReadAhead_State = SharedCacheMap->ValidDataGoal.QuadPart - (ReadAheadLenghth << 12 | (FOffset->Lowpart & 0xFFFFF000)); + ReadAheadLenghth = static_cast(ReadAhead_State >> 32); + KeReleaseInStackQueuedSpinLock(&LockHandle); + if (ReadAheadLenghth > 0) + { + SavedState = static_cast(ReadAhead_State); + } + else if ((ReadAheadLenghth & 0x80000000) != 0 || (SavedState = static_cast(ReadAhead_State)) == 0) + { + ZeroOpsFlags |= 7; + } + if (!ReadAheadLenghth && SavedState <= 0x1000) + { + ZeroOpsFlags |= 6; + } + MapFlag = CcMapAndRead(ReceivedLength, ZeroOpsFlags, 1, VirtualAddress); + if(!MapFlag) + { + DBGPRINT(" CcPrepareMdlWrite:: Page Maping Failed \n"); + } + Mdl = IoAllocateMdl(VirtualAddress, ReceivedLength, FALSE, FALSE, NULL); + if (!Mdl) + RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES ); + /*Save the current state of the UserIdealProcessor field & Then Performe Probing and locking of pages*/ + PKTHREAD currentThread = KeGetCurrentThread(); + PULONG userIdealProcessorByte = (PULONG)((ULONG_PTR)currentThread + userIdealProcessorOffset); + ULONG savedState = *(userIdealProcessorByte + 1) + 2; + *(userIdealProcessorByte + 1) = 1; + MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess); + /*Restore the saved state of the UserIdealProcessor field*/ + *(userIdealProcessorByte + 1) = savedState - 2; + /* Update the Read Aheas Stats*/ + KeAcquireInStackQueuedSpinLock(&SharedCacheMap->BcbSpinLock, &LockHandle); + if ( ReadAhead_Length.QuadPart > SharedCacheMap->ValidDataGoal.QuadPart ) + { + SharedCacheMap->ValidDataGoal.QuadPart = ReadAhead_Length.QuadPart; + } + KeReleaseInStackQueuedSpinLock(&LockHandle); + /*Free The VACB and Dereferance it*/ + CcFreeVirtualAddress(Vacb); + Vacb = nullptr; + /* Check if Valid MDL Chain already exist, if so update it with allocated one else assign MDL Chain with one we allocated */ + if (*MdlChain) + { + /*MDL Iterator in Action, While Loopers take your C++ Coolaid now */ + for(auto it = begin(MdlChain); it != end(MdlChain);++it) + { + *it = Allocated; + } + } + else + { + *MdlChain = Mdl; + } + Mdl = nullptr; + FOffset.QuadPart = Final_Length; + ReadAheadLenghth = ReadAhead_Length; + /* Update the IOSTATUS Information FLag with amount of Byte Counts */ + Information += ReceivedLength; + /* Adjust the length as per bytes written, else you will be in mess of a infinite nonsensical loop, Might result in Kaboom aka BSOD */ + Length -= ReceivedLength; + } + } + _finally{ + IoStatus->Status = STATUS_SUCESS; + IoStatus->Information = Information; + KIRQL LAST_IRQL = KeAcquireQueuedSpinLock(LockQueueMasterLock); + SharedCacheMap->OpenCount++; + KeReleaseQueuedSpinLock(LockQueueMasterLock, LAST_IRQL); +} + + + + +