Author: pschweitzer
Date: Wed Jul 26 09:28:41 2017
New Revision: 75409
URL:
http://svn.reactos.org/svn/reactos?rev=75409&view=rev
Log:
[RDBSS]
- Implement RxFastIoWrite()
- Finish implementation of RxFastIoCheckIfPossible()
[COPYSUP]
- Implement FsRtlCopyWrite2()
This brings (in link with r75398 fast IO writes to RDBSS, and thus NFS!
CORE-8204
CORE-11327
Modified:
trunk/reactos/sdk/include/ddk/mrxfcb.h
trunk/reactos/sdk/lib/drivers/copysup/copysup.c
trunk/reactos/sdk/lib/drivers/copysup/copysup.h
trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c
Modified: trunk/reactos/sdk/include/ddk/mrxfcb.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/ddk/mrxfcb.h?r…
==============================================================================
--- trunk/reactos/sdk/include/ddk/mrxfcb.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/include/ddk/mrxfcb.h [iso-8859-1] Wed Jul 26 09:28:41 2017
@@ -179,6 +179,7 @@
} MRX_SRV_OPEN, *PMRX_SRV_OPEN;
#define FOBX_FLAG_DFS_OPEN 0x0001
+#define FOBX_FLAG_BAD_HANDLE 0x0002
#define FOBX_FLAG_BACKUP_INTENT 0x0004
typedef struct _MRX_PIPE_HANDLE_INFORMATION
Modified: trunk/reactos/sdk/lib/drivers/copysup/copysup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/copysup/co…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/copysup/copysup.c [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/copysup/copysup.c [iso-8859-1] Wed Jul 26 09:28:41 2017
@@ -28,6 +28,8 @@
#include "copysup.h"
#include <pseh/pseh2.h>
+#define NDEBUG
+#include <debug.h>
/* FUNCTIONS ****************************************************************/
@@ -180,3 +182,513 @@
return Ret;
}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+FsRtlCopyWrite2(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN ULONG LockKey,
+ IN PVOID Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID TopLevelContext)
+{
+ IO_STATUS_BLOCK LocalIoStatus;
+ PFSRTL_ADVANCED_FCB_HEADER Fcb;
+ BOOLEAN WriteToEof, AcquiredShared, FileSizeChanged, Ret;
+ LARGE_INTEGER WriteOffset, LastOffset, InitialFileSize, InitialValidDataLength;
+
+ PAGED_CODE();
+
+ /* First, check whether we're writing to EOF */
+ WriteToEof = ((FileOffset->LowPart == FILE_WRITE_TO_END_OF_FILE) &&
+ (FileOffset->HighPart == -1));
+
+ /* If Cc says we cannot write, fail now */
+ if (!CcCanIWrite(FileObject, Length, Wait, FALSE))
+ {
+ return FALSE;
+ }
+
+ /* Write through means no cache */
+ if (BooleanFlagOn(FileObject->Flags, FO_WRITE_THROUGH))
+ {
+ return FALSE;
+ }
+
+ /* If write is > 64Kb, don't use FastIO */
+ if (!CcCopyWriteWontFlush(FileObject, FileOffset, Length))
+ {
+ return FALSE;
+ }
+
+ /* Initialize the IO_STATUS_BLOCK */
+ IoStatus->Status = STATUS_SUCCESS;
+ IoStatus->Information = Length;
+
+ /* No length, it's already written! */
+ if (Length == 0)
+ {
+ return TRUE;
+ }
+
+ AcquiredShared = FALSE;
+ FileSizeChanged = FALSE;
+ Fcb = FileObject->FsContext;
+
+ FsRtlEnterFileSystem();
+
+ /* If we cannot wait, or deal with files bigger then 4GB */
+ if (!Wait || (Fcb->AllocationSize.HighPart != 0))
+ {
+ /* If we're to extend the file, then, acquire exclusively */
+ if (WriteToEof || FileOffset->QuadPart + Length >
Fcb->ValidDataLength.QuadPart)
+ {
+ if (!ExAcquireResourceExclusiveLite(Fcb->Resource, Wait))
+ {
+ FsRtlExitFileSystem();
+ return FALSE;
+ }
+ }
+ /* Otherwise, a shared lock is enough */
+ else
+ {
+ if (!ExAcquireResourceSharedLite(Fcb->Resource, Wait))
+ {
+ FsRtlExitFileSystem();
+ return FALSE;
+ }
+
+ AcquiredShared = TRUE;
+ }
+
+ /* Get first write offset, and last */
+ if (WriteToEof)
+ {
+ WriteOffset.QuadPart = Fcb->FileSize.QuadPart;
+ LastOffset.QuadPart = WriteOffset.QuadPart + Length;
+ }
+ else
+ {
+ WriteOffset.QuadPart = FileOffset->QuadPart;
+ LastOffset.QuadPart = WriteOffset.QuadPart + Length;
+ }
+
+ /* If cache wasn't initialized, fail */
+ if (FileObject->PrivateCacheMap == NULL ||
+ Fcb->IsFastIoPossible == FastIoIsNotPossible)
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+
+ /* If we're to write beyond allocation size, it's no go,
+ * same is we create a hole bigger than 8kb
+ */
+ if ((Fcb->ValidDataLength.QuadPart + 0x2000 <= WriteOffset.QuadPart) ||
+ (Length > MAXLONGLONG - WriteOffset.QuadPart) ||
+ (Fcb->AllocationSize.QuadPart < LastOffset.QuadPart))
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+
+ /* If we have to extend the VDL, shared lock isn't enough */
+ if (AcquiredShared && LastOffset.QuadPart >
Fcb->ValidDataLength.QuadPart)
+ {
+ /* So release, and attempt to acquire exclusively */
+ ExReleaseResourceLite(Fcb->Resource);
+ if (!ExAcquireResourceExclusiveLite(Fcb->Resource, Wait))
+ {
+ FsRtlExitFileSystem();
+ return FALSE;
+ }
+
+ /* Get again EOF, in case file size changed in between */
+ if (WriteToEof)
+ {
+ WriteOffset.QuadPart = Fcb->FileSize.QuadPart;
+ LastOffset.QuadPart = WriteOffset.QuadPart + Length;
+ }
+
+ /* Make sure caching is still enabled */
+ if (FileObject->PrivateCacheMap == NULL ||
+ Fcb->IsFastIoPossible == FastIoIsNotPossible)
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+
+ /* And that we're not writting beyond allocation size */
+ if (Fcb->AllocationSize.QuadPart < LastOffset.QuadPart)
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+ }
+
+ /* If FastIO is questionable, then question */
+ if (Fcb->IsFastIoPossible == FastIoIsQuestionable)
+ {
+ PFAST_IO_DISPATCH FastIoDispatch;
+ PDEVICE_OBJECT RelatedDeviceObject;
+
+ RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject);
+ FastIoDispatch = RelatedDeviceObject->DriverObject->FastIoDispatch;
+ ASSERT(FastIoDispatch != NULL);
+ ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL);
+
+ if (!FastIoDispatch->FastIoCheckIfPossible(FileObject,
+ &WriteOffset,
+ Length, Wait, LockKey,
+ FALSE, &LocalIoStatus,
+ RelatedDeviceObject))
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+ }
+
+ /* If we write beyond EOF, then, save previous sizes (in case of failure)
+ * and update file size, to allow writing
+ */
+ if (LastOffset.QuadPart > Fcb->FileSize.QuadPart)
+ {
+ FileSizeChanged = TRUE;
+ InitialFileSize.QuadPart = Fcb->FileSize.QuadPart;
+ InitialValidDataLength.QuadPart = Fcb->ValidDataLength.QuadPart;
+
+ if (LastOffset.HighPart != Fcb->FileSize.HighPart &&
+ Fcb->PagingIoResource != NULL)
+ {
+ ExAcquireResourceExclusiveLite(Fcb->PagingIoResource, TRUE);
+ Fcb->FileSize.QuadPart = LastOffset.QuadPart;
+ ExReleaseResourceLite(Fcb->PagingIoResource);
+ }
+ else
+ {
+ Fcb->FileSize.QuadPart = LastOffset.QuadPart;
+ }
+ }
+
+ /* Set caller provided context as top level IRP */
+ IoSetTopLevelIrp(TopLevelContext);
+
+ Ret = TRUE;
+
+ /* And perform the writing */
+ _SEH2_TRY
+ {
+ /* Check whether we've to create a hole first */
+ if (LastOffset.QuadPart > Fcb->ValidDataLength.QuadPart)
+ {
+ Ret = CcZeroData(FileObject, &Fcb->ValidDataLength,
+ &WriteOffset, Wait);
+ }
+
+ /* If not needed, or if it worked, write data */
+ if (Ret)
+ {
+ Ret = CcCopyWrite(FileObject, &WriteOffset,
+ Length, Wait, Buffer);
+ }
+ }
+ _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH)
+ {
+ Ret = FALSE;
+ }
+ _SEH2_END;
+
+ /* Restore top level IRP */
+ IoSetTopLevelIrp(NULL);
+
+ /* If writing succeed */
+ if (Ret)
+ {
+ /* If we wrote beyond VDL, update it */
+ if (LastOffset.QuadPart > Fcb->ValidDataLength.QuadPart)
+ {
+ if (LastOffset.HighPart != Fcb->ValidDataLength.HighPart &&
+ Fcb->PagingIoResource != NULL)
+ {
+ ExAcquireResourceExclusiveLite(Fcb->PagingIoResource, TRUE);
+ Fcb->ValidDataLength.QuadPart = LastOffset.QuadPart;
+ ExReleaseResourceLite(Fcb->PagingIoResource);
+ }
+ else
+ {
+ Fcb->ValidDataLength.QuadPart = LastOffset.QuadPart;
+ }
+ }
+
+ /* File was obviously modified */
+ SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
+
+ /* And if we increased it, modify size in Cc and update FO */
+ if (FileSizeChanged)
+ {
+ (*CcGetFileSizePointer(FileObject)).QuadPart = LastOffset.QuadPart;
+ SetFlag(FileObject->Flags, FO_FILE_SIZE_CHANGED);
+ }
+
+ /* Update offset */
+ FileObject->CurrentByteOffset.QuadPart = WriteOffset.QuadPart + Length;
+ }
+ else
+ {
+ /* We failed, we need to restore previous sizes */
+ if (FileSizeChanged)
+ {
+ if (Fcb->PagingIoResource != NULL)
+ {
+ ExAcquireResourceExclusiveLite(Fcb->PagingIoResource, TRUE);
+ Fcb->FileSize.QuadPart = InitialFileSize.QuadPart;
+ Fcb->ValidDataLength.QuadPart = InitialValidDataLength.QuadPart;
+ ExReleaseResourceLite(Fcb->PagingIoResource);
+ }
+ else
+ {
+ Fcb->FileSize.QuadPart = InitialFileSize.QuadPart;
+ Fcb->ValidDataLength.QuadPart = InitialValidDataLength.QuadPart;
+ }
+ }
+ }
+ }
+ else
+ {
+ BOOLEAN AboveFour;
+
+ WriteOffset.HighPart = 0;
+ LastOffset.HighPart = 0;
+
+ /* If we're to extend the file, then, acquire exclusively
+ * Here, easy stuff, we know we can wait, no return to check!
+ */
+ if (WriteToEof || FileOffset->QuadPart + Length >
Fcb->ValidDataLength.QuadPart)
+ {
+ ExAcquireResourceExclusiveLite(Fcb->Resource, TRUE);
+ }
+ /* Otherwise, a shared lock is enough */
+ else
+ {
+ ExAcquireResourceSharedLite(Fcb->Resource, TRUE);
+ AcquiredShared = TRUE;
+ }
+
+ /* Get first write offset, and last
+ * Also check whether our writing will bring us
+ * beyond the 4GB
+ */
+ if (WriteToEof)
+ {
+ WriteOffset.LowPart = Fcb->FileSize.LowPart;
+ LastOffset.LowPart = WriteOffset.LowPart + Length;
+ AboveFour = (LastOffset.LowPart < Fcb->FileSize.LowPart);
+ }
+ else
+ {
+ WriteOffset.LowPart = FileOffset->LowPart;
+ LastOffset.LowPart = WriteOffset.LowPart + Length;
+ AboveFour = (LastOffset.LowPart < FileOffset->LowPart) ||
+ (FileOffset->HighPart != 0);
+ }
+
+ /* If cache wasn't initialized, fail */
+ if (FileObject->PrivateCacheMap == NULL ||
+ Fcb->IsFastIoPossible == FastIoIsNotPossible)
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+
+ /* If we're to write beyond allocation size, it's no go,
+ * same is we create a hole bigger than 8kb
+ * same if we end writing beyond 4GB
+ */
+ if ((Fcb->AllocationSize.LowPart < LastOffset.LowPart) ||
+ (WriteOffset.LowPart >= Fcb->ValidDataLength.LowPart + 0x2000) ||
+ AboveFour)
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+
+ /* If we have to extend the VDL, shared lock isn't enough */
+ if (AcquiredShared && LastOffset.LowPart >
Fcb->ValidDataLength.LowPart)
+ {
+ /* So release, and acquire exclusively */
+ ExReleaseResourceLite(Fcb->Resource);
+ ExAcquireResourceExclusiveLite(Fcb->Resource, TRUE);
+
+ /* Get again EOF, in case file size changed in between and
+ * recheck we won't go beyond 4GB
+ */
+ if (WriteToEof)
+ {
+ WriteOffset.LowPart = Fcb->FileSize.LowPart;
+ LastOffset.LowPart = WriteOffset.LowPart + Length;
+ AboveFour = (((LARGE_INTEGER)LastOffset).LowPart <
+ Fcb->FileSize.LowPart);
+ }
+
+ /* Make sure caching is still enabled */
+ if (FileObject->PrivateCacheMap == NULL ||
+ Fcb->IsFastIoPossible == FastIoIsNotPossible)
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+
+ /* And that we're not writting beyond allocation size
+ * and that we're not going above 4GB
+ */
+ if ((Fcb->AllocationSize.LowPart < LastOffset.LowPart) ||
+ (Fcb->AllocationSize.HighPart != 0) || AboveFour)
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+ }
+
+ /* If FastIO is questionable, then question */
+ if (Fcb->IsFastIoPossible == FastIoIsQuestionable)
+ {
+ PFAST_IO_DISPATCH FastIoDispatch;
+ PDEVICE_OBJECT RelatedDeviceObject;
+ C_ASSERT(sizeof(LARGE_INTEGER) == sizeof(LONGLONG));
+
+ RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject);
+ FastIoDispatch = RelatedDeviceObject->DriverObject->FastIoDispatch;
+ ASSERT(FastIoDispatch != NULL);
+ ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL);
+
+ if (!FastIoDispatch->FastIoCheckIfPossible(FileObject,
+ &WriteOffset,
+ Length, Wait, LockKey,
+ FALSE, &LocalIoStatus,
+ RelatedDeviceObject))
+ {
+ ExReleaseResourceLite(Fcb->Resource);
+ FsRtlExitFileSystem();
+
+ return FALSE;
+ }
+ }
+
+ /* If we write beyond EOF, then, save previous sizes (in case of failure)
+ * and update file size, to allow writing
+ */
+ if (LastOffset.LowPart > Fcb->FileSize.LowPart)
+ {
+ FileSizeChanged = TRUE;
+ InitialFileSize.LowPart = Fcb->FileSize.LowPart;
+ InitialValidDataLength.LowPart = Fcb->ValidDataLength.LowPart;
+ Fcb->FileSize.LowPart = LastOffset.LowPart;
+ }
+
+ /* Set caller provided context as top level IRP */
+ IoSetTopLevelIrp(TopLevelContext);
+
+ Ret = TRUE;
+
+ /* And perform the writing */
+ _SEH2_TRY
+ {
+ /* Check whether we've to create a hole first -
+ * it cannot fail, we can wait
+ */
+ if (LastOffset.LowPart > Fcb->ValidDataLength.LowPart)
+ {
+ CcZeroData(FileObject, &Fcb->ValidDataLength, &WriteOffset,
TRUE);
+ }
+
+ /* Write data */
+ CcFastCopyWrite(FileObject, WriteOffset.LowPart, Length, Buffer);
+ }
+ _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH)
+ {
+ Ret = FALSE;
+ }
+ _SEH2_END;
+
+ /* Restore top level IRP */
+ IoSetTopLevelIrp(NULL);
+
+ /* If writing succeed */
+ if (Ret)
+ {
+ /* If we wrote beyond VDL, update it */
+ if (LastOffset.LowPart > Fcb->ValidDataLength.LowPart)
+ {
+ Fcb->ValidDataLength.LowPart = LastOffset.LowPart;
+ }
+
+ /* File was obviously modified */
+ SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
+
+ /* And if we increased it, modify size in Cc and update FO */
+ if (FileSizeChanged)
+ {
+ (*CcGetFileSizePointer(FileObject)).LowPart = LastOffset.LowPart;
+ SetFlag(FileObject->Flags, FO_FILE_SIZE_CHANGED);
+ }
+
+ /* Update offset - we're still below 4GB, so high part must be 0 */
+ FileObject->CurrentByteOffset.LowPart = WriteOffset.LowPart + Length;
+ FileObject->CurrentByteOffset.HighPart = 0;
+ }
+ else
+ {
+ /* We failed, we need to restore previous sizes */
+ if (FileSizeChanged)
+ {
+ if (Fcb->PagingIoResource != NULL)
+ {
+ ExAcquireResourceExclusiveLite(Fcb->PagingIoResource, TRUE);
+ Fcb->FileSize.LowPart = InitialFileSize.LowPart;
+ Fcb->ValidDataLength.LowPart = InitialValidDataLength.LowPart;
+ ExReleaseResourceLite(Fcb->PagingIoResource);
+ }
+ else
+ {
+ Fcb->FileSize.LowPart = InitialFileSize.LowPart;
+ Fcb->ValidDataLength.LowPart = InitialValidDataLength.LowPart;
+ }
+ }
+ }
+ }
+
+ /* Release our resource and leave */
+ ExReleaseResourceLite(Fcb->Resource);
+
+ FsRtlExitFileSystem();
+
+ return Ret;
+}
Modified: trunk/reactos/sdk/lib/drivers/copysup/copysup.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/copysup/co…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/copysup/copysup.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/copysup/copysup.h [iso-8859-1] Wed Jul 26 09:28:41 2017
@@ -15,4 +15,16 @@
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PVOID TopLevelContext);
+BOOLEAN
+FsRtlCopyWrite2(
+ _In_ PFILE_OBJECT FileObject,
+ _In_ PLARGE_INTEGER FileOffset,
+ _In_ ULONG Length,
+ _In_ BOOLEAN Wait,
+ _In_ ULONG LockKey,
+ _In_ PVOID Buffer,
+ _Out_ PIO_STATUS_BLOCK IoStatus,
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PVOID TopLevelContext);
+
#endif
Modified: trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/rdbsslib/r…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/rdbsslib/rdbss.c [iso-8859-1] Wed Jul 26 09:28:41 2017
@@ -5364,6 +5364,9 @@
PAGED_CODE();
}
+/*
+ * @implemented
+ */
BOOLEAN
NTAPI
RxFastIoCheckIfPossible(
@@ -5376,6 +5379,7 @@
{
PFCB Fcb;
PSRV_OPEN SrvOpen;
+ LARGE_INTEGER LargeLength;
PAGED_CODE();
@@ -5436,11 +5440,11 @@
RxProcessChangeBufferingStateRequestsForSrvOpen(SrvOpen);
FsRtlExitFileSystem();
+ LargeLength.QuadPart = Length;
+
/* If operation to come is a read operation */
if (CheckForReadOperation)
{
- LARGE_INTEGER LargeLength;
-
/* Check that read cache is enabled */
if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_READCACHING_ENABLED))
{
@@ -5449,7 +5453,6 @@
}
/* Check whether there's a lock conflict */
- LargeLength.QuadPart = Length;
if (!FsRtlFastCheckLockForRead(&Fcb->Specific.Fcb.FileLock,
FileOffset,
&LargeLength,
@@ -5464,8 +5467,26 @@
return TRUE;
}
- UNIMPLEMENTED;
- return FALSE;
+ /* Check that write cache is enabled */
+ if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_WRITECACHING_ENABLED))
+ {
+ DPRINT1("Write caching disabled\n");
+ return FALSE;
+ }
+
+ /* Check whether there's a lock conflict */
+ if (!FsRtlFastCheckLockForWrite(&Fcb->Specific.Fcb.FileLock,
+ FileOffset,
+ &LargeLength,
+ LockKey,
+ FileObject,
+ PsGetCurrentProcess()))
+ {
+ DPRINT1("FsRtlFastCheckLockForWrite failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
}
BOOLEAN
@@ -5536,6 +5557,9 @@
return Ret;
}
+/*
+ * @implemented
+ */
BOOLEAN
NTAPI
RxFastIoWrite(
@@ -5548,8 +5572,39 @@
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
- UNIMPLEMENTED;
- return FALSE;
+ PFOBX Fobx;
+ BOOLEAN Ret;
+ RX_TOPLEVELIRP_CONTEXT TopLevelContext;
+
+ PAGED_CODE();
+
+ Fobx = (PFOBX)FileObject->FsContext2;
+ if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_BAD_HANDLE))
+ {
+ return FALSE;
+ }
+
+ DPRINT("RxFastIoWrite: %p (%p, %p)\n", FileObject,
FileObject->FsContext,
+ FileObject->FsContext2);
+ DPRINT("Writing %ld at %I64x\n", Length, FileOffset->QuadPart);
+
+ /* Prepare a TLI context */
+ ASSERT(RxIsThisTheTopLevelIrp(NULL));
+ RxInitializeTopLevelIrpContext(&TopLevelContext,
(PIRP)FSRTL_FAST_IO_TOP_LEVEL_IRP,
+ (PRDBSS_DEVICE_OBJECT)DeviceObject);
+
+ Ret = FsRtlCopyWrite2(FileObject, FileOffset, Length, Wait, LockKey, Buffer,
+ IoStatus, DeviceObject, &TopLevelContext);
+ if (Ret)
+ {
+ DPRINT("Write OK\n");
+ }
+ else
+ {
+ DPRINT1("Write failed!\n");
+ }
+
+ return Ret;
}
NTSTATUS