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

📄 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 页
字号:
/*
    This is a romfs file system driver for Windows NT/2000/XP.
    Copyright (C) 1999, 2000, 2001, 2002 Bo Brant閚.
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "ntifs.h"
#include "fsd.h"
#include "rom_fs.h"
#include "border.h"

NTSTATUS
FsdRead (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    NTSTATUS Status;

    ASSERT(IrpContext);

    ASSERT((IrpContext->Identifier.Type == ICX) &&
           (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

    if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE))
    {
        Status = FsdReadComplete(IrpContext);
    }
    else
    {
        Status = FsdReadNormal(IrpContext);
    }

    return Status;
}

NTSTATUS
FsdReadNormal (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    PDEVICE_OBJECT      DeviceObject;
    NTSTATUS            Status = STATUS_UNSUCCESSFUL;
    PFSD_VCB            Vcb;
    PFILE_OBJECT        FileObject;
    PFSD_FCB            Fcb;
    PFSD_CCB            Ccb;
    PIRP                Irp;
    PIO_STACK_LOCATION  IrpSp;
    ULONG               Length;
    ULONG               ReturnedLength;
    LARGE_INTEGER       ByteOffset;
    BOOLEAN             PagingIo;
    BOOLEAN             Nocache;
    BOOLEAN             SynchronousIo;
    BOOLEAN             VcbResourceAcquired = FALSE;
    BOOLEAN             FcbMainResourceAcquired = FALSE;
    BOOLEAN             FcbPagingIoResourceAcquired = FALSE;
    PUCHAR              UserBuffer;
    PDEVICE_OBJECT      DeviceToVerify;

    __try
    {
        ASSERT(IrpContext);

        ASSERT((IrpContext->Identifier.Type == ICX) &&
               (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        if (DeviceObject == FsdGlobalData.DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Vcb = (PFSD_VCB) DeviceObject->DeviceExtension;

        ASSERT(Vcb != NULL);

        ASSERT((Vcb->Identifier.Type == VCB) &&
               (Vcb->Identifier.Size == sizeof(FSD_VCB)));

        FileObject = IrpContext->FileObject;

        Fcb = (PFSD_FCB) FileObject->FsContext;

        ASSERT(Fcb);

        if (Fcb->Identifier.Type == VCB)
        {
            Irp = IrpContext->Irp;

            IrpSp = IoGetCurrentIrpStackLocation(Irp);

            Length = IrpSp->Parameters.Read.Length;
            ByteOffset = IrpSp->Parameters.Read.ByteOffset;

            PagingIo = FlagOn(Irp->Flags, IRP_PAGING_IO);
            Nocache = FlagOn(Irp->Flags, IRP_NOCACHE);
            SynchronousIo = FlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);

            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;
                __leave;
            }

            if (!ExAcquireResourceSharedLite(
                     &Vcb->MainResource,
                     IrpContext->IsSynchronous
                     ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            VcbResourceAcquired = TRUE;

            if (ByteOffset.QuadPart >=

#ifndef FSD_RO
                Vcb->PartitionInformation.PartitionLength.QuadPart
#else
                be32_to_cpu(Vcb->romfs_super_block->size)
#endif
                )
            {
                Irp->IoStatus.Information = 0;
                Status = STATUS_END_OF_FILE;
                __leave;
            }

            if ((ByteOffset.QuadPart + Length) >

#ifndef FSD_RO
                 Vcb->PartitionInformation.PartitionLength.QuadPart
#else
                 be32_to_cpu(Vcb->romfs_super_block->size)
#endif
                 )
            {
                Length = (ULONG) (
#ifndef FSD_RO
                Vcb->PartitionInformation.PartitionLength.QuadPart -
#else
                be32_to_cpu(Vcb->romfs_super_block->size) -
#endif
                ByteOffset.QuadPart);

                Length &= ~(SECTOR_SIZE - 1);
            }

            UserBuffer = FsdGetUserBuffer(Irp);

            if (UserBuffer == NULL)
            {
                Status = STATUS_INVALID_USER_BUFFER;
                __leave;
            }

            Status = FsdReadBlockDevice(
                Vcb->TargetDeviceObject,
                &ByteOffset,
                Length,
                UserBuffer
                );

            if (Status == STATUS_VERIFY_REQUIRED)
            {
                Status = IoVerifyVolume(Vcb->TargetDeviceObject, FALSE);

                if (NT_SUCCESS(Status))
                {
                    Status = FsdReadBlockDevice(
                        Vcb->TargetDeviceObject,
                        &ByteOffset,
                        Length,
                        UserBuffer
                        );
                }
            }

            if (NT_SUCCESS(Status))
            {
                Irp->IoStatus.Information = Length;
            }

            __leave;
        }

        ASSERT((Fcb->Identifier.Type == FCB) &&
               (Fcb->Identifier.Size == sizeof(FSD_FCB)));

        if (FlagOn(Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
        {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }

        Ccb = (PFSD_CCB) FileObject->FsContext2;

        ASSERT(Ccb);

        ASSERT((Ccb->Identifier.Type == CCB) &&
               (Ccb->Identifier.Size == sizeof(FSD_CCB)));

        Irp = IrpContext->Irp;

        IrpSp = IoGetCurrentIrpStackLocation(Irp);

        Length = IrpSp->Parameters.Read.Length;
        ByteOffset = IrpSp->Parameters.Read.ByteOffset;

        PagingIo = FlagOn(Irp->Flags, IRP_PAGING_IO);
        Nocache = FlagOn(Irp->Flags, IRP_NOCACHE);
        SynchronousIo = FlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);

        if (Irp->RequestorMode != KernelMode &&
            !Irp->MdlAddress &&
            Irp->UserBuffer)
        {
            ProbeForWrite(Irp->UserBuffer, Length, 1);
        }

        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;
            __leave;
        }

        if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC))
        {
            ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
            Status = STATUS_PENDING;
            __leave;
        }

        if (!PagingIo)
        {
            if (!ExAcquireResourceSharedLite(
                     &Fcb->MainResource,
                     IrpContext->IsSynchronous
                     ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            FcbMainResourceAcquired = TRUE;
        }
        else
        {
            if (!ExAcquireResourceSharedLite(
                     &Fcb->PagingIoResource,
                     IrpContext->IsSynchronous
                     ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            FcbPagingIoResourceAcquired = TRUE;
        }

        if (ByteOffset.QuadPart >= be32_to_cpu(Fcb->romfs_inode->size))
        {
            Irp->IoStatus.Information = 0;
            Status = STATUS_END_OF_FILE;
            __leave;
        }

        if (!PagingIo)
        {
            if (!FsRtlCheckLockForReadAccess(
                    &Fcb->FileLock,
                    Irp
                    ))
            {
                Status = STATUS_FILE_LOCK_CONFLICT;
                __leave;
            }
        }

        if (!Nocache)
        {
            if ((ByteOffset.QuadPart + Length) >
                 be32_to_cpu(Fcb->romfs_inode->size))
            {
                Length =
                    be32_to_cpu(Fcb->romfs_inode->size) - ByteOffset.LowPart;
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -