📄 read.c
字号:
if (FileObject->PrivateCacheMap == NULL)
{
CcInitializeCacheMap(
FileObject,
(PCC_FILE_SIZES)(&Fcb->CommonFCBHeader.AllocationSize),
FALSE,
&FsdGlobalData.CacheManagerCallbacks,
Fcb
);
}
if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL))
{
CcMdlRead(
FileObject,
&ByteOffset,
Length,
&Irp->MdlAddress,
&Irp->IoStatus
);
Status = Irp->IoStatus.Status;
}
else
{
UserBuffer = FsdGetUserBuffer(Irp);
if (UserBuffer == NULL)
{
Status = STATUS_INVALID_USER_BUFFER;
__leave;
}
if (!CcCopyRead(
FileObject,
&ByteOffset,
Length,
IrpContext->IsSynchronous,
UserBuffer,
&Irp->IoStatus
))
{
Status = STATUS_PENDING;
__leave;
}
Status = Irp->IoStatus.Status;
}
}
else
{
ReturnedLength = Length;
if ((ByteOffset.QuadPart + Length) >
be32_to_cpu(Fcb->romfs_inode->size))
{
ReturnedLength =
be32_to_cpu(Fcb->romfs_inode->size) - ByteOffset.LowPart;
Length = (ReturnedLength & ~(SECTOR_SIZE - 1)) + SECTOR_SIZE;
}
UserBuffer = FsdGetUserBuffer(Irp);
if (UserBuffer == NULL)
{
Status = STATUS_INVALID_USER_BUFFER;
__leave;
}
Status = FsdReadFileData(
Vcb->TargetDeviceObject,
(ULONG) Fcb->IndexNumber.QuadPart,
Fcb->romfs_inode,
&ByteOffset,
Length,
UserBuffer
);
if (Status == STATUS_VERIFY_REQUIRED)
{
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
Status = IoVerifyVolume(DeviceToVerify, FALSE);
if (NT_SUCCESS(Status))
{
Status = FsdReadFileData(
Vcb->TargetDeviceObject,
(ULONG) Fcb->IndexNumber.QuadPart,
Fcb->romfs_inode,
&ByteOffset,
Length,
UserBuffer
);
}
}
if (NT_SUCCESS(Status))
{
Irp->IoStatus.Information = ReturnedLength;
}
}
}
__finally
{
if (FcbPagingIoResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->PagingIoResource,
ExGetCurrentResourceThread()
);
}
if (FcbMainResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Fcb->MainResource,
ExGetCurrentResourceThread()
);
}
if (VcbResourceAcquired)
{
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread()
);
}
if (!AbnormalTermination())
{
if (Status == STATUS_PENDING)
{
Status = FsdLockUserBuffer(
IrpContext->Irp,
Length,
IoWriteAccess
);
if (NT_SUCCESS(Status))
{
Status = FsdQueueRequest(IrpContext);
}
else
{
IrpContext->Irp->IoStatus.Status = Status;
FsdCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
FsdFreeIrpContext(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;
}
FsdCompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
FsdFreeIrpContext(IrpContext);
}
}
}
return Status;
}
NTSTATUS
FsdReadComplete (
IN PFSD_IRP_CONTEXT IrpContext
)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PFILE_OBJECT FileObject;
PIRP Irp;
__try
{
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == ICX) &&
(IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));
FileObject = IrpContext->FileObject;
Irp = IrpContext->Irp;
CcMdlReadComplete(FileObject, Irp->MdlAddress);
Irp->MdlAddress = NULL;
Status = STATUS_SUCCESS;
}
__finally
{
if (!AbnormalTermination())
{
IrpContext->Irp->IoStatus.Status = Status;
FsdCompleteRequest(
IrpContext->Irp,
(CCHAR)
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
FsdFreeIrpContext(IrpContext);
}
}
return Status;
}
NTSTATUS
FsdReadFileData (
IN PDEVICE_OBJECT DeviceObject,
IN ULONG Index,
IN struct romfs_inode* Inode,
IN PLARGE_INTEGER Offset,
IN ULONG Length,
IN OUT PVOID Buffer
)
{
LARGE_INTEGER PhysicalOffset;
ULONG PhysicalLength;
PUCHAR PhysicalBuffer;
NTSTATUS Status;
ASSERT(DeviceObject != NULL);
ASSERT(Inode != NULL);
ASSERT(Offset != NULL);
ASSERT(Buffer != NULL);
KdPrint((
DRIVER_NAME
": FsdReadFileData: Index: %#x Offset: %I64u Length: %u\n",
Index,
Offset->QuadPart,
Length
));
//
// On Romfs file data is 16 byte aligned and continuous while read/write
// operations on storage devices must be sector aligned and have an length
// that is a multiple of the sector size. If the file data happens to be
// sector aligned we just calculate the physical offset to it and do a read
// from the storage device. If the file data is not sector aligned we
// allocate a temporary buffer, do a sector aligned read to it and copy the
// right data from the temporary buffer to the callers buffer.
//
if (!((Index + SIZEOF_ROMFS_INODE(Inode) + Offset->QuadPart) &
(SECTOR_SIZE - 1))
)
{
PhysicalOffset.QuadPart =
Index + SIZEOF_ROMFS_INODE(Inode) + Offset->QuadPart;
Status = FsdReadBlockDeviceAtApcLevel(
DeviceObject,
&PhysicalOffset,
Length,
Buffer
);
}
else
{
PhysicalOffset.QuadPart =
(Index + SIZEOF_ROMFS_INODE(Inode) + Offset->QuadPart) &
~(SECTOR_SIZE - 1);
PhysicalLength = Length + SECTOR_SIZE;
PhysicalBuffer = (PUCHAR) FsdAllocatePool(
NonPagedPool,
PhysicalLength,
'3mTR'
);
if (PhysicalBuffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = FsdReadBlockDeviceAtApcLevel(
DeviceObject,
&PhysicalOffset,
PhysicalLength,
PhysicalBuffer
);
RtlCopyMemory(
Buffer,
PhysicalBuffer +
((Index + SIZEOF_ROMFS_INODE(Inode) + Offset->QuadPart) &
(SECTOR_SIZE - 1)),
Length
);
FsdFreePool(PhysicalBuffer);
}
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -