2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
10 /* INCLUDES *****************************************************************/
14 /* GLOBALS ***************************************************************/
16 extern PEXT2_GLOBAL Ext2Global
;
18 /* DEFINITIONS *************************************************************/
21 Ext2ReadComplete (IN PEXT2_IRP_CONTEXT IrpContext
);
24 Ext2ReadFile (IN PEXT2_IRP_CONTEXT IrpContext
);
27 Ext2ReadVolume (IN PEXT2_IRP_CONTEXT IrpContext
);
29 /* FUNCTIONS *************************************************************/
32 Ext2CompleteIrpContext (
33 IN PEXT2_IRP_CONTEXT IrpContext
,
39 Irp
= IrpContext
->Irp
;
43 if (NT_ERROR(Status
)) {
44 Irp
->IoStatus
.Information
= 0;
47 Irp
->IoStatus
.Status
= Status
;
48 bPrint
= !IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_REQUEUED
);
51 Irp
, bPrint
, (CCHAR
)(NT_SUCCESS(Status
)?
52 IO_DISK_INCREMENT
: IO_NO_INCREMENT
) );
54 IrpContext
->Irp
= NULL
;
57 Ext2FreeIrpContext(IrpContext
);
64 Ext2ReadVolume (IN PEXT2_IRP_CONTEXT IrpContext
)
66 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
70 PEXT2_FCBVCB FcbOrVcb
= NULL
;
71 PFILE_OBJECT FileObject
= NULL
;
73 PDEVICE_OBJECT DeviceObject
= NULL
;
76 PIO_STACK_LOCATION IoStackLocation
= NULL
;
79 LARGE_INTEGER ByteOffset
;
83 BOOLEAN SynchronousIo
;
84 BOOLEAN MainResourceAcquired
= FALSE
;
87 EXT2_EXTENT BlockArray
;
92 ASSERT((IrpContext
->Identifier
.Type
== EXT2ICX
) &&
93 (IrpContext
->Identifier
.Size
== sizeof(EXT2_IRP_CONTEXT
)));
95 DeviceObject
= IrpContext
->DeviceObject
;
96 Vcb
= (PEXT2_VCB
) DeviceObject
->DeviceExtension
;
98 ASSERT((Vcb
->Identifier
.Type
== EXT2VCB
) &&
99 (Vcb
->Identifier
.Size
== sizeof(EXT2_VCB
)));
101 FileObject
= IrpContext
->FileObject
;
102 FcbOrVcb
= (PEXT2_FCBVCB
) FileObject
->FsContext
;
105 if (!(FcbOrVcb
->Identifier
.Type
== EXT2VCB
&& (PVOID
)FcbOrVcb
== (PVOID
)Vcb
)) {
107 Status
= STATUS_INVALID_DEVICE_REQUEST
;
111 Ccb
= (PEXT2_CCB
) FileObject
->FsContext2
;
112 Irp
= IrpContext
->Irp
;
113 Irp
->IoStatus
.Information
= 0;
114 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
116 Length
= IoStackLocation
->Parameters
.Read
.Length
;
117 ByteOffset
= IoStackLocation
->Parameters
.Read
.ByteOffset
;
119 PagingIo
= IsFlagOn(Irp
->Flags
, IRP_PAGING_IO
);
120 Nocache
= IsFlagOn(Irp
->Flags
, IRP_NOCACHE
) || (Ccb
!= NULL
);
121 SynchronousIo
= IsFlagOn(FileObject
->Flags
, FO_SYNCHRONOUS_IO
);
128 Irp
->IoStatus
.Information
= 0;
129 Status
= STATUS_SUCCESS
;
133 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_DPC
)) {
134 ClearFlag(IrpContext
->MinorFunction
, IRP_MN_DPC
);
135 Status
= STATUS_PENDING
;
139 if (ByteOffset
.QuadPart
>=
140 Vcb
->PartitionInformation
.PartitionLength
.QuadPart
) {
141 Irp
->IoStatus
.Information
= 0;
142 Status
= STATUS_END_OF_FILE
;
146 if (ByteOffset
.QuadPart
+ Length
> Vcb
->Header
.FileSize
.QuadPart
) {
147 Length
= (ULONG
)(Vcb
->Header
.FileSize
.QuadPart
- ByteOffset
.QuadPart
);
151 * User direct volume access
154 if (Ccb
!= NULL
&& !PagingIo
) {
156 if (!ExAcquireResourceExclusiveLite(
158 IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_WAIT
) )) {
159 Status
= STATUS_PENDING
;
162 MainResourceAcquired
= TRUE
;
164 if (!FlagOn(Ccb
->Flags
, CCB_VOLUME_DASD_PURGE
)) {
166 if (!FlagOn(Vcb
->Flags
, VCB_VOLUME_LOCKED
)) {
167 Ext2FlushVolume(IrpContext
, Vcb
, FALSE
);
170 SetFlag(Ccb
->Flags
, CCB_VOLUME_DASD_PURGE
);
173 ExReleaseResourceLite(&Vcb
->MainResource
);
174 MainResourceAcquired
= FALSE
;
176 /* will do Nocache i/o */
180 * I/O to volume StreamObject
185 if (IsFlagOn(IrpContext
->MinorFunction
, IRP_MN_MDL
)) {
194 Status
= Irp
->IoStatus
.Status
;
198 Buffer
= Ext2GetUserBuffer(Irp
);
199 if (Buffer
== NULL
) {
201 Status
= STATUS_INVALID_USER_BUFFER
;
212 Status
= STATUS_PENDING
;
216 Status
= Irp
->IoStatus
.Status
;
221 Length
&= ~((ULONG
)SECTOR_SIZE
- 1);
222 Status
= Ext2LockUserBuffer(
227 if (!NT_SUCCESS(Status
)) {
231 BlockArray
.Irp
= NULL
;
232 BlockArray
.Lba
= ByteOffset
.QuadPart
;
233 BlockArray
.Offset
= 0;
234 BlockArray
.Length
= Length
;
235 BlockArray
.Next
= NULL
;
237 Status
= Ext2ReadWriteBlocks(IrpContext
,
242 Irp
= IrpContext
->Irp
;
250 if (MainResourceAcquired
) {
251 ExReleaseResourceLite(&Vcb
->MainResource
);
254 if (!IrpContext
->ExceptionInProgress
) {
258 if (Status
== STATUS_PENDING
&&
259 !IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_REQUEUED
)) {
261 Status
= Ext2LockUserBuffer(
266 if (NT_SUCCESS(Status
)) {
267 Status
= Ext2QueueRequest(IrpContext
);
269 Ext2CompleteIrpContext(IrpContext
, Status
);
274 if (NT_SUCCESS(Status
)) {
280 FileObject
->CurrentByteOffset
.QuadPart
=
281 ByteOffset
.QuadPart
+ Irp
->IoStatus
.Information
;
284 FileObject
->Flags
|= FO_FILE_FAST_IO_READ
;
288 Ext2CompleteIrpContext(IrpContext
, Status
);;
292 Ext2FreeIrpContext(IrpContext
);
301 #define SafeZeroMemory(AT,BYTE_COUNT) { \
304 RtlZeroMemory((AT), (BYTE_COUNT)); \
305 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \
306 Ext2RaiseStatus( IrpContext, STATUS_INVALID_USER_BUFFER ); \
312 IN PEXT2_IRP_CONTEXT IrpContext
,
318 IN BOOLEAN bDirectIo
,
322 PEXT2_EXTENT Chain
= NULL
;
323 PEXT2_EXTENT Extent
= NULL
, Prev
= NULL
;
325 IO_STATUS_BLOCK IoStatus
;
326 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
337 ASSERT((Mcb
->Identifier
.Type
== EXT2MCB
) &&
338 (Mcb
->Identifier
.Size
== sizeof(EXT2_MCB
)));
340 if ((Mcb
->Identifier
.Type
!= EXT2MCB
) ||
341 (Mcb
->Identifier
.Size
!= sizeof(EXT2_MCB
))) {
345 if (Buffer
== NULL
&& IrpContext
!= NULL
)
346 Buffer
= Ext2GetUserBuffer(IrpContext
->Irp
);
349 /* handle fast symlinks */
350 if (S_ISLNK(Mcb
->Inode
.i_mode
) && 0 == Mcb
->Inode
.i_blocks
) {
352 PUCHAR Data
= (PUCHAR
) (&Mcb
->Inode
.i_block
[0]);
354 Status
= STATUS_INSUFFICIENT_RESOURCES
;
358 if (Offset
< EXT2_LINKLEN_IN_INODE
) {
359 if ((ULONG
)Offset
+ Size
>= EXT2_LINKLEN_IN_INODE
)
360 Size
= EXT2_LINKLEN_IN_INODE
- (ULONG
)Offset
- 1;
361 RtlCopyMemory(Buffer
, Data
+ (ULONG
)Offset
, Size
);
362 Status
= STATUS_SUCCESS
;
364 Status
= STATUS_END_OF_FILE
;
370 // Build the scatterred block ranges to be read
374 RealSize
= CEILING_ALIGNED(ULONG
, Size
, SECTOR_SIZE
- 1);
379 Status
= Ext2BuildExtents(
389 if (!NT_SUCCESS(Status
)) {
394 SafeZeroMemory((PCHAR
)Buffer
, Size
);
395 Status
= STATUS_SUCCESS
;
399 /* for sparse file, we need zero the gaps */
400 for (Extent
= Chain
; Buffer
!= NULL
&& Extent
!= NULL
; Extent
= Extent
->Next
) {
402 ASSERT(Extent
== Chain
);
403 if (Extent
->Offset
) {
404 SafeZeroMemory((PCHAR
)Buffer
, Extent
->Offset
);
406 } else if (Extent
->Offset
> (Prev
->Offset
+ Prev
->Length
)) {
407 SafeZeroMemory((PCHAR
)Buffer
+ Prev
->Offset
+ Prev
->Length
,
408 Extent
->Offset
- Prev
->Offset
- Prev
->Length
);
410 if (NULL
== Extent
->Next
) {
411 if (Extent
->Offset
+ Extent
->Length
< Size
) {
412 SafeZeroMemory((PCHAR
)Buffer
+ Extent
->Offset
+ Extent
->Length
,
413 Size
- Extent
->Offset
- Extent
->Length
);
421 ASSERT(IrpContext
!= NULL
);
423 // Offset should be SECTOR_SIZE aligned ...
424 Status
= Ext2ReadWriteBlocks(
432 for (Extent
= Chain
; Extent
!= NULL
; Extent
= Extent
->Next
) {
436 (PLARGE_INTEGER
)(&(Extent
->Lba
)),
439 (PVOID
)((PUCHAR
)Buffer
+ Extent
->Offset
),
442 Status
= STATUS_CANT_WAIT
;
444 Status
= IoStatus
.Status
;
447 if (!NT_SUCCESS(Status
)) {
456 Ext2DestroyExtentChain(Chain
);
462 if (NT_SUCCESS(Status
)) {
471 Ext2ReadFile(IN PEXT2_IRP_CONTEXT IrpContext
)
473 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
475 PEXT2_VCB Vcb
= NULL
;
476 PEXT2_FCB Fcb
= NULL
;
477 PEXT2_CCB Ccb
= NULL
;
478 PFILE_OBJECT FileObject
= NULL
;
480 PDEVICE_OBJECT DeviceObject
= NULL
;
483 PIO_STACK_LOCATION IoStackLocation
= NULL
;
486 ULONG ReturnedLength
= 0;
487 LARGE_INTEGER ByteOffset
;
489 BOOLEAN OpPostIrp
= FALSE
;
492 BOOLEAN SynchronousIo
;
493 BOOLEAN MainResourceAcquired
= FALSE
;
494 BOOLEAN PagingIoResourceAcquired
= FALSE
;
501 ASSERT((IrpContext
->Identifier
.Type
== EXT2ICX
) &&
502 (IrpContext
->Identifier
.Size
== sizeof(EXT2_IRP_CONTEXT
)));
504 DeviceObject
= IrpContext
->DeviceObject
;
505 Vcb
= (PEXT2_VCB
) DeviceObject
->DeviceExtension
;
507 ASSERT((Vcb
->Identifier
.Type
== EXT2VCB
) &&
508 (Vcb
->Identifier
.Size
== sizeof(EXT2_VCB
)));
510 FileObject
= IrpContext
->FileObject
;
511 Fcb
= (PEXT2_FCB
) FileObject
->FsContext
;
513 ASSERT((Fcb
->Identifier
.Type
== EXT2FCB
) &&
514 (Fcb
->Identifier
.Size
== sizeof(EXT2_FCB
)));
516 Ccb
= (PEXT2_CCB
) FileObject
->FsContext2
;
518 Irp
= IrpContext
->Irp
;
519 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
521 Length
= IoStackLocation
->Parameters
.Read
.Length
;
522 ByteOffset
= IoStackLocation
->Parameters
.Read
.ByteOffset
;
524 PagingIo
= IsFlagOn(Irp
->Flags
, IRP_PAGING_IO
);
525 Nocache
= IsFlagOn(Irp
->Flags
, IRP_NOCACHE
);
526 SynchronousIo
= IsFlagOn(FileObject
->Flags
, FO_SYNCHRONOUS_IO
);
532 DEBUG(DL_INF
, ("Ext2ReadFile: reading %wZ Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n",
533 &Fcb
->Mcb
->ShortName
, ByteOffset
.QuadPart
, Length
, PagingIo
, Nocache
));
535 if (IsSpecialFile(Fcb
) || IsInodeSymLink(Fcb
->Inode
) ) {
536 Status
= STATUS_INVALID_DEVICE_REQUEST
;
540 if ((IsSymLink(Fcb
) && IsFileDeleted(Fcb
->Mcb
->Target
)) ||
541 IsFileDeleted(Fcb
->Mcb
)) {
542 Status
= STATUS_FILE_DELETED
;
547 Irp
->IoStatus
.Information
= 0;
548 Status
= STATUS_SUCCESS
;
552 if (ByteOffset
.LowPart
== FILE_USE_FILE_POINTER_POSITION
&&
553 ByteOffset
.HighPart
== -1) {
554 ByteOffset
= FileObject
->CurrentByteOffset
;
557 if (Nocache
&& (ByteOffset
.LowPart
& (SECTOR_SIZE
- 1) ||
558 Length
& (SECTOR_SIZE
- 1))) {
559 Status
= STATUS_INVALID_PARAMETER
;
564 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_DPC
)) {
565 ClearFlag(IrpContext
->MinorFunction
, IRP_MN_DPC
);
566 Status
= STATUS_PENDING
;
571 ReturnedLength
= Length
;
575 if (!ExAcquireResourceSharedLite(
576 &Fcb
->PagingIoResource
,
577 IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_WAIT
) )) {
578 Status
= STATUS_PENDING
;
581 PagingIoResourceAcquired
= TRUE
;
585 if (Nocache
&& Ccb
!= NULL
&& Fcb
->SectionObject
.DataSectionObject
) {
587 if (!ExAcquireResourceExclusiveLite(
589 IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_WAIT
) )) {
590 Status
= STATUS_PENDING
;
593 MainResourceAcquired
= TRUE
;
595 CcFlushCache(&Fcb
->SectionObject
,
599 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
601 ClearLongFlag(Fcb
->Flags
, FCB_FILE_MODIFIED
);
603 if (ExAcquireResourceExclusiveLite(&(Fcb
->PagingIoResource
), TRUE
)) {
604 ExReleaseResourceLite(&(Fcb
->PagingIoResource
));
606 CcPurgeCacheSection( &Fcb
->SectionObject
,
611 ExConvertExclusiveToShared(&Fcb
->MainResource
);
615 if (!ExAcquireResourceSharedLite(
617 IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_WAIT
) )) {
618 Status
= STATUS_PENDING
;
621 MainResourceAcquired
= TRUE
;
624 if (!FsRtlCheckLockForReadAccess(
625 &Fcb
->FileLockAnchor
,
627 Status
= STATUS_FILE_LOCK_CONFLICT
;
632 if ((ByteOffset
.QuadPart
+ (LONGLONG
)Length
) > Fcb
->Header
.FileSize
.QuadPart
) {
633 if (ByteOffset
.QuadPart
>= Fcb
->Header
.FileSize
.QuadPart
) {
634 Irp
->IoStatus
.Information
= 0;
635 Status
= STATUS_END_OF_FILE
;
638 ReturnedLength
= (ULONG
)(Fcb
->Header
.FileSize
.QuadPart
- ByteOffset
.QuadPart
);
642 if (!IsDirectory(Fcb
) && Ccb
!= NULL
) {
643 Status
= FsRtlCheckOplock( &Fcb
->Oplock
,
649 if (Status
!= STATUS_SUCCESS
) {
655 // Set the flag indicating if Fast I/O is possible
658 Fcb
->Header
.IsFastIoPossible
= Ext2IsFastIoPossible(Fcb
);
663 if (IsDirectory(Fcb
)) {
667 if (FileObject
->PrivateCacheMap
== NULL
) {
668 CcInitializeCacheMap(
670 (PCC_FILE_SIZES
)(&Fcb
->Header
.AllocationSize
),
672 &Ext2Global
->CacheManagerCallbacks
,
674 CcSetReadAheadGranularity(
676 READ_AHEAD_GRANULARITY
);
679 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_MDL
)) {
687 Status
= Irp
->IoStatus
.Status
;
691 Buffer
= Ext2GetUserBuffer(Irp
);
692 if (Buffer
== NULL
) {
693 Status
= STATUS_INVALID_USER_BUFFER
;
698 if (!CcCopyRead(FileObject
, &ByteOffset
, ReturnedLength
,
699 Ext2CanIWait(), Buffer
, &Irp
->IoStatus
)) {
701 if (Ext2CanIWait() || !CcCopyRead(FileObject
, &ByteOffset
,
702 ReturnedLength
, TRUE
,
703 Buffer
, &Irp
->IoStatus
)) {
704 Status
= STATUS_PENDING
;
709 Status
= Irp
->IoStatus
.Status
;
714 ULONG BytesRead
= ReturnedLength
;
715 PUCHAR SystemVA
= Ext2GetUserBuffer(IrpContext
->Irp
);
717 if (ByteOffset
.QuadPart
+ BytesRead
> Fcb
->Header
.ValidDataLength
.QuadPart
) {
719 if (ByteOffset
.QuadPart
>= Fcb
->Header
.ValidDataLength
.QuadPart
) {
721 SafeZeroMemory(SystemVA
, Length
);
723 Irp
->IoStatus
.Information
= ReturnedLength
;
724 Status
= STATUS_SUCCESS
;
727 BytesRead
= (ULONG
)(Fcb
->Header
.ValidDataLength
.QuadPart
- ByteOffset
.QuadPart
);
729 SafeZeroMemory(SystemVA
+ BytesRead
, Length
- BytesRead
);
734 Status
= Ext2LockUserBuffer(
739 if (!NT_SUCCESS(Status
)) {
743 Status
= Ext2ReadInode(
753 /* we need re-queue this request in case STATUS_CANT_WAIT
754 and fail it in other failure cases */
755 if (!NT_SUCCESS(Status
)) {
759 /* pended by low level device */
760 if (Status
== STATUS_PENDING
) {
761 IrpContext
->Irp
= Irp
= NULL
;
765 Irp
= IrpContext
->Irp
;
767 Status
= Irp
->IoStatus
.Status
;
769 if (!NT_SUCCESS(Status
)) {
770 Ext2NormalizeAndRaiseStatus(IrpContext
, Status
);
774 Irp
->IoStatus
.Information
= ReturnedLength
;
779 if (PagingIoResourceAcquired
) {
780 ExReleaseResourceLite(&Fcb
->PagingIoResource
);
783 if (MainResourceAcquired
) {
784 ExReleaseResourceLite(&Fcb
->MainResource
);
788 if (!OpPostIrp
&& !IrpContext
->ExceptionInProgress
) {
791 if ( Status
== STATUS_PENDING
||
792 Status
== STATUS_CANT_WAIT
) {
794 Status
= Ext2LockUserBuffer(
799 if (NT_SUCCESS(Status
)) {
800 Status
= Ext2QueueRequest(IrpContext
);
802 Ext2CompleteIrpContext(IrpContext
, Status
);
805 if (NT_SUCCESS(Status
)) {
808 FileObject
->CurrentByteOffset
.QuadPart
=
809 ByteOffset
.QuadPart
+ Irp
->IoStatus
.Information
;
811 FileObject
->Flags
|= FO_FILE_FAST_IO_READ
;
815 Ext2CompleteIrpContext(IrpContext
, Status
);
820 Ext2FreeIrpContext(IrpContext
);
825 DEBUG(DL_IO
, ("Ext2ReadFile: %wZ fetch at Off=%I64xh Len=%xh Paging=%xh Nocache=%xh Returned=%xh Status=%xh\n",
826 &Fcb
->Mcb
->ShortName
, ByteOffset
.QuadPart
, Length
, PagingIo
, Nocache
, ReturnedLength
, Status
));
832 Ext2ReadComplete (IN PEXT2_IRP_CONTEXT IrpContext
)
834 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
835 PFILE_OBJECT FileObject
;
841 ASSERT((IrpContext
->Identifier
.Type
== EXT2ICX
) &&
842 (IrpContext
->Identifier
.Size
== sizeof(EXT2_IRP_CONTEXT
)));
844 FileObject
= IrpContext
->FileObject
;
845 Irp
= IrpContext
->Irp
;
847 CcMdlReadComplete(FileObject
, Irp
->MdlAddress
);
848 Irp
->MdlAddress
= NULL
;
849 Status
= STATUS_SUCCESS
;
853 if (!IrpContext
->ExceptionInProgress
) {
854 Ext2CompleteIrpContext(IrpContext
, Status
);
863 Ext2Read (IN PEXT2_IRP_CONTEXT IrpContext
)
867 PEXT2_FCBVCB FcbOrVcb
;
868 PDEVICE_OBJECT DeviceObject
;
869 PFILE_OBJECT FileObject
;
870 BOOLEAN bCompleteRequest
;
874 ASSERT((IrpContext
->Identifier
.Type
== EXT2ICX
) &&
875 (IrpContext
->Identifier
.Size
== sizeof(EXT2_IRP_CONTEXT
)));
879 if (FlagOn(IrpContext
->MinorFunction
, IRP_MN_COMPLETE
)) {
881 Status
= Ext2ReadComplete(IrpContext
);
882 bCompleteRequest
= FALSE
;
886 DeviceObject
= IrpContext
->DeviceObject
;
888 if (IsExt2FsDevice(DeviceObject
)) {
889 Status
= STATUS_INVALID_DEVICE_REQUEST
;
890 bCompleteRequest
= TRUE
;
894 Vcb
= (PEXT2_VCB
) DeviceObject
->DeviceExtension
;
895 if (Vcb
->Identifier
.Type
!= EXT2VCB
||
896 Vcb
->Identifier
.Size
!= sizeof(EXT2_VCB
) ) {
897 Status
= STATUS_INVALID_DEVICE_REQUEST
;
898 bCompleteRequest
= TRUE
;
903 FileObject
= IrpContext
->FileObject
;
905 if (FlagOn(Vcb
->Flags
, VCB_VOLUME_LOCKED
) &&
906 Vcb
->LockFile
!= FileObject
) {
907 Status
= STATUS_ACCESS_DENIED
;
911 FcbOrVcb
= (PEXT2_FCBVCB
) FileObject
->FsContext
;
913 if (FcbOrVcb
->Identifier
.Type
== EXT2VCB
) {
915 Status
= Ext2ReadVolume(IrpContext
);
916 bCompleteRequest
= FALSE
;
918 } else if (FcbOrVcb
->Identifier
.Type
== EXT2FCB
) {
920 if (IsFlagOn(Vcb
->Flags
, VCB_DISMOUNT_PENDING
)) {
921 Status
= STATUS_TOO_LATE
;
922 bCompleteRequest
= TRUE
;
926 Status
= Ext2ReadFile(IrpContext
);
927 bCompleteRequest
= FALSE
;
929 DEBUG(DL_ERR
, ( "Ext2Read: Inavlid FileObject (Vcb or Fcb corrupted)\n"));
932 Status
= STATUS_INVALID_PARAMETER
;
933 bCompleteRequest
= TRUE
;
938 if (bCompleteRequest
) {
939 Ext2CompleteIrpContext(IrpContext
, Status
);