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

📄 memory.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * COPYRIGHT:        See COPYRIGHT.TXT
 * PROJECT:          Ext2 File System Driver for WinNT/2K/XP
 * FILE:             memory.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, Ext2AllocateIrpContext)
#pragma alloc_text(PAGE, Ext2FreeIrpContext)
#pragma alloc_text(PAGE, Ext2AllocateFcb)
#pragma alloc_text(PAGE, Ext2FreeFcb)
#pragma alloc_text(PAGE, Ext2AllocateMcb)
#pragma alloc_text(PAGE, Ext2SearchMcbTree)
#pragma alloc_text(PAGE, Ext2SearchMcb)
#pragma alloc_text(PAGE, Ext2GetFullFileName)
#pragma alloc_text(PAGE, Ext2AddMcbNode)
#pragma alloc_text(PAGE, Ext2DeleteMcbNode)
#pragma alloc_text(PAGE, Ext2GetMcbDepth)
#pragma alloc_text(PAGE, Ext2CompareMcb)
#pragma alloc_text(PAGE, Ext2FindUnusedMcb)
#pragma alloc_text(PAGE, Ext2FreeMcbTree)
#pragma alloc_text(PAGE, Ext2CheckBitmapConsistency)
#pragma alloc_text(PAGE, Ext2CheckSetBlock)
#pragma alloc_text(PAGE, Ext2InitializeVcb)
#pragma alloc_text(PAGE, Ext2FreeCcb)
#pragma alloc_text(PAGE, Ext2AllocateCcb)
#pragma alloc_text(PAGE, Ext2FreeVcb)
#pragma alloc_text(PAGE, Ext2CreateFcbFromMcb)
#endif


PEXT2_IRP_CONTEXT
Ext2AllocateIrpContext (IN PDEVICE_OBJECT   DeviceObject,
                        IN PIRP             Irp )
{
    PIO_STACK_LOCATION  IoStackLocation;
    PEXT2_IRP_CONTEXT    IrpContext;
    
    ASSERT(DeviceObject != NULL);
    ASSERT(Irp != NULL);
    
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
    
    IrpContext = (PEXT2_IRP_CONTEXT) (ExAllocateFromNPagedLookasideList( &(gExt2Global->Ext2IrpContextLookasideList)));

    if (IrpContext == NULL) {

        IrpContext = ExAllocatePool( NonPagedPool, sizeof(EXT2_IRP_CONTEXT) );

        //
        //  Zero out the irp context and indicate that it is from pool and
        //  not region allocated
        //

        RtlZeroMemory(IrpContext, sizeof(EXT2_IRP_CONTEXT));

        SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_FROM_POOL);

    } else {

        //
        //  Zero out the irp context and indicate that it is from zone and
        //  not pool allocated
        //

        RtlZeroMemory(IrpContext, sizeof(EXT2_IRP_CONTEXT) );
    }
    
    if (!IrpContext)
    {
        return NULL;
    }
    
    IrpContext->Identifier.Type = EXT2ICX;
    IrpContext->Identifier.Size = sizeof(EXT2_IRP_CONTEXT);
    
    IrpContext->Irp = Irp;
    
    IrpContext->MajorFunction = IoStackLocation->MajorFunction;
    IrpContext->MinorFunction = IoStackLocation->MinorFunction;
    
    IrpContext->DeviceObject = DeviceObject;
    
    IrpContext->FileObject = IoStackLocation->FileObject;
    
    if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
        IrpContext->MajorFunction == IRP_MJ_DEVICE_CONTROL ||
        IrpContext->MajorFunction == IRP_MJ_SHUTDOWN)
    {
        IrpContext->IsSynchronous = TRUE;
    }
    else if (IrpContext->MajorFunction == IRP_MJ_CLEANUP ||
        IrpContext->MajorFunction == IRP_MJ_CLOSE)
    {
        IrpContext->IsSynchronous = FALSE;
    }
    else
    {
        IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
    }
    
    //
    // Temporary workaround for a bug in close that makes it reference a
    // fileobject when it is no longer valid.
    //
    if (IrpContext->MajorFunction == IRP_MJ_CLOSE)
    {
        IrpContext->IsSynchronous = TRUE;
    }
    
    IrpContext->IsTopLevel = (IoGetTopLevelIrp() == Irp);
    
    IrpContext->ExceptionInProgress = FALSE;
    
    return IrpContext;
}

VOID
Ext2FreeIrpContext (IN PEXT2_IRP_CONTEXT IrpContext)
{
    ASSERT(IrpContext != NULL);
    
    ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
        (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));


    Ext2UnpinRepinnedBcbs(IrpContext);
    
    //  Return the Irp context record to the region or to pool depending on
    //  its flag

    if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FROM_POOL)) {

        ExFreePool( IrpContext );

    } else {

        ExFreeToNPagedLookasideList(&(gExt2Global->Ext2IrpContextLookasideList), IrpContext);
    }
}

VOID
Ext2RepinBcb (
    IN PEXT2_IRP_CONTEXT IrpContext,
    IN PBCB Bcb
    )
{
    PEXT2_REPINNED_BCBS Repinned;
    ULONG i;

    Repinned = &IrpContext->Repinned;

    while (TRUE)
    {
        for (i = 0; i < EXT2_REPINNED_BCBS_ARRAY_SIZE; i += 1)
        {
            if (Repinned->Bcb[i] == Bcb)
            {
                return;
            }

            if (Repinned->Bcb[i] == NULL)
            {
                Repinned->Bcb[i] = Bcb;
                CcRepinBcb( Bcb );

                return;
            }
        }

        if (Repinned->Next == NULL)
        {
            Repinned->Next = FsRtlAllocatePool( PagedPool, sizeof(EXT2_REPINNED_BCBS) );
            RtlZeroMemory( Repinned->Next, sizeof(EXT2_REPINNED_BCBS) );
        }

        Repinned = Repinned->Next;
    }
}

VOID
Ext2UnpinRepinnedBcbs (
    IN PEXT2_IRP_CONTEXT IrpContext
    )
{
    IO_STATUS_BLOCK RaiseIosb;
    PEXT2_REPINNED_BCBS Repinned;
    BOOLEAN WriteThroughToDisk;
    PFILE_OBJECT FileObject = NULL;
    BOOLEAN ForceVerify = FALSE;
    ULONG i;

    Repinned = &IrpContext->Repinned;
    RaiseIosb.Status = STATUS_SUCCESS;

    WriteThroughToDisk = (BOOLEAN) (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH) ||
                                    IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY));

    while (Repinned != NULL)
    {
        for (i = 0; i < EXT2_REPINNED_BCBS_ARRAY_SIZE; i += 1)
        {
            if (Repinned->Bcb[i] != NULL)
            {
                IO_STATUS_BLOCK Iosb;

                if ( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY) )
                {
                    FileObject = CcGetFileObjectFromBcb( Repinned->Bcb[i] );
                }

                CcUnpinRepinnedBcb( Repinned->Bcb[i],
                                    WriteThroughToDisk,
                                    &Iosb );

                if ( !NT_SUCCESS(Iosb.Status) )
                {
                    if (RaiseIosb.Status == STATUS_SUCCESS)
                    {
                        RaiseIosb = Iosb;
                    }

                    if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_FLOPPY) &&
                        (IrpContext->MajorFunction != IRP_MJ_CLEANUP) &&
                        (IrpContext->MajorFunction != IRP_MJ_FLUSH_BUFFERS) &&
                        (IrpContext->MajorFunction != IRP_MJ_SET_INFORMATION))
                    {

                        CcPurgeCacheSection( FileObject->SectionObjectPointer,
                                             NULL,
                                             0,
                                             FALSE );

                        ForceVerify = TRUE;
                    }
                }

                Repinned->Bcb[i] = NULL;

            }
            else
            {
                break;
            }
        }

        if (Repinned != &IrpContext->Repinned)
        {

            PEXT2_REPINNED_BCBS Saved;

            Saved = Repinned->Next;
            ExFreePool( Repinned );
            Repinned = Saved;

        }
        else
        {

            Repinned = Repinned->Next;
            IrpContext->Repinned.Next = NULL;
        }
    }

    if (!NT_SUCCESS(RaiseIosb.Status))
    {
        if (ForceVerify && FileObject)
        {
            SetFlag(FileObject->DeviceObject->Flags, DO_VERIFY_VOLUME);
            IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
                                          FileObject->DeviceObject );
        }

        IrpContext->Irp->IoStatus = RaiseIosb;
        Ext2NormalizeAndRaiseStatus(IrpContext, RaiseIosb.Status );
    }

    return;
}


PEXT2_FCB
Ext2AllocateFcb (IN PEXT2_VCB   Vcb,
         IN PEXT2_MCB           Ext2Mcb,
         IN PEXT2_INODE         ext2_inode )
{
    PEXT2_FCB Fcb;

    Fcb = (PEXT2_FCB) (ExAllocateFromNPagedLookasideList( &(gExt2Global->Ext2FcbLookasideList)));

    if (Fcb == NULL)
    {
        Fcb = (PEXT2_FCB)ExAllocatePool(NonPagedPool, sizeof(EXT2_FCB));

        RtlZeroMemory(Fcb, sizeof(EXT2_FCB));

        SetFlag(Fcb->Flags, FCB_FROM_POOL);
    }
    else
    {
        RtlZeroMemory(Fcb, sizeof(EXT2_FCB));
    }

    if (!Fcb)
    {
        return NULL;
    }
    
    Fcb->Identifier.Type = EXT2FCB;
    Fcb->Identifier.Size = sizeof(EXT2_FCB);

    FsRtlInitializeFileLock (
        &Fcb->FileLockAnchor,
        NULL,
        NULL );
    
    Fcb->OpenHandleCount = 0;
    Fcb->ReferenceCount = 0;
    
    Fcb->Vcb = Vcb;

#if DBG    

    Fcb->AnsiFileName.Length = Ext2Mcb->ShortName.Length / sizeof(WCHAR);

    Fcb->AnsiFileName.MaximumLength = Ext2Mcb->ShortName.Length / sizeof(WCHAR) + 1;

    Fcb->AnsiFileName.Buffer = (PUCHAR) ExAllocatePool(
        PagedPool,
        Ext2Mcb->ShortName.Length / sizeof(WCHAR) + 1 );

    if (!Fcb->AnsiFileName.Buffer)
    {
        goto errorout;
    }

    Ext2WcharToChar(
        Fcb->AnsiFileName.Buffer,
        Ext2Mcb->ShortName.Buffer,
        Ext2Mcb->ShortName.Length / sizeof(WCHAR)
        );

    Fcb->AnsiFileName.Buffer[Ext2Mcb->ShortName.Length / sizeof(WCHAR)] = 0;

#endif

    Ext2Mcb->FileAttr = FILE_ATTRIBUTE_NORMAL;
    
    if (S_ISDIR(ext2_inode->i_mode))
    {
        SetFlag(Ext2Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY);
    }

    if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) || Ext2IsReadOnly(ext2_inode->i_mode))
    {
        SetFlag(Ext2Mcb->FileAttr, FILE_ATTRIBUTE_READONLY);
    }
    
    Fcb->ext2_inode = ext2_inode;

    Fcb->Ext2Mcb = Ext2Mcb;
    Ext2Mcb->Ext2Fcb = Fcb;
    
    RtlZeroMemory(&Fcb->CommonFCBHeader, sizeof(FSRTL_COMMON_FCB_HEADER));
    
    Fcb->CommonFCBHeader.NodeTypeCode = (USHORT) EXT2FCB;
    Fcb->CommonFCBHeader.NodeByteSize = sizeof(EXT2_FCB);
    Fcb->CommonFCBHeader.IsFastIoPossible = FastIoIsNotPossible;
    Fcb->CommonFCBHeader.Resource = &(Fcb->MainResource);
    Fcb->CommonFCBHeader.PagingIoResource = &(Fcb->PagingIoResource);

    Fcb->CommonFCBHeader.AllocationSize.QuadPart = (LONGLONG)(Fcb->ext2_inode->i_blocks * SECTOR_SIZE);
    Fcb->CommonFCBHeader.FileSize.QuadPart = (LONGLONG)(Fcb->ext2_inode->i_size);
    Fcb->CommonFCBHeader.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff);
    
    Fcb->SectionObject.DataSectionObject = NULL;
    Fcb->SectionObject.SharedCacheMap = NULL;
    Fcb->SectionObject.ImageSectionObject = NULL;

    ExInitializeResourceLite(&(Fcb->MainResource));
    ExInitializeResourceLite(&(Fcb->PagingIoResource));

    ExInitializeResourceLite(&(Fcb->CountResource));

    InsertTailList(&Vcb->FcbList, &Fcb->Next);

/*
    if (dir_inode != inode)
    {
        ParentFcb = Ext2SearchMcb(Vcb, dir_inode);

        if (ParentFcb)
        {
            Fcb->ParentFcb = ParentFcb;
            ExAcquireResourceExclusiveLite(&ParentFcb->CountResource, TRUE);
            ParentFcb->ReferenceCount++;
            ExReleaseResourceForThreadLite(
                    &ParentFcb->CountResource,
                    ExGetCurrentResourceThread());

        }
    }
*/

#if DBG

    ExAcquireResourceExclusiveLite(
        &gExt2Global->Resource,
        TRUE );

    gExt2Global->FcbAllocated++;

    ExReleaseResourceForThreadLite(
        &gExt2Global->Resource,
        ExGetCurrentResourceThread() );
#endif
    
    return Fcb;

#if DBG
errorout:
#endif

    if (Fcb)
    {

#if DBG
        if (Fcb->AnsiFileName.Buffer)
            ExFreePool(Fcb->AnsiFileName.Buffer);
#endif
        
        if (FlagOn(Fcb->Flags, FCB_FROM_POOL)) {
            
            ExFreePool( Fcb );
            
        } else {
            
            ExFreeToNPagedLookasideList(&(gExt2Global->Ext2FcbLookasideList), Fcb);
        }
        
    }

    return NULL;
}

VOID
Ext2FreeFcb (IN PEXT2_FCB Fcb)
{
    ASSERT(Fcb != NULL);
    
    ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
        (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

    FsRtlUninitializeFileLock(&Fcb->FileLockAnchor);

    ExDeleteResourceLite(&Fcb->CountResource);

    ExDeleteResourceLite(&Fcb->MainResource);
    
    ExDeleteResourceLite(&Fcb->PagingIoResource);
    
    RemoveEntryList(&Fcb->Next);

	Fcb->Ext2Mcb->Ext2Fcb = NULL;

    if(IsFlagOn(Fcb->Flags, FCB_FILE_DELETED))
    {
        if (Fcb->Ext2Mcb)
        {
            Ext2DeleteMcbNode(Fcb->Ext2Mcb->Parent, Fcb->Ext2Mcb);
            Ext2FreeMcb(Fcb->Ext2Mcb);
        }
    }

#if DBG    
    ExFreePool(Fcb->AnsiFileName.Buffer);
#endif

    ExFreePool(Fcb->ext2_inode);

/*

    if ( Fcb->ParentFcb )
    {
        ASSERT((Fcb->ParentFcb->Identifier.Type == FCB) &&
            (Fcb->ParentFcb->Identifier.Size == sizeof(EXT2_FCB)));
        
        ExAcquireResourceExclusiveLite(&Fcb->ParentFcb->CountResource, TRUE);
        Fcb->ParentFcb->ReferenceCount -- ;
        ExReleaseResourceForThreadLite(
            &Fcb->ParentFcb->CountResource,
            ExGetCurrentResourceThread());
        
        if (!Fcb->ParentFcb->ReferenceCount)
            Ext2FreeFcb(Fcb->ParentFcb);
    }
*/

⌨️ 快捷键说明

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