mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
Added:
FsRtlPrepareMdlWriteDev() FsRtlMdlWriteCompleteDev() FsRtlPrepareMdlWrite() FsRtlMdlWriteComplete() svn path=/trunk/; revision=25910
This commit is contained in:
parent
35f897c768
commit
982855b6e3
3 changed files with 368 additions and 46 deletions
|
@ -133,14 +133,16 @@ CcMdlWriteComplete(IN PFILE_OBJECT FileObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use slow path */
|
/* Use slow path */
|
||||||
CcMdlWriteCompleteDev(FileOffset, MdlChain, FileObject);
|
CcMdlWriteComplete2(FileObject,FileOffset, MdlChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
CcMdlWriteCompleteDev(IN PLARGE_INTEGER FileOffset,
|
CcMdlWriteComplete2(
|
||||||
IN PMDL MdlChain,
|
IN PFILE_OBJECT FileObject,
|
||||||
IN PFILE_OBJECT FileObject)
|
IN PLARGE_INTEGER FileOffset,
|
||||||
|
IN PMDL MdlChain
|
||||||
|
)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: ntoskrnl/fsrtl/fastio.c
|
* FILE: ntoskrnl/fsrtl/fastio.c
|
||||||
* PURPOSE: Provides Fast I/O entrypoints to the Cache Manager
|
* PURPOSE: Provides Fast I/O entrypoints to the Cache Manager
|
||||||
* PROGRAMMERS: None.
|
* PROGRAMMERS: buzdelabuz2@gmail.com,alex.ionescu@reactos.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -196,7 +196,8 @@ FsRtlCopyRead(IN PFILE_OBJECT FileObject,
|
||||||
/* Set this as top-level IRP */
|
/* Set this as top-level IRP */
|
||||||
PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP;
|
PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP;
|
||||||
|
|
||||||
_SEH_TRY {
|
_SEH_TRY
|
||||||
|
{
|
||||||
/* Make sure the IO and file size is below 4GB */
|
/* Make sure the IO and file size is below 4GB */
|
||||||
if (Wait && !(Offset.HighPart | FcbHeader->FileSize.HighPart )) {
|
if (Wait && !(Offset.HighPart | FcbHeader->FileSize.HighPart )) {
|
||||||
|
|
||||||
|
@ -226,7 +227,8 @@ FsRtlCopyRead(IN PFILE_OBJECT FileObject,
|
||||||
FileObject->CurrentByteOffset.QuadPart += IoStatus->Information;
|
FileObject->CurrentByteOffset.QuadPart += IoStatus->Information;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(FsRtlCcCopyFilter) {
|
_SEH_EXCEPT(FsRtlCcCopyFilter)
|
||||||
|
{
|
||||||
Result = FALSE;
|
Result = FALSE;
|
||||||
} _SEH_END;
|
} _SEH_END;
|
||||||
|
|
||||||
|
@ -365,13 +367,16 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
(FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) &&
|
(FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) &&
|
||||||
(FcbHeader->AllocationSize.HighPart == 0) &&
|
(FcbHeader->AllocationSize.HighPart == 0) &&
|
||||||
!b_4GB
|
!b_4GB
|
||||||
) {
|
)
|
||||||
} else {
|
{
|
||||||
|
} else
|
||||||
|
{
|
||||||
goto FailAndCleanup;
|
goto FailAndCleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}else {
|
}else
|
||||||
|
{
|
||||||
goto FailAndCleanup;
|
goto FailAndCleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +424,8 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
/* Set this as top-level IRP */
|
/* Set this as top-level IRP */
|
||||||
PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP;
|
PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP;
|
||||||
|
|
||||||
_SEH_TRY {
|
_SEH_TRY
|
||||||
|
{
|
||||||
if (Offset.LowPart > FcbHeader->ValidDataLength.LowPart) {
|
if (Offset.LowPart > FcbHeader->ValidDataLength.LowPart) {
|
||||||
LARGE_INTEGER OffsetVar;
|
LARGE_INTEGER OffsetVar;
|
||||||
OffsetVar.LowPart = Offset.LowPart;
|
OffsetVar.LowPart = Offset.LowPart;
|
||||||
|
@ -430,7 +436,8 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
/* Call the cache manager */
|
/* Call the cache manager */
|
||||||
CcFastCopyWrite(FileObject,Offset.LowPart,Length,Buffer);
|
CcFastCopyWrite(FileObject,Offset.LowPart,Length,Buffer);
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(FsRtlCcCopyFilter) {
|
_SEH_EXCEPT(FsRtlCcCopyFilter)
|
||||||
|
{
|
||||||
Result = FALSE;
|
Result = FALSE;
|
||||||
} _SEH_END;
|
} _SEH_END;
|
||||||
|
|
||||||
|
@ -493,13 +500,13 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
{
|
{
|
||||||
/* Acquire the resource shared */
|
/* Acquire the resource shared */
|
||||||
if (!ExAcquireResourceSharedLite(FcbHeader->Resource,Wait)) {
|
if (!ExAcquireResourceSharedLite(FcbHeader->Resource,Wait)) {
|
||||||
goto FailAndCleanup;
|
goto LeaveCriticalAndFail;
|
||||||
}
|
}
|
||||||
ResourceAquiredShared =TRUE;
|
ResourceAquiredShared =TRUE;
|
||||||
} else {
|
} else {
|
||||||
/* Acquire the resource exclusive */
|
/* Acquire the resource exclusive */
|
||||||
if (!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait)) {
|
if (!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait)) {
|
||||||
goto FailAndCleanup;
|
goto LeaveCriticalAndFail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,7 +535,8 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
/* Check if we can keep the lock shared */
|
/* Check if we can keep the lock shared */
|
||||||
if (ResourceAquiredShared && (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) ) {
|
if (ResourceAquiredShared && (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) ) {
|
||||||
ExReleaseResourceLite(FcbHeader->Resource);
|
ExReleaseResourceLite(FcbHeader->Resource);
|
||||||
if(!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait)) {
|
if(!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait))
|
||||||
|
{
|
||||||
goto LeaveCriticalAndFail;
|
goto LeaveCriticalAndFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,7 +550,8 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
if ( (FileObject->PrivateCacheMap != NULL) &&
|
if ( (FileObject->PrivateCacheMap != NULL) &&
|
||||||
(FcbHeader->IsFastIoPossible != FastIoIsNotPossible) &&
|
(FcbHeader->IsFastIoPossible != FastIoIsNotPossible) &&
|
||||||
(FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart)
|
(FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart)
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
/* Do nothing */
|
/* Do nothing */
|
||||||
} else {
|
} else {
|
||||||
goto FailAndCleanup;
|
goto FailAndCleanup;
|
||||||
|
@ -600,7 +609,8 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
/* Nagar p.544 */
|
/* Nagar p.544 */
|
||||||
/* Set ourselves as top component */
|
/* Set ourselves as top component */
|
||||||
PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP;
|
PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP;
|
||||||
_SEH_TRY {
|
_SEH_TRY
|
||||||
|
{
|
||||||
BOOLEAN CallCc = TRUE;
|
BOOLEAN CallCc = TRUE;
|
||||||
/* Check if there is a gap between the end of the file and the offset
|
/* Check if there is a gap between the end of the file and the offset
|
||||||
If yes, then we have to zero the data
|
If yes, then we have to zero the data
|
||||||
|
@ -619,7 +629,8 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
if (CallCc) {
|
if (CallCc) {
|
||||||
Result = CcCopyWrite(FileObject,&Offset,Length, Wait, Buffer);
|
Result = CcCopyWrite(FileObject,&Offset,Length, Wait, Buffer);
|
||||||
}
|
}
|
||||||
}_SEH_EXCEPT(FsRtlCcCopyFilter) {
|
}_SEH_EXCEPT(FsRtlCcCopyFilter)
|
||||||
|
{
|
||||||
Result = FALSE;
|
Result = FALSE;
|
||||||
} _SEH_END;
|
} _SEH_END;
|
||||||
|
|
||||||
|
@ -637,6 +648,7 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
} else {
|
} else {
|
||||||
FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart;
|
FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Flag the file as modified */
|
/* Flag the file as modified */
|
||||||
FileObject->Flags |= FO_FILE_MODIFIED;
|
FileObject->Flags |= FO_FILE_MODIFIED;
|
||||||
|
@ -649,7 +661,6 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject,
|
||||||
/* Update the current FO byte offset */
|
/* Update the current FO byte offset */
|
||||||
FileObject->CurrentByteOffset.QuadPart = NewSize.QuadPart;
|
FileObject->CurrentByteOffset.QuadPart = NewSize.QuadPart;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The operation did not succeed
|
/* The operation did not succeed
|
||||||
|
@ -743,7 +754,7 @@ FsRtlGetFileSize(IN PFILE_OBJECT FileObject,
|
||||||
Irp->UserIosb = &IoStatus;
|
Irp->UserIosb = &IoStatus;
|
||||||
Irp->UserEvent = &Event;
|
Irp->UserEvent = &Event;
|
||||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||||
Irp->Flags = IRP_INPUT_OPERATION | IRP_PAGING_IO;
|
Irp->Flags = IRP_SYNCHRONOUS_PAGING_IO | IRP_PAGING_IO;
|
||||||
Irp->RequestorMode = KernelMode;
|
Irp->RequestorMode = KernelMode;
|
||||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||||
Irp->AssociatedIrp.SystemBuffer = &Info;
|
Irp->AssociatedIrp.SystemBuffer = &Info;
|
||||||
|
@ -761,12 +772,14 @@ FsRtlGetFileSize(IN PFILE_OBJECT FileObject,
|
||||||
Status = IofCallDriver(DeviceObject,Irp);
|
Status = IofCallDriver(DeviceObject,Irp);
|
||||||
|
|
||||||
/* Standard DDK IRP result processing */
|
/* Standard DDK IRP result processing */
|
||||||
if (Status == STATUS_PENDING) {
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
|
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there was a synchronous error, signal it */
|
/* If there was a synchronous error, signal it */
|
||||||
if (!NT_SUCCESS(Status)) {
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
IoStatus.Status = Status;
|
IoStatus.Status = Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,10 +1043,41 @@ FsRtlMdlWriteComplete(IN PFILE_OBJECT FileObject,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN PMDL MdlChain)
|
IN PMDL MdlChain)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
|
||||||
|
PFAST_IO_DISPATCH FastDispatch;
|
||||||
|
|
||||||
|
/* Get Device Object and Fast Calls */
|
||||||
|
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
|
||||||
|
|
||||||
|
/* Check if we support Fast Calls, and check this one */
|
||||||
|
if (FastDispatch && FastDispatch->MdlWriteComplete)
|
||||||
|
{
|
||||||
|
/* Use the fast path */
|
||||||
|
return FastDispatch->MdlWriteComplete(FileObject,
|
||||||
|
FileOffset,
|
||||||
|
MdlChain,
|
||||||
|
DeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Base File System (Volume) and Fast Calls */
|
||||||
|
BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
|
||||||
|
FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
|
||||||
|
|
||||||
|
/* If the Base Device Object has its own FastDispatch Routine, fail */
|
||||||
|
if (FastDispatch && FastDispatch->MdlWriteComplete &&
|
||||||
|
BaseDeviceObject != DeviceObject)
|
||||||
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No fast path, use slow path */
|
||||||
|
return FsRtlMdlWriteCompleteDev(FileObject,
|
||||||
|
FileOffset,
|
||||||
|
MdlChain,
|
||||||
|
DeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -1044,10 +1088,17 @@ FsRtlMdlWriteCompleteDev(IN PFILE_OBJECT FileObject,
|
||||||
IN PMDL MdlChain,
|
IN PMDL MdlChain,
|
||||||
IN PDEVICE_OBJECT DeviceObject)
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
if (FileObject->Flags & FO_WRITE_THROUGH)
|
||||||
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Call the Cache Manager */
|
||||||
|
CcMdlWriteComplete2(FileObject,FileOffset,MdlChain);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -1060,12 +1111,49 @@ FsRtlPrepareMdlWrite(IN PFILE_OBJECT FileObject,
|
||||||
OUT PMDL *MdlChain,
|
OUT PMDL *MdlChain,
|
||||||
OUT PIO_STATUS_BLOCK IoStatus)
|
OUT PIO_STATUS_BLOCK IoStatus)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
|
||||||
|
PFAST_IO_DISPATCH FastDispatch;
|
||||||
|
|
||||||
|
/* Get Device Object and Fast Calls */
|
||||||
|
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
|
||||||
|
|
||||||
|
/* Check if we support Fast Calls, and check this one */
|
||||||
|
if (FastDispatch && FastDispatch->PrepareMdlWrite)
|
||||||
|
{
|
||||||
|
/* Use the fast path */
|
||||||
|
return FastDispatch->PrepareMdlWrite(FileObject,
|
||||||
|
FileOffset,
|
||||||
|
Length,
|
||||||
|
LockKey,
|
||||||
|
MdlChain,
|
||||||
|
IoStatus,
|
||||||
|
DeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Base File System (Volume) and Fast Calls */
|
||||||
|
BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
|
||||||
|
FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
|
||||||
|
|
||||||
|
/* If the Base Device Object has its own FastDispatch Routine, fail */
|
||||||
|
if (FastDispatch && FastDispatch->PrepareMdlWrite &&
|
||||||
|
BaseDeviceObject != DeviceObject)
|
||||||
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No fast path, use slow path */
|
||||||
|
return FsRtlPrepareMdlWriteDev(FileObject,
|
||||||
|
FileOffset,
|
||||||
|
Length,
|
||||||
|
LockKey,
|
||||||
|
MdlChain,
|
||||||
|
IoStatus,
|
||||||
|
DeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -1077,10 +1165,237 @@ FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject,
|
||||||
OUT PIO_STATUS_BLOCK IoStatus,
|
OUT PIO_STATUS_BLOCK IoStatus,
|
||||||
IN PDEVICE_OBJECT DeviceObject)
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
BOOLEAN Result = TRUE;
|
||||||
|
PFAST_IO_DISPATCH FastIoDispatch;
|
||||||
|
PDEVICE_OBJECT Device;
|
||||||
|
PFSRTL_COMMON_FCB_HEADER FcbHeader;
|
||||||
|
|
||||||
|
LARGE_INTEGER OldFileSize;
|
||||||
|
LARGE_INTEGER OldValidDataLength;
|
||||||
|
LARGE_INTEGER NewSize;
|
||||||
|
LARGE_INTEGER Offset;
|
||||||
|
|
||||||
|
/* WDK doc. Offset=0xffffffffffffffff indicates append to the end of file */
|
||||||
|
BOOLEAN FileOffsetAppend = ((FileOffset->HighPart == 0xffffffff) && (FileOffset->LowPart == 0xffffffff));
|
||||||
|
BOOLEAN FileSizeModified = FALSE;
|
||||||
|
BOOLEAN ResourceAquiredShared = FALSE;
|
||||||
|
|
||||||
|
/* Initialize some of the vars and pointers */
|
||||||
|
OldFileSize.QuadPart = 0;
|
||||||
|
OldValidDataLength.QuadPart = 0;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
Offset.QuadPart = FileOffset->QuadPart + Length;
|
||||||
|
|
||||||
|
/* Nagar p.544 -- Check with Cc if we can write */
|
||||||
|
if ( (!CcCanIWrite(FileObject, Length,TRUE,FALSE))||
|
||||||
|
(FileObject->Flags & FO_WRITE_THROUGH))
|
||||||
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IoStatus->Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* No actual read */
|
||||||
|
if (!Length)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext;
|
||||||
|
FsRtlEnterFileSystem();
|
||||||
|
|
||||||
|
/* Check we are going to extend the file */
|
||||||
|
if ( (FileOffsetAppend == FALSE) &&
|
||||||
|
( (FileOffset->QuadPart + Length) <= FcbHeader->ValidDataLength.QuadPart )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Acquire the resource shared */
|
||||||
|
ExAcquireResourceSharedLite(FcbHeader->Resource,TRUE);
|
||||||
|
ResourceAquiredShared =TRUE;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
/* Acquire the resource exclusive */
|
||||||
|
ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we are appending */
|
||||||
|
if (FileOffsetAppend == TRUE) {
|
||||||
|
Offset.QuadPart = FcbHeader->FileSize.QuadPart;
|
||||||
|
NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
Offset.QuadPart = FileOffset->QuadPart;
|
||||||
|
NewSize.QuadPart = FileOffset->QuadPart + Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (FileObject->PrivateCacheMap) &&
|
||||||
|
(FcbHeader->IsFastIoPossible) &&
|
||||||
|
(MAXLONGLONG >= (LONGLONG) FileOffset->QuadPart + Length) &&
|
||||||
|
(NewSize.QuadPart <= FcbHeader->AllocationSize.QuadPart) )
|
||||||
|
{
|
||||||
|
/* Check if we can keep the lock shared */
|
||||||
|
if (ResourceAquiredShared && (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) ) {
|
||||||
|
ExReleaseResourceLite(FcbHeader->Resource);
|
||||||
|
ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE);
|
||||||
|
|
||||||
|
/* Compute the offset and the new filesize */
|
||||||
|
if (FileOffsetAppend) {
|
||||||
|
Offset.QuadPart = FcbHeader->FileSize.QuadPart;
|
||||||
|
NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recheck the above points since we released and reacquire the lock */
|
||||||
|
if ( (FileObject->PrivateCacheMap != NULL) &&
|
||||||
|
(FcbHeader->IsFastIoPossible != FastIoIsNotPossible) &&
|
||||||
|
(FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Do nothing */
|
||||||
|
} else {
|
||||||
|
goto FailAndCleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we need to find out if fast I/O is available */
|
||||||
|
if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable)
|
||||||
|
{
|
||||||
|
/* Sanity check */
|
||||||
|
/* ASSERT(!KeIsExecutingDpc()); */
|
||||||
|
|
||||||
|
/* Get the Fast I/O table */
|
||||||
|
Device = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
FastIoDispatch = Device->DriverObject->FastIoDispatch;
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
ASSERT(FastIoDispatch != NULL);
|
||||||
|
ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL);
|
||||||
|
|
||||||
|
/* Ask the driver if we can do it */
|
||||||
|
if (!FastIoDispatch->FastIoCheckIfPossible(FileObject,
|
||||||
|
FileOffset,
|
||||||
|
Length,
|
||||||
|
TRUE,
|
||||||
|
LockKey,
|
||||||
|
FALSE,
|
||||||
|
IoStatus,
|
||||||
|
Device))
|
||||||
|
{
|
||||||
|
/* It's not, fail */
|
||||||
|
goto FailAndCleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we are going to modify the filesize, save the old fs in case the operation fails */
|
||||||
|
if (NewSize.QuadPart > FcbHeader->FileSize.QuadPart)
|
||||||
|
{
|
||||||
|
FileSizeModified = TRUE;
|
||||||
|
OldFileSize.QuadPart = FcbHeader->FileSize.QuadPart;
|
||||||
|
OldValidDataLength.QuadPart = FcbHeader->ValidDataLength.QuadPart;
|
||||||
|
|
||||||
|
/* If the high part of the filesize is going to change, grab the Paging IoResouce */
|
||||||
|
if (NewSize.HighPart != FcbHeader->FileSize.HighPart && FcbHeader->PagingIoResource)
|
||||||
|
{
|
||||||
|
ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE);
|
||||||
|
FcbHeader->FileSize.QuadPart = NewSize.QuadPart;
|
||||||
|
ExReleaseResourceLite(FcbHeader->PagingIoResource);
|
||||||
|
} else {
|
||||||
|
FcbHeader->FileSize.QuadPart = NewSize.QuadPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Nagar p.544 */
|
||||||
|
/* Set ourselves as top component */
|
||||||
|
PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP;
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Check if there is a gap between the end of the file and the offset
|
||||||
|
If yes, then we have to zero the data
|
||||||
|
*/
|
||||||
|
if (Offset.QuadPart > FcbHeader->ValidDataLength.QuadPart) {
|
||||||
|
Result = CcZeroData(FileObject,&FcbHeader->ValidDataLength,&Offset,TRUE);
|
||||||
|
if (Result)
|
||||||
|
{
|
||||||
|
CcPrepareMdlWrite(FileObject,&Offset,Length,MdlChain,IoStatus);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CcPrepareMdlWrite(FileObject,&Offset,Length,MdlChain,IoStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
}_SEH_EXCEPT(FsRtlCcCopyFilter)
|
||||||
|
{
|
||||||
|
Result = FALSE;
|
||||||
|
} _SEH_END;
|
||||||
|
|
||||||
|
/* Reset the top component */
|
||||||
|
PsGetCurrentThread()->TopLevelIrp = 0;
|
||||||
|
|
||||||
|
/* Did the operation suceeded */
|
||||||
|
if (Result) {
|
||||||
|
/* Check if we need to update the filesize */
|
||||||
|
if (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) {
|
||||||
|
if (NewSize.HighPart != FcbHeader->ValidDataLength.HighPart && FcbHeader->PagingIoResource) {
|
||||||
|
ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE);
|
||||||
|
FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart;
|
||||||
|
ExReleaseResourceLite(FcbHeader->PagingIoResource);
|
||||||
|
} else {
|
||||||
|
FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flag the file as modified */
|
||||||
|
FileObject->Flags |= FO_FILE_MODIFIED;
|
||||||
|
/* Check if the filesize has changed */
|
||||||
|
if (FileSizeModified) {
|
||||||
|
/* Update the file sizes */
|
||||||
|
((SHARED_CACHE_MAP*) FileObject->SectionObjectPointer->SharedCacheMap)->FileSize.QuadPart = NewSize.QuadPart;
|
||||||
|
FileObject->Flags |= FO_FILE_SIZE_CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The operation did not succeed
|
||||||
|
Reset the file size to what it should be
|
||||||
|
*/
|
||||||
|
if (FileSizeModified) {
|
||||||
|
if (FcbHeader->PagingIoResource) {
|
||||||
|
ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE);
|
||||||
|
FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart;
|
||||||
|
FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart;
|
||||||
|
ExReleaseResourceLite(FcbHeader->PagingIoResource);
|
||||||
|
}else{
|
||||||
|
FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart;
|
||||||
|
FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
goto Cleanup;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto FailAndCleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FailAndCleanup:
|
||||||
|
|
||||||
|
ExReleaseResourceLite(FcbHeader->Resource);
|
||||||
|
FsRtlExitFileSystem();
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
|
||||||
|
ExReleaseResourceLite(FcbHeader->Resource);
|
||||||
|
FsRtlExitFileSystem();
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -1088,6 +1403,10 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject)
|
FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
PAGED_CODE();
|
||||||
|
FsRtlAcquireFileExclusiveCommon(FileObject,0,0);
|
||||||
|
*/
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,6 +1417,7 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
FsRtlReleaseFile(IN PFILE_OBJECT FileObject)
|
FsRtlReleaseFile(IN PFILE_OBJECT FileObject)
|
||||||
{
|
{
|
||||||
|
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,10 +70,10 @@ CcMdlReadComplete2(
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcMdlWriteCompleteDev(
|
CcMdlWriteComplete2(
|
||||||
|
IN PFILE_OBJECT FileObject,
|
||||||
IN PLARGE_INTEGER FileOffset,
|
IN PLARGE_INTEGER FileOffset,
|
||||||
IN PMDL MdlChain,
|
IN PMDL MdlChain
|
||||||
IN PFILE_OBJECT FileObject
|
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
Loading…
Reference in a new issue