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

📄 fileinfo.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * COPYRIGHT:        See COPYRIGHT.TXT
 * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
 * FILE:             fileinfo.c
 * PROGRAMMER:       Matt Wu <mattwu@163.com>
 * HOMEPAGE:         http://ext2.yeah.net
 * UPDATE HISTORY: 
 */

/* INCLUDES *****************************************************************/

#include "ntifs.h"
#include "ext2fs.h"

/* GLOBALS ***************************************************************/

extern PEXT2_GLOBAL gExt2Global;

/* DEFINITIONS *************************************************************/

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, Ext2QueryInformation)
#pragma alloc_text(PAGE, Ext2SetInformation)
#pragma alloc_text(PAGE, Ext2ExpandFileAllocation)
#pragma alloc_text(PAGE, Ext2TruncateFileAllocation)
#pragma alloc_text(PAGE, Ext2SetDispositionInfo)
#pragma alloc_text(PAGE, Ext2SetRenameInfo)
#endif


NTSTATUS
Ext2QueryInformation (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PFILE_OBJECT            FileObject;
    PEXT2_FCB               Fcb;
    PEXT2_CCB               Ccb;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IoStackLocation;
    FILE_INFORMATION_CLASS  FileInformationClass;
    ULONG                   Length;
    PVOID                   Buffer;
    BOOLEAN                 FcbResourceAcquired = FALSE;
    
    __try
    {
        ASSERT(IrpContext != NULL);
        
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
            (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
        
        DeviceObject = IrpContext->DeviceObject;
        
        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == gExt2Global->DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }
        
        FileObject = IrpContext->FileObject;
        
        Fcb = (PEXT2_FCB) FileObject->FsContext;
        
        ASSERT(Fcb != NULL);
        
        //
        // This request is not allowed on volumes
        //
        if (Fcb->Identifier.Type == EXT2VCB)
        {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }
        
        ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
            (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
        
        if (!IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) && !FlagOn(Fcb->Flags, FCB_PAGE_FILE))
        {
            if (!ExAcquireResourceSharedLite(
                &Fcb->MainResource,
                IrpContext->IsSynchronous
                ))
            {
                Status = STATUS_PENDING;
                __leave;
            }
            
            FcbResourceAcquired = TRUE;
        }
        
        Ccb = (PEXT2_CCB) FileObject->FsContext2;
        
        ASSERT(Ccb != NULL);
        
        ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
            (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
        
        Irp = IrpContext->Irp;
        
        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
        
        FileInformationClass =
            IoStackLocation->Parameters.QueryFile.FileInformationClass;
        
        Length = IoStackLocation->Parameters.QueryFile.Length;
        
        Buffer = Irp->AssociatedIrp.SystemBuffer;
        
        RtlZeroMemory(Buffer, Length);
        
        switch (FileInformationClass)
        {
        case FileBasicInformation:
            {
                PFILE_BASIC_INFORMATION FileBasicInformation;
                
                if (Length < sizeof(FILE_BASIC_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }
                
                FileBasicInformation = (PFILE_BASIC_INFORMATION) Buffer;
                
                FileBasicInformation->CreationTime = Ext2SysTime(Fcb->ext2_inode->i_ctime);
                
                FileBasicInformation->LastAccessTime = Ext2SysTime(Fcb->ext2_inode->i_atime);
                
                FileBasicInformation->LastWriteTime = Ext2SysTime(Fcb->ext2_inode->i_mtime);
                
                FileBasicInformation->ChangeTime = Ext2SysTime(Fcb->ext2_inode->i_mtime);
                
                FileBasicInformation->FileAttributes = Fcb->Ext2Mcb->FileAttr;
                
                Irp->IoStatus.Information = sizeof(FILE_BASIC_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }

#if (_WIN32_WINNT >= 0x0500)

        case FileAttributeTagInformation:
            {
                PFILE_ATTRIBUTE_TAG_INFORMATION FATI;
                
                if (Length < sizeof(FILE_ATTRIBUTE_TAG_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }
                
                FATI = (PFILE_ATTRIBUTE_TAG_INFORMATION) Buffer;
                
                FATI->FileAttributes = Fcb->Ext2Mcb->FileAttr;
                FATI->ReparseTag = 0;
                
                Irp->IoStatus.Information = sizeof(FILE_ATTRIBUTE_TAG_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }
#endif // (_WIN32_WINNT >= 0x0500)


        case FileStandardInformation:
            {
                PFILE_STANDARD_INFORMATION FileStandardInformation;
                
                if (Length < sizeof(FILE_STANDARD_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }
                
                FileStandardInformation = (PFILE_STANDARD_INFORMATION) Buffer;
                
                FileStandardInformation->AllocationSize.QuadPart =
                    (LONGLONG)(Fcb->ext2_inode->i_size);
                
                FileStandardInformation->EndOfFile.QuadPart =
                    (LONGLONG)(Fcb->ext2_inode->i_size);
                
                FileStandardInformation->NumberOfLinks = Fcb->ext2_inode->i_links_count;
                
                if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
                    FileStandardInformation->DeletePending = FALSE;
                else
                    FileStandardInformation->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);                
                
                if (Fcb->Ext2Mcb->FileAttr & FILE_ATTRIBUTE_DIRECTORY)
                {
                    FileStandardInformation->Directory = TRUE;
                }
                else
                {
                    FileStandardInformation->Directory = FALSE;
                }
                
                Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }
            
        case FileInternalInformation:
            {
                PFILE_INTERNAL_INFORMATION FileInternalInformation;
                
                if (Length < sizeof(FILE_INTERNAL_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }
                
                FileInternalInformation = (PFILE_INTERNAL_INFORMATION) Buffer;
                
                // The "inode number"
                FileInternalInformation->IndexNumber.QuadPart = (LONGLONG)Fcb->Ext2Mcb->Inode;
                
                Irp->IoStatus.Information = sizeof(FILE_INTERNAL_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }
            
        case FileEaInformation:
            {
                PFILE_EA_INFORMATION FileEaInformation;
                
                if (Length < sizeof(FILE_EA_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }
                
                FileEaInformation = (PFILE_EA_INFORMATION) Buffer;
                
                // Romfs doesn't have any extended attributes
                FileEaInformation->EaSize = 0;
                
                Irp->IoStatus.Information = sizeof(FILE_EA_INFORMATION);
                Status = STATUS_SUCCESS;
                __leave;
            }
            
        case FileNameInformation:
            {
                PFILE_NAME_INFORMATION FileNameInformation;
                
                if (Length < sizeof(FILE_NAME_INFORMATION) +
                    Fcb->Ext2Mcb->ShortName.Length - sizeof(WCHAR))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }
                
                FileNameInformation = (PFILE_NAME_INFORMATION) Buffer;
                
                FileNameInformation->FileNameLength = Fcb->Ext2Mcb->ShortName.Length;
                
                RtlCopyMemory(
                    FileNameInformation->FileName,
                    Fcb->Ext2Mcb->ShortName.Buffer,
                    Fcb->Ext2Mcb->ShortName.Length );
                
                Irp->IoStatus.Information = sizeof(FILE_NAME_INFORMATION) +
                    Fcb->Ext2Mcb->ShortName.Length - sizeof(WCHAR);
                Status = STATUS_SUCCESS;
                __leave;
            }
            
        case FilePositionInformation:
            {
                PFILE_POSITION_INFORMATION FilePositionInformation;
                
                if (Length < sizeof(FILE_POSITION_INFORMATION))
                {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    __leave;
                }
                
                FilePositionInformation = (PFILE_POSITION_INFORMATION) Buffer;
                
                FilePositionInformation->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) Buffer;
                
                FileBasicInformation =
                    &FileAllInformation->BasicInformation;
                
                FileStandardInformation =
                    &FileAllInformation->StandardInformation;
                
                FileInternalInformation =
                    &FileAllInformation->InternalInformation;
                
                FileEaInformation =
                    &FileAllInformation->EaInformation;
                
                FilePositionInformation =
                    &FileAllInformation->PositionInformation;
                
                FileNameInformation =
                    &FileAllInformation->NameInformation;
                
                FileBasicInformation->CreationTime = Ext2SysTime(Fcb->ext2_inode->i_ctime);
                
                FileBasicInformation->LastAccessTime = Ext2SysTime(Fcb->ext2_inode->i_atime);
                
                FileBasicInformation->LastWriteTime = Ext2SysTime(Fcb->ext2_inode->i_mtime);
                
                FileBasicInformation->ChangeTime = Ext2SysTime(Fcb->ext2_inode->i_mtime);
                
                FileBasicInformation->FileAttributes = Fcb->Ext2Mcb->FileAttr;
                
                FileStandardInformation->AllocationSize.QuadPart =
                    (LONGLONG)(Fcb->ext2_inode->i_size);
                
                FileStandardInformation->EndOfFile.QuadPart =
                    (LONGLONG)(Fcb->ext2_inode->i_size);
                
                FileStandardInformation->NumberOfLinks = Fcb->ext2_inode->i_links_count;

                if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
                    FileStandardInformation->DeletePending = FALSE;
                else
                    FileStandardInformation->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);
                
                if (FlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
                {
                    FileStandardInformation->Directory = TRUE;
                }
                else
                {
                    FileStandardInformation->Directory = FALSE;
                }
                
                // The "inode number"
                FileInternalInformation->IndexNumber.QuadPart = (LONGLONG)Fcb->Ext2Mcb->Inode;
                
                // Romfs doesn't have any extended attributes
                FileEaInformation->EaSize = 0;
                
                FilePositionInformation->CurrentByteOffset =
                    FileObject->CurrentByteOffset;
                
                if (Length < sizeof(FILE_ALL_INFORMATION) +
                    Fcb->Ext2Mcb->ShortName.Length - sizeof(WCHAR))
                {
                    Irp->IoStatus.Information = sizeof(FILE_ALL_INFORMATION);
                    Status = STATUS_BUFFER_OVERFLOW;
                    __leave;
                }
                
                FileNameInformation->FileNameLength = Fcb->Ext2Mcb->ShortName.Length;
                
                RtlCopyMemory(
                    FileNameInformation->FileName,
                    Fcb->Ext2Mcb->ShortName.Buffer,
                    Fcb->Ext2Mcb->ShortName.Length
                    );
                
                Irp->IoStatus.Information = sizeof(FILE_ALL_INFORMATION) +
                    Fcb->Ext2Mcb->ShortName.Length - sizeof(WCHAR);
                Status = STATUS_SUCCESS;
                __leave;
            }
        
        /*
        case FileAlternateNameInformation:
            {
        // TODO: Handle FileAlternateNameInformation
        
          // Here we would like to use RtlGenerate8dot3Name but I don't
          // know how to use the argument PGENERATE_NAME_CONTEXT
          }
          */
          
        case FileNetworkOpenInformation:
        {
            PFILE_NETWORK_OPEN_INFORMATION FileNetworkOpenInformation;
            
            if (Length < sizeof(FILE_NETWORK_OPEN_INFORMATION))
            {
                Status = STATUS_INFO_LENGTH_MISMATCH;
                __leave;
            }
            
            FileNetworkOpenInformation =
                (PFILE_NETWORK_OPEN_INFORMATION) Buffer;
            

⌨️ 快捷键说明

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