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

📄 fileinfo.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
FsdQueryInformation (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PFILE_OBJECT            FileObject;
    PFSD_FCB                Fcb;
    PFSD_CCB                Ccb;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IrpSp;
    FILE_INFORMATION_CLASS  FileInformationClass;
    ULONG                   Length;
    PVOID                   SystemBuffer;
    BOOLEAN                 FcbResourceAcquired = FALSE;

    __try
    {
        ASSERT(IrpContext != NULL);

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

        FileObject = IrpContext->FileObject;

        Fcb = (PFSD_FCB) FileObject->FsContext;

        ASSERT(Fcb != NULL);

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

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

#ifndef FSD_RO
        if (!FlagOn(Fcb->Flags, FCB_PAGE_FILE))
#endif
        {
            if (!ExAcquireResourceSharedLite(
                     &Fcb->MainResource,
                     IrpContext->IsSynchronous
                     ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            FcbResourceAcquired = TRUE;
        }

        Ccb = (PFSD_CCB) FileObject->FsContext2;

        ASSERT(Ccb != NULL);

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

        Irp = IrpContext->Irp;

        IrpSp = IoGetCurrentIrpStackLocation(Irp);

        FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass;

        Length = IrpSp->Parameters.QueryFile.Length;

        SystemBuffer = Irp->AssociatedIrp.SystemBuffer;

        RtlZeroMemory(SystemBuffer, Length);

        switch (FileInformationClass)
        {
        case FileBasicInformation:
            {
                PFILE_BASIC_INFORMATION Buffer;

                if (Length < sizeof(FILE_BASIC_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                Buffer = (PFILE_BASIC_INFORMATION) SystemBuffer;

/*
                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;

                Irp->IoStatus.Information = sizeof(FILE_BASIC_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }

        case FileStandardInformation:
            {
                PFILE_STANDARD_INFORMATION Buffer;

                if (Length < sizeof(FILE_STANDARD_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                Buffer = (PFILE_STANDARD_INFORMATION) SystemBuffer;

/*
                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);

                Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }

        case FileInternalInformation:
            {
                PFILE_INTERNAL_INFORMATION Buffer;

                if (Length < sizeof(FILE_INTERNAL_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                Buffer = (PFILE_INTERNAL_INFORMATION) SystemBuffer;

/*
                typedef struct _FILE_INTERNAL_INFORMATION {
                    LARGE_INTEGER IndexNumber;
                } FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
*/

                // The "inode number"
                Buffer->IndexNumber = Fcb->IndexNumber;

                Irp->IoStatus.Information = sizeof(FILE_INTERNAL_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }

        case FileEaInformation:
            {
                PFILE_EA_INFORMATION Buffer;

                if (Length < sizeof(FILE_EA_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                Buffer = (PFILE_EA_INFORMATION) SystemBuffer;

/*
                typedef struct _FILE_EA_INFORMATION {
                    ULONG EaSize;
                } FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
*/

                // Romfs doesn't have any extended attributes
                Buffer->EaSize = 0;

                Irp->IoStatus.Information = sizeof(FILE_EA_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }

        case FileNameInformation:
            {
                PFILE_NAME_INFORMATION Buffer;

                if (Length < sizeof(FILE_NAME_INFORMATION) +
                    Fcb->FileName.Length - sizeof(WCHAR))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                Buffer = (PFILE_NAME_INFORMATION) SystemBuffer;

/*
                typedef struct _FILE_NAME_INFORMATION {
                    ULONG FileNameLength;
                    WCHAR FileName[1];
                } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
*/

                Buffer->FileNameLength = Fcb->FileName.Length;

                RtlCopyMemory(
                    Buffer->FileName,
                    Fcb->FileName.Buffer,
                    Fcb->FileName.Length
                    );

                Irp->IoStatus.Information = sizeof(FILE_NAME_INFORMATION) +
                    Fcb->FileName.Length - sizeof(WCHAR);
                Status = STATUS_SUCCESS;
                __leave;
            }

        case FilePositionInformation:
            {
                PFILE_POSITION_INFORMATION Buffer;

                if (Length < sizeof(FILE_POSITION_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                Buffer = (PFILE_POSITION_INFORMATION) SystemBuffer;

/*
                typedef struct _FILE_POSITION_INFORMATION {
                    LARGE_INTEGER CurrentByteOffset;
                } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
*/

                Buffer->CurrentByteOffset = FileObject->CurrentByteOffset;

                Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }

        case FileAllInformation:
            {
                PFILE_ALL_INFORMATION       FileAllInformation;
                PFILE_BASIC_INFORMATION     FileBasicInformation;
                PFILE_STANDARD_INFORMATION  FileStandardInformation;
                PFILE_INTERNAL_INFORMATION  FileInternalInformation;
                PFILE_EA_INFORMATION        FileEaInformation;
                PFILE_POSITION_INFORMATION  FilePositionInformation;
                PFILE_NAME_INFORMATION      FileNameInformation;

                if (Length < sizeof(FILE_ALL_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }

                FileAllInformation = (PFILE_ALL_INFORMATION) SystemBuffer;

/*
                typedef struct _FILE_ALL_INFORMATION {
                    FILE_BASIC_INFORMATION      BasicInformation;
                    FILE_STANDARD_INFORMATION   StandardInformation;
                    FILE_INTERNAL_INFORMATION   InternalInformation;
                    FILE_EA_INFORMATION         EaInformation;
                    FILE_ACCESS_INFORMATION     AccessInformation;
                    FILE_POSITION_INFORMATION   PositionInformation;
                    FILE_MODE_INFORMATION       ModeInformation;
                    FILE_ALIGNMENT_INFORMATION  AlignmentInformation;
                    FILE_NAME_INFORMATION       NameInformation;
                } FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
*/

                FileBasicInformation =
                    &FileAllInformation->BasicInformation;

                FileStandardInformation =
                    &FileAllInformation->StandardInformation;

                FileInternalInformation =
                    &FileAllInformation->InternalInformation;

                FileEaInformation =
                    &FileAllInformation->EaInformation;

                FilePositionInformation =
                    &FileAllInformation->PositionInformation;

                FileNameInformation =
                    &FileAllInformation->NameInformation;

                FileBasicInformation->CreationTime.QuadPart = 0;

                FileBasicInformation->LastAccessTime.QuadPart = 0;

                FileBasicInformation->LastWriteTime.QuadPart = 0;

                FileBasicInformation->ChangeTime.QuadPart = 0;

                FileBasicInformation->FileAttributes = Fcb->FileAttributes;

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

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

                FileStandardInformation->NumberOfLinks = 1;

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

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

                // The "inode number"
                FileInternalInformation->IndexNumber = Fcb->IndexNumber;

                // Romfs doesn't have any extended attributes
                FileEaInformation->EaSize = 0;

                FilePositionInformation->CurrentByteOffset =
                    FileObject->CurrentByteOffset;

                if (Length < sizeof(FILE_ALL_INFORMATION) +
                    Fcb->FileName.Length - sizeof(WCHAR))
                {

⌨️ 快捷键说明

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