📄 read.c
字号:
}
else
{
for(i = 0; i < blocks; i++)
{
IoStatus.Information = 0;
Ext2CopyRead(
Vcb->StreamObj,
(PLARGE_INTEGER)(&(ext2_bdl[i].Lba)),
ext2_bdl[i].Length,
TRUE,
(PVOID)((PUCHAR)Buffer + ext2_bdl[i].Offset),
&IoStatus );
Status = IoStatus.Status;
}
}
errorout:
if (ext2_bdl)
ExFreePool(ext2_bdl);
return Status;
}
NTSTATUS
Ext2ReadFile(IN PEXT2_IRP_CONTEXT IrpContext)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PEXT2_VCB Vcb;
PEXT2_FCB Fcb;
PEXT2_CCB Ccb;
PFILE_OBJECT FileObject;
PFILE_OBJECT CacheObject;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
PIO_STACK_LOCATION IoStackLocation;
ULONG Length;
ULONG ReturnedLength;
LARGE_INTEGER ByteOffset;
BOOLEAN PagingIo;
BOOLEAN Nocache;
BOOLEAN SynchronousIo;
BOOLEAN MainResourceAcquired = FALSE;
BOOLEAN PagingIoResourceAcquired = FALSE;
PUCHAR Buffer;
__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 = (Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
Nocache = (Irp->Flags & IRP_NOCACHE ? TRUE : FALSE);
SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO ? TRUE : FALSE);
if (Length == 0)
{
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
__leave;
}
if (Nocache &&
(ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
Length & (SECTOR_SIZE - 1)))
{
Status = STATUS_INVALID_PARAMETER;
Ext2DbgBreakPoint();
__leave;
}
if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC))
{
ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
Status = STATUS_PENDING;
Ext2DbgBreakPoint();
__leave;
}
if (!PagingIo)
{
if (!ExAcquireResourceSharedLite(
&Fcb->MainResource,
IrpContext->IsSynchronous ))
{
Status = STATUS_PENDING;
__leave;
}
MainResourceAcquired = TRUE;
if (!FsRtlCheckLockForReadAccess(
&Fcb->FileLockAnchor,
Irp ))
{
Status = STATUS_FILE_LOCK_CONFLICT;
__leave;
}
}
else
{
if (!ExAcquireResourceSharedLite(
&Fcb->PagingIoResource,
IrpContext->IsSynchronous ))
{
Status = STATUS_PENDING;
__leave;
}
PagingIoResourceAcquired = TRUE;
}
if (!Nocache)
{
if ((ByteOffset.QuadPart + (LONGLONG)Length) >
Fcb->CommonFCBHeader.FileSize.QuadPart )
{
if (ByteOffset.QuadPart >= (Fcb->CommonFCBHeader.FileSize.QuadPart))
{
Irp->IoStatus.Information = 0;
Status = STATUS_END_OF_FILE;
__leave;
}
Length =
(ULONG)(Fcb->CommonFCBHeader.FileSize.QuadPart - ByteOffset.QuadPart);
}
ReturnedLength = Length;
if (FlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
{
__leave;
}
{
if (FileObject->PrivateCacheMap == NULL)
{
CcInitializeCacheMap(
FileObject,
(PCC_FILE_SIZES)(&Fcb->CommonFCBHeader.AllocationSize),
FALSE,
&gExt2Global->CacheManagerCallbacks,
Fcb );
}
CacheObject = FileObject;
}
if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL))
{
CcMdlRead(
CacheObject,
(&ByteOffset),
Length,
&Irp->MdlAddress,
&Irp->IoStatus );
Status = Irp->IoStatus.Status;
}
else
{
Buffer = Ext2GetUserBuffer(Irp);
if (Buffer == NULL)
{
Status = STATUS_INVALID_USER_BUFFER;
Ext2DbgBreakPoint();
__leave;
}
if (!CcCopyRead(
CacheObject,
(PLARGE_INTEGER)&ByteOffset,
Length,
IrpContext->IsSynchronous,
Buffer,
&Irp->IoStatus ))
{
Status = STATUS_PENDING;
Ext2DbgBreakPoint();
__leave;
}
Status = Irp->IoStatus.Status;
}
}
else
{
if ((ByteOffset.QuadPart + (LONGLONG)Length) > Fcb->CommonFCBHeader.AllocationSize.QuadPart)
{
if (ByteOffset.QuadPart >= Fcb->CommonFCBHeader.AllocationSize.QuadPart)
{
Irp->IoStatus.Information = 0;
Status = STATUS_END_OF_FILE;
Ext2DbgBreakPoint();
__leave;
}
Length =
(ULONG)(Fcb->CommonFCBHeader.AllocationSize.QuadPart- ByteOffset.QuadPart);
}
ReturnedLength = Length;
Status = Ext2LockUserBuffer(
IrpContext->Irp,
Length,
IoWriteAccess );
if (!NT_SUCCESS(Status))
{
__leave;
}
Buffer = Ext2GetUserBuffer(Irp);
if (Buffer == NULL)
{
Status = STATUS_INVALID_USER_BUFFER;
Ext2DbgBreakPoint();
__leave;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Length;
Status =
Ext2ReadInode(
IrpContext,
Vcb,
Fcb->ext2_inode,
(ULONG)(ByteOffset.QuadPart),
NULL,
Length,
&ReturnedLength);
Irp = IrpContext->Irp;
}
}
__finally
{
if (PagingIoResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->PagingIoResource,
ExGetCurrentResourceThread());
}
if (MainResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->MainResource,
ExGetCurrentResourceThread());
}
if (!IrpContext->ExceptionInProgress)
{
if (Irp)
{
if (Status == STATUS_PENDING)
{
Status = Ext2LockUserBuffer(
IrpContext->Irp,
Length,
IoWriteAccess );
if (NT_SUCCESS(Status))
{
Status = Ext2QueueRequest(IrpContext);
}
else
{
IrpContext->Irp->IoStatus.Status = Status;
Ext2CompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
Ext2FreeIrpContext(IrpContext);
}
}
else
{
IrpContext->Irp->IoStatus.Status = Status;
if (SynchronousIo && !PagingIo && NT_SUCCESS(Status))
{
FileObject->CurrentByteOffset.QuadPart =
ByteOffset.QuadPart + Irp->IoStatus.Information;
}
if (!PagingIo && NT_SUCCESS(Status))
{
FileObject->Flags &= ~FO_FILE_FAST_IO_READ;
}
Ext2CompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
Ext2FreeIrpContext(IrpContext);
}
}
else
{
Ext2FreeIrpContext(IrpContext);
}
}
}
return Status;
}
NTSTATUS
Ext2ReadComplete (IN PEXT2_IRP_CONTEXT IrpContext)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PFILE_OBJECT FileObject;
PIRP Irp;
__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;
}
__finally
{
if (!IrpContext->ExceptionInProgress)
{
IrpContext->Irp->IoStatus.Status = Status;
Ext2CompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
Ext2FreeIrpContext(IrpContext);
}
}
return Status;
}
NTSTATUS
Ext2Read (IN PEXT2_IRP_CONTEXT IrpContext)
{
NTSTATUS Status;
PEXT2_FCBVCB FcbOrVcb;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
(IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
__try
{
if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE))
{
Status = Ext2ReadComplete(IrpContext);
}
else
{
DeviceObject = IrpContext->DeviceObject;
if (DeviceObject == gExt2Global->DeviceObject)
{
Status = Ext2CompleteIrpContext(IrpContext, STATUS_INVALID_DEVICE_REQUEST);
__leave;
}
FileObject = IrpContext->FileObject;
FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
if (FcbOrVcb->Identifier.Type == EXT2VCB)
{
Status = Ext2ReadVolume(IrpContext);
}
else if (FcbOrVcb->Identifier.Type == EXT2FCB)
{
Status = Ext2ReadFile(IrpContext);
}
else
{
Ext2DbgPrint(D_READ, "Ext2Read: INVALID PARAMETER ... \n");
Ext2DbgBreakPoint();
Status = Ext2CompleteIrpContext(IrpContext, STATUS_INVALID_PARAMETER);
}
}
}
__finally
{
}
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -