[NTOSKRNL:CC] Catch Controller:: CcPrepareMdlWrite
Implement Remaining MDL Handler Function
This commit is contained in:
parent
9a120bad01
commit
85794e26cd
@ -223,9 +223,6 @@ NTAPI
|
||||
CcMdlWriteAbort(IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
|
||||
|
||||
|
||||
KIRQL CurrentIrql = null;
|
||||
PSHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
|
||||
@ -236,11 +233,8 @@ for( auto it = begin(MdlChain); it != end(MdlChain);++it)
|
||||
{
|
||||
MmUnlockPages(*it);
|
||||
}
|
||||
|
||||
IoFreeMdl(*it);
|
||||
|
||||
}
|
||||
|
||||
if ( (MdlChain->MdlFlags & 2) != 0 )
|
||||
{
|
||||
CurrentIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
|
||||
@ -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<ULONG>(ReadAhead_State >> 32);
|
||||
KeReleaseInStackQueuedSpinLock(&LockHandle);
|
||||
if (ReadAheadLenghth > 0)
|
||||
{
|
||||
SavedState = static_cast<ULONG>(ReadAhead_State);
|
||||
}
|
||||
else if ((ReadAheadLenghth & 0x80000000) != 0 || (SavedState = static_cast<ULONG>(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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user