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

📄 fastio.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"

#pragma code_seg(FSD_PAGED_CODE)

BOOLEAN
FsdFastIoCheckIfPossible (
    IN PFILE_OBJECT         FileObject,
    IN PLARGE_INTEGER       FileOffset,
    IN ULONG                Length,
    IN BOOLEAN              Wait,
    IN ULONG                LockKey,
    IN BOOLEAN              CheckForReadOperation,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject
    )
{
    BOOLEAN         Status = FALSE;
    PFSD_FCB        Fcb;
    LARGE_INTEGER   LargeLength;

    LargeLength.QuadPart = Length;

    __try
    {
        __try
        {
            FsRtlEnterFileSystem();

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

            Fcb = (PFSD_FCB) FileObject->FsContext;

            ASSERT(Fcb != NULL);

            if (Fcb->Identifier.Type == VCB)
            {
                Status = FALSE;
                __leave;
            }

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

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

            if (CheckForReadOperation)
            {
                Status = FsRtlFastCheckLockForRead(
                    &Fcb->FileLock,
                    FileOffset,
                    &LargeLength,
                    LockKey,
                    FileObject,
                    PsGetCurrentProcess()
                    );
            }
            else
            {
#ifndef FSD_RO
                Status = FsRtlFastCheckLockForWrite(
                    &Fcb->FileLockAnchor,
                    FileOffset,
                    &LargeLength,
                    LockKey,
                    FileObject,
                    PsGetCurrentProcess()
                    );
#else
                Status = FALSE;
#endif
            }

            KdPrint((
                DRIVER_NAME ": %-16.16s %-31s %s\n",
                FsdGetCurrentProcessName(),
                "FASTIO_CHECK_IF_POSSIBLE",
                Fcb->AnsiFileName.Buffer
                ));

            KdPrint((
                DRIVER_NAME ": Offset: %I64u Length: %u Key: %u %s %s\n",
                FileOffset->QuadPart,
                Length,
                LockKey,
                (CheckForReadOperation ? "CheckForReadOperation:" : "CheckForWriteOperation:"),
                (Status ? "Succeeded" : "Failed")
                ));
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            Status = FALSE;
        }
    }
    __finally
    {
        FsRtlExitFileSystem();
    }

    return Status;
}

//
// When not debugging the fast I/O read entry point is set directly to
// FsRtlCopyRead.
//

#if DBG

BOOLEAN
FsdFastIoRead (
    IN PFILE_OBJECT         FileObject,
    IN PLARGE_INTEGER       FileOffset,
    IN ULONG                Length,
    IN BOOLEAN              Wait,
    IN ULONG                LockKey,
    OUT PVOID               Buffer,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject
    )
{
    BOOLEAN     Status;
    PFSD_FCB    Fcb;

    Fcb = (PFSD_FCB) FileObject->FsContext;

    ASSERT(Fcb != NULL);

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

    KdPrint((
        DRIVER_NAME ": %-16.16s %-31s %s\n",
        FsdGetCurrentProcessName(),
        "FASTIO_READ",
        Fcb->AnsiFileName.Buffer
        ));

    KdPrint((
        DRIVER_NAME ": Offset: %I64u Length: %u Key: %u\n",
        FileOffset->QuadPart,
        Length,
        LockKey
        ));

    Status = FsRtlCopyRead (
        FileObject,
        FileOffset,
        Length,
        Wait,
        LockKey,
        Buffer,
        IoStatus,
        DeviceObject
        );

    if (Status == FALSE)
    {
        KdPrint((
            DRIVER_NAME ": %-16.16s %-31s *** Status: FALSE ***\n",
            FsdGetCurrentProcessName(),
            "FASTIO_READ"
            ));
    }
    else if (IoStatus->Status != STATUS_SUCCESS)
    {
        KdPrint((
            DRIVER_NAME ": %-16.16s %-31s *** Status: %s (%#x) ***\n",
            FsdGetCurrentProcessName(),
            "FASTIO_READ",
            FsdNtStatusToString(IoStatus->Status),
            IoStatus->Status
            ));
    }

    return Status;
}

#endif // DBG

BOOLEAN
FsdFastIoQueryBasicInfo (
    IN PFILE_OBJECT             FileObject,
    IN BOOLEAN                  Wait,
    OUT PFILE_BASIC_INFORMATION Buffer,
    OUT PIO_STATUS_BLOCK        IoStatus,
    IN PDEVICE_OBJECT           DeviceObject
    )
{
    BOOLEAN     Status = FALSE;
    PFSD_FCB    Fcb;
    BOOLEAN     FcbMainResourceAcquired = FALSE;

    __try
    {
        __try
        {
            FsRtlEnterFileSystem();

            if (DeviceObject == FsdGlobalData.DeviceObject)
            {
                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                Status = TRUE;
                __leave;
            }

            Fcb = (PFSD_FCB) FileObject->FsContext;

            ASSERT(Fcb != NULL);

            if (Fcb->Identifier.Type == VCB)
            {
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                Status = TRUE;
                __leave;
            }

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

            KdPrint((
                DRIVER_NAME ": %-16.16s %-31s %s\n",
                FsdGetCurrentProcessName(),
                "FASTIO_QUERY_BASIC_INFO",
                Fcb->AnsiFileName.Buffer
                ));

            if (!ExAcquireResourceSharedLite(
                    &Fcb->MainResource,
                    Wait
                    ))
            {
                Status = FALSE;
                __leave;
            }

            FcbMainResourceAcquired = TRUE;

            RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION));

/*
            typedef struct _FILE_BASIC_INFORMATION {
                LARGE_INTEGER   CreationTime;
                LARGE_INTEGER   LastAccessTime;
                LARGE_INTEGER   LastWriteTime;
                LARGE_INTEGER   ChangeTime;
                ULONG           FileAttributes;
            } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
*/

            Buffer->CreationTime.QuadPart = 0;

            Buffer->LastAccessTime.QuadPart = 0;

            Buffer->LastWriteTime.QuadPart = 0;

            Buffer->ChangeTime.QuadPart = 0;

            Buffer->FileAttributes = Fcb->FileAttributes;

            IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);

            IoStatus->Status = STATUS_SUCCESS;

            Status =  TRUE;
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            IoStatus->Status = GetExceptionCode();
            Status = TRUE;
        }
    }
    __finally
    {
        if (FcbMainResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }

        FsRtlExitFileSystem();
    }

    if (Status == FALSE)
    {
        KdPrint((
            DRIVER_NAME ": %-16.16s %-31s *** Status: FALSE ***\n",
            FsdGetCurrentProcessName(),
            "FASTIO_QUERY_BASIC_INFO"
            ));
    }
    else if (IoStatus->Status != STATUS_SUCCESS)
    {
        KdPrint((
            DRIVER_NAME ": %-16.16s %-31s *** Status: %s (%#x) ***\n",
            FsdGetCurrentProcessName(),
            "FASTIO_QUERY_BASIC_INFO",
            FsdNtStatusToString(IoStatus->Status),
            IoStatus->Status
            ));
    }

    return Status;
}

BOOLEAN
FsdFastIoQueryStandardInfo (
    IN PFILE_OBJECT                 FileObject,
    IN BOOLEAN                      Wait,
    OUT PFILE_STANDARD_INFORMATION  Buffer,
    OUT PIO_STATUS_BLOCK            IoStatus,
    IN PDEVICE_OBJECT               DeviceObject
    )
{
    BOOLEAN     Status = FALSE;
    PFSD_FCB    Fcb;
    BOOLEAN     FcbMainResourceAcquired = FALSE;

    __try
    {
        __try
        {
            FsRtlEnterFileSystem();

            if (DeviceObject == FsdGlobalData.DeviceObject)
            {
                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                Status = TRUE;
                __leave;
            }

            Fcb = (PFSD_FCB) FileObject->FsContext;

            ASSERT(Fcb != NULL);

            if (Fcb->Identifier.Type == VCB)
            {
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                Status = TRUE;
                __leave;
            }

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

            KdPrint((
                DRIVER_NAME ": %-16.16s %-31s %s\n",
                FsdGetCurrentProcessName(),
                "FASTIO_QUERY_STANDARD_INFO",
                Fcb->AnsiFileName.Buffer
                ));

            if (!ExAcquireResourceSharedLite(
                    &Fcb->MainResource,
                    Wait
                    ))
            {
                Status = FALSE;
                __leave;
            }

            FcbMainResourceAcquired = TRUE;

            RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION));

/*
            typedef struct _FILE_STANDARD_INFORMATION {
                LARGE_INTEGER   AllocationSize;
                LARGE_INTEGER   EndOfFile;
                ULONG           NumberOfLinks;
                BOOLEAN         DeletePending;
                BOOLEAN         Directory;
            } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
*/

            Buffer->AllocationSize.QuadPart =
                be32_to_cpu(Fcb->romfs_inode->size);

            Buffer->EndOfFile.QuadPart =
                be32_to_cpu(Fcb->romfs_inode->size);

            Buffer->NumberOfLinks = 1;

#ifndef FSD_RO
            Buffer->DeletePending = FlagOn(Fcb->Flags, FCB_DELETE_PENDING);
#else
            Buffer->DeletePending = FALSE;
#endif

            Buffer->Directory = FlagOn(Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY);

            IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);

            IoStatus->Status = STATUS_SUCCESS;

            Status =  TRUE;
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            IoStatus->Status = GetExceptionCode();
            Status = TRUE;
        }
    }
    __finally
    {
        if (FcbMainResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }

        FsRtlExitFileSystem();
    }

    if (Status == FALSE)
    {
        KdPrint((
            DRIVER_NAME ": %-16.16s %-31s *** Status: FALSE ***\n",
            FsdGetCurrentProcessName(),
            "FASTIO_QUERY_STANDARD_INFO"
            ));
    }
    else if (IoStatus->Status != STATUS_SUCCESS)
    {
        KdPrint((
            DRIVER_NAME ": %-16.16s %-31s *** Status: %s (%#x) ***\n",
            FsdGetCurrentProcessName(),
            "FASTIO_QUERY_STANDARD_INFO",
            FsdNtStatusToString(IoStatus->Status),
            IoStatus->Status
            ));
    }

    return Status;
}

BOOLEAN
FsdFastIoLock (
    IN PFILE_OBJECT         FileObject,
    IN PLARGE_INTEGER       FileOffset,
    IN PLARGE_INTEGER       Length,
    IN PEPROCESS            Process,
    IN ULONG                Key,
    IN BOOLEAN              FailImmediately,
    IN BOOLEAN              ExclusiveLock,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject
    )
{
    BOOLEAN     Status = FALSE;
    PFSD_FCB    Fcb;

    __try
    {
        __try
        {
            FsRtlEnterFileSystem();

            if (DeviceObject == FsdGlobalData.DeviceObject)
            {
                IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
                Status = TRUE;
                __leave;
            }

            Fcb = (PFSD_FCB) FileObject->FsContext;

            ASSERT(Fcb != NULL);

            if (Fcb->Identifier.Type == VCB)
            {
                IoStatus->Status = STATUS_INVALID_PARAMETER;
                Status = TRUE;
                __leave;
            }

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

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

            KdPrint((
                DRIVER_NAME ": %-16.16s %-31s %s\n",
                (PUCHAR) Process + ProcessNameOffset,

⌨️ 快捷键说明

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