⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read.c

📁 I want to provide an example file system driver for Windows NT/2000/XP. For some time I have worked
💻 C
📖 第 1 页 / 共 2 页
字号:
            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 + -