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

📄 dirctl.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * COPYRIGHT:        See COPYRIGHT.TXT
 * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
 * FILE:             dirctl.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, Ext2GetInfoLength)
#pragma alloc_text(PAGE, Ext2ProcessDirEntry)
#pragma alloc_text(PAGE, Ext2QueryDirectory)
#pragma alloc_text(PAGE, Ext2NotifyChangeDirectory)
#pragma alloc_text(PAGE, Ext2DirectoryControl)
#endif

ULONG
Ext2GetInfoLength(IN FILE_INFORMATION_CLASS  FileInformationClass)
{
    switch (FileInformationClass)
    {
    case FileDirectoryInformation:
        return sizeof(FILE_DIRECTORY_INFORMATION);
        break;
        
    case FileFullDirectoryInformation:
        return sizeof(FILE_FULL_DIR_INFORMATION);
        break;
        
    case FileBothDirectoryInformation:
        return sizeof(FILE_BOTH_DIR_INFORMATION);
        break;
        
    case FileNamesInformation:
        return sizeof(FILE_NAMES_INFORMATION);
        break;
        
    default:
        break;
    }

    return 0;
}

/*
#define FillInfo (FI, BSize, Inode, Index, NSize, pName, Single) {\
    if (!Single) \
        FI->NextEntryOffset = BSize + NSize - sizeof(WCHAR); \
    else \
            FI->NextEntryOffset = 0; \
    FI->FileIndex = Index; \
    FI->CreationTime.QuadPart = Inode.i_ctime; \
    FI->LastAccessTime.QuadPart = Inode.i_atime; \
    FI->LastWriteTime.QuadPart = Inode.i_mtime; \
    FI->ChangeTime.QuadPart = Inode.i_mtime; \
    FI->EndOfFile.QuadPart = Inode.i_size; \
    FI->AllocationSize.QuadPart = Inode.i_size; \
    FI->LastAccessTime.QuadPart = Inode.i_atime; \
    FI->FileAttributes = FILE_ATTRIBUTE_NORMAL; \
    if (S_ISDIR(Inode->i_mode)) \
        FI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; \
    FI->FileNameLength = NSize; \
    RtlCopyMemory(FI->FileName, pName->Buffer, NSize); \
    dwBytes = BSize + NSize - sizeof(WCHAR); }
*/

ULONG
Ext2ProcessDirEntry(IN PEXT2_VCB         Vcb,
            IN FILE_INFORMATION_CLASS  FileInformationClass,
            IN ULONG         in,
            IN PVOID         Buffer,
            IN ULONG         UsedLength,
            IN ULONG         Length,
            IN ULONG         FileIndex,
            IN PUNICODE_STRING   pName,
            IN BOOLEAN       Single )
{
    EXT2_INODE inode;
    PFILE_DIRECTORY_INFORMATION FDI;
    PFILE_FULL_DIR_INFORMATION FFI;
    PFILE_BOTH_DIR_INFORMATION FBI;
    PFILE_NAMES_INFORMATION FNI;

    ULONG InfoLength = 0;
    ULONG NameLength = 0;
    ULONG dwBytes = 0;

    NameLength = pName->Length;

    if (!in)
    {
        Ext2DbgPrint(D_DIRCTL, "Ext2PricessDirEntry: ext2_dir_entry is empty.\n");
        return 0;
    }

    InfoLength = Ext2GetInfoLength(FileInformationClass);
    if (!InfoLength || InfoLength + NameLength - sizeof(WCHAR)> Length)
    {
        Ext2DbgPrint(D_DIRCTL, "Ext2PricessDirEntry: Size/Length error.\n");
        return 0;
    }

    if(!Ext2LoadInode(Vcb, in, &inode))
    {
        Ext2DbgPrint(D_DIRCTL, "Ext2PricessDirEntry: Loading inode %xh error.\n", in);
        return 0;
    }

    switch(FileInformationClass)
    {
    case FileDirectoryInformation:
        FDI = (PFILE_DIRECTORY_INFORMATION) ((PUCHAR)Buffer + UsedLength);
        if (!Single)
            FDI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR);
        else
            FDI->NextEntryOffset = 0;
        FDI->FileIndex = FileIndex;
        FDI->CreationTime = Ext2SysTime(inode.i_ctime);
        FDI->LastAccessTime = Ext2SysTime(inode.i_atime);
        FDI->LastWriteTime = Ext2SysTime(inode.i_mtime);
        FDI->ChangeTime = Ext2SysTime(inode.i_mtime);
        FDI->EndOfFile.QuadPart = inode.i_size;
        FDI->AllocationSize.QuadPart = inode.i_size;
        FDI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

        if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || Ext2IsReadOnly(inode.i_mode))
        {
            SetFlag(FDI->FileAttributes, FILE_ATTRIBUTE_READONLY);
        }

        if (S_ISDIR(inode.i_mode))
            FDI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

        FDI->FileNameLength = NameLength;
        RtlCopyMemory(FDI->FileName, pName->Buffer, NameLength);
        dwBytes = InfoLength + NameLength - sizeof(WCHAR); 
        break;
        
    case FileFullDirectoryInformation:
        FFI = (PFILE_FULL_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength);
//      FillInfo (FFI, InfoLength, inode, FileIndex, NameLength, pName, Single)
        if (!Single)
            FFI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR);
        else
            FFI->NextEntryOffset = 0;
        FFI->FileIndex = FileIndex;
        FFI->CreationTime = Ext2SysTime(inode.i_ctime);
        FFI->LastAccessTime = Ext2SysTime(inode.i_atime);
        FFI->LastWriteTime = Ext2SysTime(inode.i_mtime);
        FFI->ChangeTime = Ext2SysTime(inode.i_mtime);
        FFI->EndOfFile.QuadPart = inode.i_size;
        FFI->AllocationSize.QuadPart = inode.i_size;
        FFI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

        if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)  || Ext2IsReadOnly(inode.i_mode))
        {
            SetFlag(FFI->FileAttributes, FILE_ATTRIBUTE_READONLY);
        }

        if (S_ISDIR(inode.i_mode))
            FFI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

        FFI->FileNameLength = NameLength;
        RtlCopyMemory(FFI->FileName, pName->Buffer, NameLength);
        dwBytes = InfoLength + NameLength - sizeof(WCHAR); 

        break;
        
    case FileBothDirectoryInformation:
        FBI = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength);
//      FillInfo (FBI, InfoLength, inode, FileIndex, NameLength, pName, Single)
        if (!Single)
            FBI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR);
        else
            FBI->NextEntryOffset = 0;
        FBI->CreationTime = Ext2SysTime(inode.i_ctime);
        FBI->LastAccessTime = Ext2SysTime(inode.i_atime);
        FBI->LastWriteTime = Ext2SysTime(inode.i_mtime);
        FBI->ChangeTime = Ext2SysTime(inode.i_mtime);

/*
        FBI->CreationTime.QuadPart = inode.i_ctime;
        FBI->LastAccessTime.QuadPart = inode.i_atime;
        FBI->LastWriteTime.QuadPart = inode.i_mtime;
        FBI->ChangeTime.QuadPart = inode.i_mtime;
*/
        FBI->EndOfFile.QuadPart = inode.i_size;
        FBI->AllocationSize.QuadPart = inode.i_size;
        FBI->FileAttributes = FILE_ATTRIBUTE_NORMAL;

        if (FlagOn(Vcb->Flags, VCB_READ_ONLY)  || Ext2IsReadOnly(inode.i_mode))
        {
            SetFlag(FBI->FileAttributes, FILE_ATTRIBUTE_READONLY);
        }

        if (S_ISDIR(inode.i_mode))
            FBI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
        FBI->FileNameLength = NameLength;
        RtlCopyMemory(FBI->FileName, pName->Buffer, NameLength);
        dwBytes = InfoLength + NameLength - sizeof(WCHAR); 

        break;
        
    case FileNamesInformation:
        FNI = (PFILE_NAMES_INFORMATION) ((PUCHAR)Buffer + UsedLength);
        if (!Single)
            FNI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR);
        else
            FNI->NextEntryOffset = 0;
        FNI->FileNameLength = NameLength;
        RtlCopyMemory(FNI->FileName, pName->Buffer, NameLength);
        dwBytes = InfoLength + NameLength - sizeof(WCHAR); 

        break;
        
    default:
        break;
    }

    return dwBytes;
}


NTSTATUS
Ext2QueryDirectory (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PEXT2_VCB               Vcb;
    PFILE_OBJECT            FileObject;
    PEXT2_FCB               Fcb;
    PEXT2_CCB               Ccb;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IoStackLocation;
    FILE_INFORMATION_CLASS  FileInformationClass;
    ULONG                   Length;
    PUNICODE_STRING         FileName;
    ULONG                   FileIndex;
    BOOLEAN                 RestartScan;
    BOOLEAN                 ReturnSingleEntry;
    BOOLEAN                 IndexSpecified;
    PUCHAR                  Buffer;
    BOOLEAN                 FirstQuery;
    PEXT2_INODE             Inode = NULL;
    BOOLEAN                 FcbResourceAcquired = FALSE;
    ULONG                   UsedLength = 0;
    USHORT                  InodeFileNameLength;
    UNICODE_STRING          InodeFileName;
    PEXT2_DIR_ENTRY2        pDir = NULL;
    ULONG                   dwBytes;
    ULONG                   dwTemp = 0;
    ULONG                   dwSize = 0;
    ULONG                   dwReturn = 0;
    BOOLEAN                 bRun = TRUE;
    ULONG                   ByteOffset;

    InodeFileName.Buffer = NULL;
    
    __try
    {
        ASSERT(IrpContext);
        
        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;
        }
        
        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
            (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
        
        FileObject = IrpContext->FileObject;
        
        Fcb = (PEXT2_FCB) FileObject->FsContext;
        
        ASSERT(Fcb);
        
        //
        // 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 (!FlagOn(Fcb->Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
        {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }
        
        Ccb = (PEXT2_CCB) FileObject->FsContext2;
        
        ASSERT(Ccb);
        
        ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
            (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
        
        Irp = IrpContext->Irp;
        
        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
        
#ifndef _GNU_NTIFS_
        
        FileInformationClass =
            IoStackLocation->Parameters.QueryDirectory.FileInformationClass;
        
        Length = IoStackLocation->Parameters.QueryDirectory.Length;
        
        FileName = IoStackLocation->Parameters.QueryDirectory.FileName;
        
        FileIndex = IoStackLocation->Parameters.QueryDirectory.FileIndex;
        
#else // _GNU_NTIFS_
        
        FileInformationClass = ((PEXTENDED_IO_STACK_LOCATION)
            IoStackLocation)->Parameters.QueryDirectory.FileInformationClass;
        
        Length = ((PEXTENDED_IO_STACK_LOCATION)
            IoStackLocation)->Parameters.QueryDirectory.Length;
        
        FileName = ((PEXTENDED_IO_STACK_LOCATION)
            IoStackLocation)->Parameters.QueryDirectory.FileName;
        
        FileIndex = ((PEXTENDED_IO_STACK_LOCATION)
            IoStackLocation)->Parameters.QueryDirectory.FileIndex;
        
#endif // _GNU_NTIFS_
        
        RestartScan = FlagOn(((PEXTENDED_IO_STACK_LOCATION)
            IoStackLocation)->Flags, SL_RESTART_SCAN);
        ReturnSingleEntry = FlagOn(((PEXTENDED_IO_STACK_LOCATION)
            IoStackLocation)->Flags, SL_RETURN_SINGLE_ENTRY);
        IndexSpecified = FlagOn(((PEXTENDED_IO_STACK_LOCATION)
            IoStackLocation)->Flags, SL_INDEX_SPECIFIED);
/*
        if (!Irp->MdlAddress && Irp->UserBuffer)
        {
            ProbeForWrite(Irp->UserBuffer, Length, 1);
        }
*/
        Buffer = Ext2GetUserBuffer(Irp);

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

        FcbResourceAcquired = TRUE;
        
        if (FileName != NULL)
        {
    
            if (Ccb->DirectorySearchPattern.Buffer != NULL)
            {
                FirstQuery = FALSE;
            }
            else
            {
                FirstQuery = TRUE;
                
                Ccb->DirectorySearchPattern.Length =
                    Ccb->DirectorySearchPattern.MaximumLength =
                    FileName->Length;
                
                Ccb->DirectorySearchPattern.Buffer =
                    ExAllocatePool(PagedPool, FileName->Length);
                
                if (Ccb->DirectorySearchPattern.Buffer == NULL)
                {
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                    __leave;
                }

                Status = RtlUpcaseUnicodeString(
                    &(Ccb->DirectorySearchPattern),
                    FileName,
                    FALSE);

                if (!NT_SUCCESS(Status))
                    __leave;
            }
        }
        else if (Ccb->DirectorySearchPattern.Buffer != NULL)
        {
            FirstQuery = FALSE;
            FileName = &Ccb->DirectorySearchPattern;
        }
        else
        {
            FirstQuery = TRUE;
            
            Ccb->DirectorySearchPattern.Length =
                Ccb->DirectorySearchPattern.MaximumLength = 2;
            
            Ccb->DirectorySearchPattern.Buffer =
                ExAllocatePool(PagedPool, 2);
            
            if (Ccb->DirectorySearchPattern.Buffer == NULL)

⌨️ 快捷键说明

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