Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: read.c * PROGRAMMER: Matt Wu <mattwu@163.com> * HOMEPAGE: http://www.ext2fsd.com * UPDATE HISTORY: */
/* INCLUDES *****************************************************************/
#include "ext2fs.h"
/* GLOBALS ***************************************************************/
extern PEXT2_GLOBAL Ext2Global;
/* DEFINITIONS *************************************************************/
NTSTATUSExt2ReadComplete (IN PEXT2_IRP_CONTEXT IrpContext);
NTSTATUSExt2ReadFile (IN PEXT2_IRP_CONTEXT IrpContext);
NTSTATUSExt2ReadVolume (IN PEXT2_IRP_CONTEXT IrpContext);
/* FUNCTIONS *************************************************************/
NTSTATUSExt2CompleteIrpContext ( IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status ){ PIRP Irp = NULL; BOOLEAN bPrint;
Irp = IrpContext->Irp;
if (Irp != NULL) {
if (NT_ERROR(Status)) { Irp->IoStatus.Information = 0; }
Irp->IoStatus.Status = Status; bPrint = !IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
Ext2CompleteRequest( Irp, bPrint, (CCHAR)(NT_SUCCESS(Status)? IO_DISK_INCREMENT : IO_NO_INCREMENT) );
IrpContext->Irp = NULL; }
Ext2FreeIrpContext(IrpContext);
return Status;}
NTSTATUSExt2ReadVolume (IN PEXT2_IRP_CONTEXT IrpContext){ NTSTATUS Status = STATUS_UNSUCCESSFUL;
PEXT2_VCB Vcb = NULL; PEXT2_CCB Ccb = NULL; PEXT2_FCBVCB FcbOrVcb = NULL; PFILE_OBJECT FileObject = NULL;
PDEVICE_OBJECT DeviceObject = NULL;
PIRP Irp = NULL; PIO_STACK_LOCATION IoStackLocation = NULL;
ULONG Length; LARGE_INTEGER ByteOffset;
BOOLEAN PagingIo; BOOLEAN Nocache; BOOLEAN SynchronousIo; BOOLEAN MainResourceAcquired = FALSE;
PUCHAR Buffer = NULL; EXT2_EXTENT BlockArray;
_SEH2_TRY {
ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject; Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension; ASSERT(Vcb != NULL); ASSERT((Vcb->Identifier.Type == EXT2VCB) && (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
FileObject = IrpContext->FileObject; FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext; ASSERT(FcbOrVcb);
if (!(FcbOrVcb->Identifier.Type == EXT2VCB && (PVOID)FcbOrVcb == (PVOID)Vcb)) {
Status = STATUS_INVALID_DEVICE_REQUEST; _SEH2_LEAVE; }
Ccb = (PEXT2_CCB) FileObject->FsContext2; Irp = IrpContext->Irp; Irp->IoStatus.Information = 0; IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
Length = IoStackLocation->Parameters.Read.Length; ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO); Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE) || (Ccb != NULL); SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
if (PagingIo) { ASSERT(Nocache); }
if (Length == 0) { Irp->IoStatus.Information = 0; Status = STATUS_SUCCESS; _SEH2_LEAVE; }
if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) { ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC); Status = STATUS_PENDING; _SEH2_LEAVE; }
if (ByteOffset.QuadPart >= Vcb->PartitionInformation.PartitionLength.QuadPart ) { Irp->IoStatus.Information = 0; Status = STATUS_END_OF_FILE; _SEH2_LEAVE; }
if (ByteOffset.QuadPart + Length > Vcb->Header.FileSize.QuadPart) { Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart); }
/* * User direct volume access */
if (Ccb != NULL && !PagingIo) {
if (!ExAcquireResourceExclusiveLite( &Vcb->MainResource, IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) { Status = STATUS_PENDING; _SEH2_LEAVE; } MainResourceAcquired = TRUE;
if (!FlagOn(Ccb->Flags, CCB_VOLUME_DASD_PURGE)) {
if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) { Ext2FlushVolume(IrpContext, Vcb, FALSE); }
SetFlag(Ccb->Flags, CCB_VOLUME_DASD_PURGE); }
ExReleaseResourceLite(&Vcb->MainResource); MainResourceAcquired = FALSE;
/* will do Nocache i/o */ }
/* * I/O to volume StreamObject */
if (!Nocache) {
if (IsFlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
CcMdlRead( Vcb->Volume, &ByteOffset, Length, &Irp->MdlAddress, &Irp->IoStatus );
Status = Irp->IoStatus.Status;
} else {
Buffer = Ext2GetUserBuffer(Irp); if (Buffer == NULL) { DbgBreak(); Status = STATUS_INVALID_USER_BUFFER; _SEH2_LEAVE; }
if (!CcCopyRead( Vcb->Volume, &ByteOffset, Length, Ext2CanIWait(), Buffer, &Irp->IoStatus )) { Status = STATUS_PENDING; _SEH2_LEAVE; }
Status = Irp->IoStatus.Status; }
} else {
Length &= ~((ULONG)SECTOR_SIZE - 1); Status = Ext2LockUserBuffer( IrpContext->Irp, Length, IoWriteAccess );
if (!NT_SUCCESS(Status)) { _SEH2_LEAVE; }
BlockArray.Irp = NULL; BlockArray.Lba = ByteOffset.QuadPart; BlockArray.Offset = 0; BlockArray.Length = Length; BlockArray.Next = NULL;
Status = Ext2ReadWriteBlocks(IrpContext, Vcb, &BlockArray, Length );
Irp = IrpContext->Irp; if (!Irp) { _SEH2_LEAVE; } }
} _SEH2_FINALLY {
if (MainResourceAcquired) { ExReleaseResourceLite(&Vcb->MainResource); }
if (!IrpContext->ExceptionInProgress) {
if (Irp) {
if (Status == STATUS_PENDING && !IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED)) {
Status = Ext2LockUserBuffer( IrpContext->Irp, Length, IoWriteAccess );
if (NT_SUCCESS(Status)) { Status = Ext2QueueRequest(IrpContext); } else { Ext2CompleteIrpContext(IrpContext, Status); }
} else {
if (NT_SUCCESS(Status)) {
if (!PagingIo) {
if (SynchronousIo) {
FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information; }
FileObject->Flags |= FO_FILE_FAST_IO_READ; } }
Ext2CompleteIrpContext(IrpContext, Status);; }
} else { Ext2FreeIrpContext(IrpContext); } } } _SEH2_END;
return Status;}
#define SafeZeroMemory(AT,BYTE_COUNT) { \ _SEH2_TRY { \ if (AT) \ RtlZeroMemory((AT), (BYTE_COUNT)); \ } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ Ext2RaiseStatus( IrpContext, STATUS_INVALID_USER_BUFFER ); \ } _SEH2_END; \}
NTSTATUSExt2ReadInode ( IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN PVOID Buffer, IN ULONG Size, IN BOOLEAN bDirectIo, OUT PULONG BytesRead){ PEXT2_EXTENT Chain = NULL; PEXT2_EXTENT Extent = NULL, Prev = NULL;
IO_STATUS_BLOCK IoStatus; NTSTATUS Status = STATUS_UNSUCCESSFUL; ULONG RealSize ;
if (BytesRead) { *BytesRead = 0; }
_SEH2_TRY {
Ext2ReferMcb(Mcb);
ASSERT((Mcb->Identifier.Type == EXT2MCB) && (Mcb->Identifier.Size == sizeof(EXT2_MCB)));
if ((Mcb->Identifier.Type != EXT2MCB) || (Mcb->Identifier.Size != sizeof(EXT2_MCB))) { _SEH2_LEAVE; }
if (Buffer == NULL && IrpContext != NULL) Buffer = Ext2GetUserBuffer(IrpContext->Irp);
/* handle fast symlinks */ if (S_ISLNK(Mcb->Inode.i_mode) && 0 == Mcb->Inode.i_blocks) {
PUCHAR Data = (PUCHAR) (&Mcb->Inode.i_block[0]); if (!Buffer) { Status = STATUS_INSUFFICIENT_RESOURCES; _SEH2_LEAVE; }
if (Offset < EXT2_LINKLEN_IN_INODE) { if ((ULONG)Offset + Size >= EXT2_LINKLEN_IN_INODE) Size = EXT2_LINKLEN_IN_INODE - (ULONG)Offset - 1; RtlCopyMemory(Buffer, Data + (ULONG)Offset, Size); Status = STATUS_SUCCESS; } else { Status = STATUS_END_OF_FILE; } _SEH2_LEAVE; }
// // Build the scatterred block ranges to be read //
if (bDirectIo) { RealSize = CEILING_ALIGNED(ULONG, Size, SECTOR_SIZE - 1); } else { RealSize = Size; }
Status = Ext2BuildExtents( IrpContext, Vcb, Mcb, Offset, RealSize, FALSE, &Chain );
if (!NT_SUCCESS(Status)) { _SEH2_LEAVE; }
if (Chain == NULL) { SafeZeroMemory((PCHAR)Buffer, Size); Status = STATUS_SUCCESS; _SEH2_LEAVE; }
/* for sparse file, we need zero the gaps */ for (Extent = Chain; Buffer != NULL && Extent != NULL; Extent = Extent->Next) { if (NULL == Prev) { ASSERT(Extent == Chain); if (Extent->Offset) { SafeZeroMemory((PCHAR)Buffer, Extent->Offset); } } else if (Extent->Offset > (Prev->Offset + Prev->Length)) { SafeZeroMemory((PCHAR)Buffer + Prev->Offset + Prev->Length, Extent->Offset - Prev->Offset - Prev->Length); } if (NULL == Extent->Next) { if (Extent->Offset + Extent->Length < Size) { SafeZeroMemory((PCHAR)Buffer + Extent->Offset + Extent->Length, Size - Extent->Offset - Extent->Length); } } Prev = Extent; }
if (bDirectIo) {
ASSERT(IrpContext != NULL);
// Offset should be SECTOR_SIZE aligned ... Status = Ext2ReadWriteBlocks( IrpContext, Vcb, Chain, Size ); } else {
for (Extent = Chain; Extent != NULL; Extent = Extent->Next) {
if (!CcCopyRead( Vcb->Volume, (PLARGE_INTEGER)(&(Extent->Lba)), Extent->Length, PIN_WAIT, (PVOID)((PUCHAR)Buffer + Extent->Offset), &IoStatus )) { Status = STATUS_CANT_WAIT; } else { Status = IoStatus.Status; }
if (!NT_SUCCESS(Status)) { break; } } }
} _SEH2_FINALLY {
if (Chain) { Ext2DestroyExtentChain(Chain); }
Ext2DerefMcb(Mcb); } _SEH2_END;
if (NT_SUCCESS(Status)) { if (BytesRead) *BytesRead = Size; }
return Status;}
NTSTATUSExt2ReadFile(IN PEXT2_IRP_CONTEXT IrpContext){ NTSTATUS Status = STATUS_UNSUCCESSFUL;
PEXT2_VCB Vcb = NULL; PEXT2_FCB Fcb = NULL; PEXT2_CCB Ccb = NULL; PFILE_OBJECT FileObject = NULL;
PDEVICE_OBJECT DeviceObject = NULL;
PIRP Irp = NULL; PIO_STACK_LOCATION IoStackLocation = NULL;
ULONG Length; ULONG ReturnedLength = 0; LARGE_INTEGER ByteOffset;
BOOLEAN OpPostIrp = FALSE; BOOLEAN PagingIo; BOOLEAN Nocache; BOOLEAN SynchronousIo; BOOLEAN MainResourceAcquired = FALSE; BOOLEAN PagingIoResourceAcquired = FALSE;
PUCHAR Buffer;
_SEH2_TRY {
ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject; Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension; ASSERT(Vcb != NULL); ASSERT((Vcb->Identifier.Type == EXT2VCB) && (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
FileObject = IrpContext->FileObject; Fcb = (PEXT2_FCB) FileObject->FsContext; ASSERT(Fcb); ASSERT((Fcb->Identifier.Type == EXT2FCB) && (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
Ccb = (PEXT2_CCB) FileObject->FsContext2;
Irp = IrpContext->Irp; IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
Length = IoStackLocation->Parameters.Read.Length; ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO); Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE); SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
if (PagingIo) { ASSERT(Nocache); }
DEBUG(DL_INF, ("Ext2ReadFile: reading %wZ Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n", &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache));
if (IsSpecialFile(Fcb) || IsInodeSymLink(Fcb->Inode) ) { Status = STATUS_INVALID_DEVICE_REQUEST; _SEH2_LEAVE; }
if ((IsSymLink(Fcb) && IsFileDeleted(Fcb->Mcb->Target)) || IsFileDeleted(Fcb->Mcb)) { Status = STATUS_FILE_DELETED; _SEH2_LEAVE; }
if (Length == 0) { Irp->IoStatus.Information = 0; Status = STATUS_SUCCESS; _SEH2_LEAVE; }
if (ByteOffset.LowPart == FILE_USE_FILE_POINTER_POSITION && ByteOffset.HighPart == -1) { ByteOffset = FileObject->CurrentByteOffset; }
if (Nocache && (ByteOffset.LowPart & (SECTOR_SIZE - 1) || Length & (SECTOR_SIZE - 1))) { Status = STATUS_INVALID_PARAMETER; DbgBreak(); _SEH2_LEAVE; }
if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) { ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC); Status = STATUS_PENDING; DbgBreak(); _SEH2_LEAVE; }
ReturnedLength = Length;
if (PagingIo) {
if (!ExAcquireResourceSharedLite( &Fcb->PagingIoResource, IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) { Status = STATUS_PENDING; _SEH2_LEAVE; } PagingIoResourceAcquired = TRUE;
} else {
if (Nocache && Ccb != NULL && Fcb->SectionObject.DataSectionObject) {
if (!ExAcquireResourceExclusiveLite( &Fcb->MainResource, IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) { Status = STATUS_PENDING; _SEH2_LEAVE; } MainResourceAcquired = TRUE;
CcFlushCache(&Fcb->SectionObject, &ByteOffset, Length, &Irp->IoStatus ); if (!NT_SUCCESS(Irp->IoStatus.Status)) _SEH2_LEAVE; ClearLongFlag(Fcb->Flags, FCB_FILE_MODIFIED);
if (ExAcquireResourceExclusiveLite(&(Fcb->PagingIoResource), TRUE)) { ExReleaseResourceLite(&(Fcb->PagingIoResource)); } CcPurgeCacheSection( &Fcb->SectionObject, NULL, 0, FALSE );
ExConvertExclusiveToShared(&Fcb->MainResource);
} else {
if (!ExAcquireResourceSharedLite( &Fcb->MainResource, IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) { Status = STATUS_PENDING; _SEH2_LEAVE; } MainResourceAcquired = TRUE; }
if (!FsRtlCheckLockForReadAccess( &Fcb->FileLockAnchor, Irp )) { Status = STATUS_FILE_LOCK_CONFLICT; _SEH2_LEAVE; } }
if ((ByteOffset.QuadPart + (LONGLONG)Length) > Fcb->Header.FileSize.QuadPart) { if (ByteOffset.QuadPart >= Fcb->Header.FileSize.QuadPart) { Irp->IoStatus.Information = 0; Status = STATUS_END_OF_FILE; _SEH2_LEAVE; } ReturnedLength = (ULONG)(Fcb->Header.FileSize.QuadPart - ByteOffset.QuadPart); }
if (!IsDirectory(Fcb) && Ccb != NULL) { Status = FsRtlCheckOplock( &Fcb->Oplock, Irp, IrpContext, Ext2OplockComplete, Ext2LockIrp );
if (Status != STATUS_SUCCESS) { OpPostIrp = TRUE; _SEH2_LEAVE; }
// // Set the flag indicating if Fast I/O is possible //
Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb); }
if (!Nocache) {
if (IsDirectory(Fcb)) { _SEH2_LEAVE; }
if (FileObject->PrivateCacheMap == NULL) { CcInitializeCacheMap( FileObject, (PCC_FILE_SIZES)(&Fcb->Header.AllocationSize), FALSE, &Ext2Global->CacheManagerCallbacks, Fcb ); CcSetReadAheadGranularity( FileObject, READ_AHEAD_GRANULARITY ); }
if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) { CcMdlRead( FileObject, (&ByteOffset), ReturnedLength, &Irp->MdlAddress, &Irp->IoStatus );
Status = Irp->IoStatus.Status;
} else {
Buffer = Ext2GetUserBuffer(Irp); if (Buffer == NULL) { Status = STATUS_INVALID_USER_BUFFER; DbgBreak(); _SEH2_LEAVE; }
if (!CcCopyRead(FileObject, &ByteOffset, ReturnedLength, Ext2CanIWait(), Buffer, &Irp->IoStatus)) {
if (Ext2CanIWait() || !CcCopyRead(FileObject, &ByteOffset, ReturnedLength, TRUE, Buffer, &Irp->IoStatus)) { Status = STATUS_PENDING; DbgBreak(); _SEH2_LEAVE; } } Status = Irp->IoStatus.Status; }
} else {
ULONG BytesRead = ReturnedLength; PUCHAR SystemVA = Ext2GetUserBuffer(IrpContext->Irp);
if (ByteOffset.QuadPart + BytesRead > Fcb->Header.ValidDataLength.QuadPart) {
if (ByteOffset.QuadPart >= Fcb->Header.ValidDataLength.QuadPart) { if (SystemVA) { SafeZeroMemory(SystemVA, Length); } Irp->IoStatus.Information = ReturnedLength; Status = STATUS_SUCCESS; _SEH2_LEAVE; } else { BytesRead = (ULONG)(Fcb->Header.ValidDataLength.QuadPart - ByteOffset.QuadPart); if (SystemVA) { SafeZeroMemory(SystemVA + BytesRead, Length - BytesRead); } } }
Status = Ext2LockUserBuffer( IrpContext->Irp, BytesRead, IoReadAccess );
if (!NT_SUCCESS(Status)) { _SEH2_LEAVE; }
Status = Ext2ReadInode( IrpContext, Vcb, Fcb->Mcb, ByteOffset.QuadPart, NULL, BytesRead, TRUE, NULL );
/* we need re-queue this request in case STATUS_CANT_WAIT and fail it in other failure cases */ if (!NT_SUCCESS(Status)) { _SEH2_LEAVE; }
/* pended by low level device */ if (Status == STATUS_PENDING) { IrpContext->Irp = Irp = NULL; _SEH2_LEAVE; }
Irp = IrpContext->Irp; ASSERT(Irp); Status = Irp->IoStatus.Status;
if (!NT_SUCCESS(Status)) { Ext2NormalizeAndRaiseStatus(IrpContext, Status); } }
Irp->IoStatus.Information = ReturnedLength;
} _SEH2_FINALLY {
if (Irp) { if (PagingIoResourceAcquired) { ExReleaseResourceLite(&Fcb->PagingIoResource); }
if (MainResourceAcquired) { ExReleaseResourceLite(&Fcb->MainResource); } }
if (!OpPostIrp && !IrpContext->ExceptionInProgress) {
if (Irp) { if ( Status == STATUS_PENDING || Status == STATUS_CANT_WAIT) {
Status = Ext2LockUserBuffer( IrpContext->Irp, Length, IoWriteAccess );
if (NT_SUCCESS(Status)) { Status = Ext2QueueRequest(IrpContext); } else { Ext2CompleteIrpContext(IrpContext, Status); } } else { if (NT_SUCCESS(Status)) { if (!PagingIo) { if (SynchronousIo) { FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + Irp->IoStatus.Information; } FileObject->Flags |= FO_FILE_FAST_IO_READ; } }
Ext2CompleteIrpContext(IrpContext, Status); }
} else {
Ext2FreeIrpContext(IrpContext); } } } _SEH2_END;
DEBUG(DL_IO, ("Ext2ReadFile: %wZ fetch at Off=%I64xh Len=%xh Paging=%xh Nocache=%xh Returned=%xh Status=%xh\n", &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache, ReturnedLength, Status)); return Status;
}
NTSTATUSExt2ReadComplete (IN PEXT2_IRP_CONTEXT IrpContext){ NTSTATUS Status = STATUS_UNSUCCESSFUL; PFILE_OBJECT FileObject; PIRP Irp;
_SEH2_TRY {
ASSERT(IrpContext); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
FileObject = IrpContext->FileObject; Irp = IrpContext->Irp;
CcMdlReadComplete(FileObject, Irp->MdlAddress); Irp->MdlAddress = NULL; Status = STATUS_SUCCESS;
} _SEH2_FINALLY {
if (!IrpContext->ExceptionInProgress) { Ext2CompleteIrpContext(IrpContext, Status); } } _SEH2_END;
return Status;}
NTSTATUSExt2Read (IN PEXT2_IRP_CONTEXT IrpContext){ NTSTATUS Status; PEXT2_VCB Vcb; PEXT2_FCBVCB FcbOrVcb; PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; BOOLEAN bCompleteRequest;
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
_SEH2_TRY {
if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE)) {
Status = Ext2ReadComplete(IrpContext); bCompleteRequest = FALSE;
} else {
DeviceObject = IrpContext->DeviceObject;
if (IsExt2FsDevice(DeviceObject)) { Status = STATUS_INVALID_DEVICE_REQUEST; bCompleteRequest = TRUE; _SEH2_LEAVE; }
Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension; if (Vcb->Identifier.Type != EXT2VCB || Vcb->Identifier.Size != sizeof(EXT2_VCB) ) { Status = STATUS_INVALID_DEVICE_REQUEST; bCompleteRequest = TRUE;
_SEH2_LEAVE; }
FileObject = IrpContext->FileObject;
if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) && Vcb->LockFile != FileObject ) { Status = STATUS_ACCESS_DENIED;#ifdef __REACTOS__ bCompleteRequest = TRUE;#endif _SEH2_LEAVE; }
FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
if (FcbOrVcb->Identifier.Type == EXT2VCB) {
Status = Ext2ReadVolume(IrpContext); bCompleteRequest = FALSE;
} else if (FcbOrVcb->Identifier.Type == EXT2FCB) {
if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) { Status = STATUS_TOO_LATE; bCompleteRequest = TRUE; _SEH2_LEAVE; }
Status = Ext2ReadFile(IrpContext); bCompleteRequest = FALSE; } else { DEBUG(DL_ERR, ( "Ext2Read: Inavlid FileObject (Vcb or Fcb corrupted)\n")); DbgBreak();
Status = STATUS_INVALID_PARAMETER; bCompleteRequest = TRUE; } }
} _SEH2_FINALLY { if (bCompleteRequest) { Ext2CompleteIrpContext(IrpContext, Status); } } _SEH2_END;
return Status;}