2 * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3 * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
6 * PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
11 /* INCLUDES *****************************************************************/
15 /* GLOBALS ***************************************************************/
17 extern PRFSD_GLOBAL RfsdGlobal
;
19 /* DEFINITIONS *************************************************************/
22 RfsdReadComplete (IN PRFSD_IRP_CONTEXT IrpContext
);
25 RfsdReadFile (IN PRFSD_IRP_CONTEXT IrpContext
);
28 RfsdReadVolume (IN PRFSD_IRP_CONTEXT IrpContext
);
31 #pragma alloc_text(PAGE, RfsdCompleteIrpContext)
32 #pragma alloc_text(PAGE, RfsdCopyRead)
33 #pragma alloc_text(PAGE, RfsdRead)
34 #pragma alloc_text(PAGE, RfsdReadVolume)
35 #pragma alloc_text(PAGE, RfsdReadInode)
36 #pragma alloc_text(PAGE, RfsdReadFile)
37 #pragma alloc_text(PAGE, RfsdReadComplete)
40 /* FUNCTIONS *************************************************************/
42 /** Proxy to CcCopyRead, which simply asserts the success of the IoStatus. */
45 IN PFILE_OBJECT FileObject
,
46 IN PLARGE_INTEGER FileOffset
,
50 OUT PIO_STATUS_BLOCK IoStatus
57 bRet
= CcCopyRead(FileObject
,
65 ASSERT(NT_SUCCESS(IoStatus
->Status
));
73 if (CcMapData( FileObject,
79 RtlCopyMemory(Buffer, Buf, Length);
80 IoStatus->Status = STATUS_SUCCESS;
81 IoStatus->Information = Length;
86 // IoStatus->Status = STATUS_
92 __drv_mustHoldCriticalRegion
94 RfsdReadVolume (IN PRFSD_IRP_CONTEXT IrpContext
)
96 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
100 PRFSD_FCBVCB FcbOrVcb
;
101 PFILE_OBJECT FileObject
;
103 PDEVICE_OBJECT DeviceObject
;
106 PIO_STACK_LOCATION IoStackLocation
;
109 LARGE_INTEGER ByteOffset
;
113 BOOLEAN SynchronousIo
;
114 BOOLEAN MainResourceAcquired
= FALSE
;
115 BOOLEAN PagingIoResourceAcquired
= FALSE
;
117 PUCHAR Buffer
= NULL
;
118 PRFSD_BDL rfsd_bdl
= NULL
;
126 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
127 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
129 DeviceObject
= IrpContext
->DeviceObject
;
131 Vcb
= (PRFSD_VCB
) DeviceObject
->DeviceExtension
;
135 ASSERT((Vcb
->Identifier
.Type
== RFSDVCB
) &&
136 (Vcb
->Identifier
.Size
== sizeof(RFSD_VCB
)));
138 FileObject
= IrpContext
->FileObject
;
140 FcbOrVcb
= (PRFSD_FCBVCB
) FileObject
->FsContext
;
144 if (!(FcbOrVcb
->Identifier
.Type
== RFSDVCB
&& (PVOID
)FcbOrVcb
== (PVOID
)Vcb
)) {
146 Status
= STATUS_INVALID_DEVICE_REQUEST
;
150 Ccb
= (PRFSD_CCB
) FileObject
->FsContext2
;
152 Irp
= IrpContext
->Irp
;
154 Irp
->IoStatus
.Information
= 0;
156 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
158 Length
= IoStackLocation
->Parameters
.Read
.Length
;
159 ByteOffset
= IoStackLocation
->Parameters
.Read
.ByteOffset
;
161 PagingIo
= (Irp
->Flags
& IRP_PAGING_IO
? TRUE
: FALSE
);
162 Nocache
= (Irp
->Flags
& IRP_NOCACHE
? TRUE
: FALSE
);
163 SynchronousIo
= (FileObject
->Flags
& FO_SYNCHRONOUS_IO
? TRUE
: FALSE
);
167 Irp
->IoStatus
.Information
= 0;
168 Status
= STATUS_SUCCESS
;
174 if(!IsFlagOn(Ccb
->Flags
, CCB_ALLOW_EXTENDED_DASD_IO
)) {
175 if (ByteOffset
.QuadPart
+ Length
> Vcb
->Header
.FileSize
.QuadPart
) {
176 Length
= (ULONG
)(Vcb
->Header
.FileSize
.QuadPart
- ByteOffset
.QuadPart
);
183 if ((ByteOffset
.LowPart
& (SECTOR_SIZE
- 1)) ||
184 (Length
& (SECTOR_SIZE
- 1)) ) {
185 Status
= STATUS_INVALID_PARAMETER
;
189 Status
= RfsdLockUserBuffer(
194 if (!NT_SUCCESS(Status
)) {
198 BlockArray
.Irp
= NULL
;
199 BlockArray
.Lba
= ByteOffset
.QuadPart
;;
200 BlockArray
.Offset
= 0;
201 BlockArray
.Length
= Length
;
203 Status
= RfsdReadWriteBlocks(IrpContext
,
209 Irp
= IrpContext
->Irp
;
216 ( (ByteOffset
.LowPart
& (SECTOR_SIZE
- 1)) ||
217 (Length
& (SECTOR_SIZE
- 1)) )) {
220 Status
= STATUS_INVALID_PARAMETER
;
224 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_DPC
)) {
225 ClearFlag(IrpContext
->MinorFunction
, IRP_MN_DPC
);
226 Status
= STATUS_PENDING
;
231 if (!ExAcquireResourceSharedLite(
233 IrpContext
->IsSynchronous
)) {
234 Status
= STATUS_PENDING
;
238 MainResourceAcquired
= TRUE
;
242 if (!ExAcquireResourceSharedLite(
243 &Vcb
->PagingIoResource
,
244 IrpContext
->IsSynchronous
))
246 Status
= STATUS_PENDING
;
250 PagingIoResourceAcquired
= TRUE
;
254 if (ByteOffset
.QuadPart
>=
255 Vcb
->PartitionInformation
.PartitionLength
.QuadPart
) {
256 Irp
->IoStatus
.Information
= 0;
257 Status
= STATUS_END_OF_FILE
;
263 if ((ByteOffset
.QuadPart
+ Length
) >
264 Vcb
->PartitionInformation
.PartitionLength
.QuadPart
){
266 Vcb
->PartitionInformation
.PartitionLength
.QuadPart
-
267 ByteOffset
.QuadPart
);
268 Length
&= ~((ULONG
)SECTOR_SIZE
- 1);
271 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_MDL
)) {
280 Status
= Irp
->IoStatus
.Status
;
284 Buffer
= RfsdGetUserBuffer(Irp
);
286 if (Buffer
== NULL
) {
288 Status
= STATUS_INVALID_USER_BUFFER
;
294 (PLARGE_INTEGER
)&ByteOffset
,
296 IrpContext
->IsSynchronous
,
299 Status
= STATUS_PENDING
;
303 Status
= Irp
->IoStatus
.Status
;
308 if ((ByteOffset
.QuadPart
+ Length
) >
309 Vcb
->PartitionInformation
.PartitionLength
.QuadPart
) {
311 Vcb
->PartitionInformation
.PartitionLength
.QuadPart
-
312 ByteOffset
.QuadPart
);
314 Length
&= ~((ULONG
)SECTOR_SIZE
- 1);
317 Status
= RfsdLockUserBuffer(
322 if (!NT_SUCCESS(Status
)) {
327 Buffer
= RfsdGetUserBuffer(Irp
);
329 rfsd_bdl
= ExAllocatePoolWithTag(PagedPool
, sizeof(RFSD_BDL
), RFSD_POOL_TAG
);
333 Status
= STATUS_INSUFFICIENT_RESOURCES
;
337 rfsd_bdl
->Irp
= NULL
;
338 rfsd_bdl
->Lba
= ByteOffset
.QuadPart
;
339 rfsd_bdl
->Length
= Length
;
340 rfsd_bdl
->Offset
= 0;
342 Status
= RfsdReadWriteBlocks(IrpContext
,
349 Irp
= IrpContext
->Irp
;
357 if (PagingIoResourceAcquired
) {
358 ExReleaseResourceForThreadLite(
359 &Vcb
->PagingIoResource
,
360 ExGetCurrentResourceThread());
363 if (MainResourceAcquired
) {
364 ExReleaseResourceForThreadLite(
366 ExGetCurrentResourceThread());
370 ExFreePool(rfsd_bdl
);
372 if (!IrpContext
->ExceptionInProgress
) {
374 if (IrpContext
->Irp
) {
376 if (Status
== STATUS_PENDING
&&
377 !IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_REQUEUED
)) {
379 Status
= RfsdLockUserBuffer(
384 if (NT_SUCCESS(Status
)) {
385 Status
= RfsdQueueRequest(IrpContext
);
387 RfsdCompleteIrpContext(IrpContext
, Status
);
392 if (NT_SUCCESS(Status
)) {
398 IrpContext
->FileObject
->CurrentByteOffset
.QuadPart
=
399 ByteOffset
.QuadPart
+ IrpContext
->Irp
->IoStatus
.Information
;
402 IrpContext
->FileObject
->Flags
|= FO_FILE_FAST_IO_READ
;
406 RfsdCompleteIrpContext(IrpContext
, Status
);;
410 RfsdFreeIrpContext(IrpContext
);
418 // [mark] read some goop [from the file pt'd to by inode -- from whatever blocks buildbdl makes] into the buffer
421 IN PRFSD_IRP_CONTEXT IrpContext
, // [may be null]
423 IN PRFSD_KEY_IN_MEMORY Key
, // Key that identifies the data on disk to be read. This is simply forwarded through to BuildBDL. (NOTE: IN THIS CASE, THE OFFSET AND TYPE FIELDS MATTER)
424 IN PRFSD_INODE Inode
, // a filled Inode / stat data structure
425 IN ULONGLONG Offset
, // User's requested offset to read within the file (relative to the file)
426 IN OUT PVOID Buffer
, // buffer to read out to
427 IN ULONG Size
, // size of destination buffer
428 OUT PULONG dwRet
) // some kind of size [probably bytes read?]
430 PRFSD_BDL Bdl
= NULL
;
432 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
433 IO_STATUS_BLOCK IoStatus
;
445 // Calculate the inode size
448 FileSize
= (ULONGLONG
) Inode
->i_size
;
450 //KdPrint(("Rfsd: RfsdReadInode: file size = %I64u, offset = %I64u, length = %u\n", FileSize, Offset, Size));
452 // TODO: temporary hack to get correct alloc size for dir tails... but i doubt 8 works in all cases :-) [what i should really be using is the size of the direct item in the block header!]
453 // AllocSize = CEILING_ALIGNED(FileSize, (ULONGLONG)Vcb->BlockSize);
454 // AllocSize = CEILING_ALIGNED(FileSize, (ULONGLONG) 8);
455 AllocSize
= CEILING_ALIGNED(FileSize
, (ULONGLONG
) 1); // temp hack to ensure that i'll read out EXACTLY the # of bytes he requested
458 // Check inputed parameters: Offset / Size
461 if (Offset
>= AllocSize
) {
463 RfsdPrint((DBG_ERROR
, "RfsdReadInode: beyond the file range.\n"));
464 return STATUS_SUCCESS
;
467 if (Offset
+ Size
> AllocSize
) {
469 Size
= (ULONG
)(AllocSize
- Offset
);
473 //-----------------------------
476 // Build the scatterred block ranges to be read
479 Status
= RfsdBuildBDL2(
484 if (!NT_SUCCESS(Status
)) {
489 Status
= STATUS_SUCCESS
;
495 ULONGLONG bufferPos
= 0;
497 for(i
= 0, j
= 0; i
< blocks
; i
++) {
498 if ( // The block is needed for the user's requested contents
499 // (The user's requested offset lies within the block, or the block's start is within the user's requested range)
500 ( (Offset
>= Bdl
[i
].Offset
) && (Offset
< (Bdl
[i
].Offset
+ Bdl
[i
].Length
)) ) || // The user's offset is within the block's range
501 ( (Bdl
[i
].Offset
>= Offset
) && (Bdl
[i
].Offset
< (Offset
+ Size
)) ) // The block's offset is within the user's range
504 ULONGLONG offsetFromDisk
= Bdl
[i
].Lba
;
505 ULONGLONG lengthToRead
= min(Size
- bufferPos
, Bdl
[i
].Length
);
508 //KdPrint(("Rfsd: blocks = %u, i = %u, j = %u\n", blocks, i, j));
509 //KdPrint(("Rfsd: Bdl[%u].Lba = %I64u, Bdl[%u].Offset = %I64u, Bdl[%u].Length = %u\n", i, Bdl[i].Lba, i, Bdl[i].Offset, i, Bdl[i].Length));
510 //KdPrint(("Rfsd: offsetFromDisk = %I64u, lengthToRead = %I64u\n", offsetFromDisk, lengthToRead));
511 //KdPrint(("Rfsd: Buffer = %p, bufferPos = %I64u\n", Buffer, bufferPos));
513 IoStatus
.Information
= 0;
517 (PLARGE_INTEGER
) (&offsetFromDisk
), // offset (relative to partition)
518 (ULONG
) lengthToRead
, // length to read
520 (PVOID
)((PUCHAR
)Buffer
+ bufferPos
), // buffer to read into
523 Status
= IoStatus
.Status
;
524 bufferPos
+= IoStatus
.Information
;
525 //KdPrint(("Rfsd: IoStatus.Status = %#x, IoStatus.Information = %u\n", IoStatus.Status, IoStatus.Information));
533 if (Bdl
) ExFreePool(Bdl
);
535 if (NT_SUCCESS(Status
)) {
537 if (dwRet
) *dwRet
= Size
;
543 __drv_mustHoldCriticalRegion
545 RfsdReadFile(IN PRFSD_IRP_CONTEXT IrpContext
)
547 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
552 PFILE_OBJECT FileObject
;
553 PFILE_OBJECT CacheObject
;
555 PDEVICE_OBJECT DeviceObject
;
558 PIO_STACK_LOCATION IoStackLocation
;
561 ULONG ReturnedLength
;
562 LARGE_INTEGER ByteOffset
;
566 BOOLEAN SynchronousIo
;
567 BOOLEAN MainResourceAcquired
= FALSE
;
568 BOOLEAN PagingIoResourceAcquired
= FALSE
;
578 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
579 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
581 DeviceObject
= IrpContext
->DeviceObject
;
583 Vcb
= (PRFSD_VCB
) DeviceObject
->DeviceExtension
;
587 ASSERT((Vcb
->Identifier
.Type
== RFSDVCB
) &&
588 (Vcb
->Identifier
.Size
== sizeof(RFSD_VCB
)));
590 FileObject
= IrpContext
->FileObject
;
592 Fcb
= (PRFSD_FCB
) FileObject
->FsContext
;
596 ASSERT((Fcb
->Identifier
.Type
== RFSDFCB
) &&
597 (Fcb
->Identifier
.Size
== sizeof(RFSD_FCB
)));
599 Ccb
= (PRFSD_CCB
) FileObject
->FsContext2
;
601 Irp
= IrpContext
->Irp
;
603 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
605 Length
= IoStackLocation
->Parameters
.Read
.Length
;
606 ByteOffset
= IoStackLocation
->Parameters
.Read
.ByteOffset
;
609 KdPrint(("$$$ " __FUNCTION__
" on key: %x,%xh to read %i bytes at the offset %xh in the file\n",
610 Fcb
->RfsdMcb
->Key
.k_dir_id
, Fcb
->RfsdMcb
->Key
.k_objectid
,
611 Length
, ByteOffset
.QuadPart
));
614 PagingIo
= (Irp
->Flags
& IRP_PAGING_IO
? TRUE
: FALSE
);
615 Nocache
= (Irp
->Flags
& IRP_NOCACHE
? TRUE
: FALSE
);
616 SynchronousIo
= (FileObject
->Flags
& FO_SYNCHRONOUS_IO
? TRUE
: FALSE
);
619 if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) {
620 Status = STATUS_FILE_DELETED;
624 if (IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING)) {
625 Status = STATUS_DELETE_PENDING;
631 Irp
->IoStatus
.Information
= 0;
632 Status
= STATUS_SUCCESS
;
637 (ByteOffset
.LowPart
& (SECTOR_SIZE
- 1) ||
638 Length
& (SECTOR_SIZE
- 1))) {
639 Status
= STATUS_INVALID_PARAMETER
;
644 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_DPC
)) {
645 ClearFlag(IrpContext
->MinorFunction
, IRP_MN_DPC
);
646 Status
= STATUS_PENDING
;
652 if (!ExAcquireResourceSharedLite(
654 IrpContext
->IsSynchronous
)) {
655 Status
= STATUS_PENDING
;
659 MainResourceAcquired
= TRUE
;
661 if (!FsRtlCheckLockForReadAccess(
662 &Fcb
->FileLockAnchor
,
664 Status
= STATUS_FILE_LOCK_CONFLICT
;
668 if (!ExAcquireResourceSharedLite(
669 &Fcb
->PagingIoResource
,
670 IrpContext
->IsSynchronous
)) {
671 Status
= STATUS_PENDING
;
675 PagingIoResourceAcquired
= TRUE
;
679 // Attempt cached access...
681 if ((ByteOffset
.QuadPart
+ (LONGLONG
)Length
) >
682 Fcb
->Header
.FileSize
.QuadPart
) {
683 if (ByteOffset
.QuadPart
>= (Fcb
->Header
.FileSize
.QuadPart
)) {
684 Irp
->IoStatus
.Information
= 0;
685 Status
= STATUS_END_OF_FILE
;
690 (ULONG
)(Fcb
->Header
.FileSize
.QuadPart
- ByteOffset
.QuadPart
);
694 ReturnedLength
= Length
;
696 if (IsDirectory(Fcb
)) {
701 if (FileObject
->PrivateCacheMap
== NULL
) {
702 CcInitializeCacheMap(
704 (PCC_FILE_SIZES
)(&Fcb
->Header
.AllocationSize
),
706 &RfsdGlobal
->CacheManagerCallbacks
,
710 CacheObject
= FileObject
;
713 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_MDL
)) {
721 Status
= Irp
->IoStatus
.Status
;
724 Buffer
= RfsdGetUserBuffer(Irp
);
726 if (Buffer
== NULL
) {
727 Status
= STATUS_INVALID_USER_BUFFER
;
733 CacheObject
, // the file object (representing the open operation performed by the thread)
734 (PLARGE_INTEGER
)&ByteOffset
, // starting offset IN THE FILE, from where the read should be performed
735 Length
, // number of bytes requested in the read operation
736 IrpContext
->IsSynchronous
,
737 Buffer
, // < buffer to read the contents to
739 Status
= STATUS_PENDING
;
744 Status
= Irp
->IoStatus
.Status
;
748 // Attempt access without the cache...
750 if ((ByteOffset
.QuadPart
+ (LONGLONG
)Length
) > Fcb
->Header
.AllocationSize
.QuadPart
) {
752 if (ByteOffset
.QuadPart
>= Fcb
->Header
.AllocationSize
.QuadPart
) {
753 Irp
->IoStatus
.Information
= 0;
754 Status
= STATUS_END_OF_FILE
;
760 (ULONG
)(Fcb
->Header
.AllocationSize
.QuadPart
- ByteOffset
.QuadPart
);
763 ReturnedLength
= Length
;
765 /* lock the user buffer into MDL and make them paged-in */
766 Status
= RfsdLockUserBuffer(
771 if (NT_SUCCESS(Status
)) {
773 /* Zero the total buffer */
774 PVOID SystemVA
= RfsdGetUserBuffer(IrpContext
->Irp
);
777 RtlZeroMemory(SystemVA
, Length
);
779 RfsdPrint((DBG_INFO
, "RfsdReadFile: Zero read buffer: Offset=%I64xh Size=%xh ... \n",
780 ByteOffset
.QuadPart
, Length
));
787 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
788 Irp
->IoStatus
.Information
= Length
;
791 Status
= RfsdReadInode(
794 &(Fcb
->RfsdMcb
->Key
),
797 RfsdGetUserBuffer(IrpContext
->Irp
), // NOTE: Ext2fsd just passes NULL for the buffer, and relies on the initial cache call to retrieve tha data. We'll instead be explicitly putting it into the user's buffer, via a much different mechanism.
801 Irp
= IrpContext
->Irp
;
807 if (PagingIoResourceAcquired
) {
808 ExReleaseResourceForThreadLite(
809 &Fcb
->PagingIoResource
,
810 ExGetCurrentResourceThread());
813 if (MainResourceAcquired
) {
814 ExReleaseResourceForThreadLite(
816 ExGetCurrentResourceThread());
819 if (!IrpContext
->ExceptionInProgress
) {
820 if (IrpContext
->Irp
) {
821 if (Status
== STATUS_PENDING
) {
823 Status
= RfsdLockUserBuffer(
828 if (NT_SUCCESS(Status
)) {
829 Status
= RfsdQueueRequest(IrpContext
);
831 RfsdCompleteIrpContext(IrpContext
, Status
);
834 if (NT_SUCCESS(Status
)) {
837 IrpContext
->FileObject
->CurrentByteOffset
.QuadPart
=
838 ByteOffset
.QuadPart
+ IrpContext
->Irp
->IoStatus
.Information
;
841 IrpContext
->FileObject
->Flags
|= FO_FILE_FAST_IO_READ
;
845 RfsdCompleteIrpContext(IrpContext
, Status
);
848 RfsdFreeIrpContext(IrpContext
);
857 RfsdReadComplete (IN PRFSD_IRP_CONTEXT IrpContext
)
859 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
860 PFILE_OBJECT FileObject
;
869 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
870 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
872 FileObject
= IrpContext
->FileObject
;
874 Irp
= IrpContext
->Irp
;
876 CcMdlReadComplete(FileObject
, Irp
->MdlAddress
);
878 Irp
->MdlAddress
= NULL
;
880 Status
= STATUS_SUCCESS
;
884 if (!IrpContext
->ExceptionInProgress
) {
885 RfsdCompleteIrpContext(IrpContext
, Status
);
892 __drv_mustHoldCriticalRegion
894 RfsdRead (IN PRFSD_IRP_CONTEXT IrpContext
)
898 PRFSD_FCBVCB FcbOrVcb
;
899 PDEVICE_OBJECT DeviceObject
;
900 PFILE_OBJECT FileObject
;
901 BOOLEAN bCompleteRequest
;
907 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
908 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
912 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_COMPLETE
)) {
913 // Caller wants to tell the Cache Manager that a previously allocated MDL can be freed.
914 Status
= RfsdReadComplete(IrpContext
);
915 bCompleteRequest
= FALSE
;
919 DeviceObject
= IrpContext
->DeviceObject
;
921 if (DeviceObject
== RfsdGlobal
->DeviceObject
) {
922 Status
= STATUS_INVALID_DEVICE_REQUEST
;
923 bCompleteRequest
= TRUE
;
927 Vcb
= (PRFSD_VCB
) DeviceObject
->DeviceExtension
;
929 if (Vcb
->Identifier
.Type
!= RFSDVCB
||
930 Vcb
->Identifier
.Size
!= sizeof(RFSD_VCB
) ) {
931 Status
= STATUS_INVALID_DEVICE_REQUEST
;
932 bCompleteRequest
= TRUE
;
937 if (IsFlagOn(Vcb
->Flags
, VCB_DISMOUNT_PENDING
)) {
939 Status
= STATUS_TOO_LATE
;
940 bCompleteRequest
= TRUE
;
944 FileObject
= IrpContext
->FileObject
;
946 FcbOrVcb
= (PRFSD_FCBVCB
) FileObject
->FsContext
;
948 if (FcbOrVcb
->Identifier
.Type
== RFSDVCB
) {
949 Status
= RfsdReadVolume(IrpContext
);
950 bCompleteRequest
= FALSE
;
951 } else if (FcbOrVcb
->Identifier
.Type
== RFSDFCB
) {
952 Status
= RfsdReadFile(IrpContext
);
953 bCompleteRequest
= FALSE
;
955 RfsdPrint((DBG_ERROR
, "RfsdRead: INVALID PARAMETER ... \n"));
958 Status
= STATUS_INVALID_PARAMETER
;
959 bCompleteRequest
= TRUE
;
964 if (bCompleteRequest
) {
965 RfsdCompleteIrpContext(IrpContext
, Status
);