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

📄 memory.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * COPYRIGHT:        GNU GENERAL PUBLIC LICENSE VERSION 2
 * PROJECT:          ReiserFs file system driver for Windows NT/2000/XP/Vista.
 * FILE:             memory.c
 * PURPOSE:          
 * PROGRAMMER:       Mark Piper, Matt Wu, Bo Brant閚.
 * HOMEPAGE:         
 * UPDATE HISTORY: 
 */

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

#include "rfsd.h"

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

extern PRFSD_GLOBAL RfsdGlobal;

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

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, RfsdAllocateIrpContext)
#pragma alloc_text(PAGE, RfsdFreeIrpContext)
#pragma alloc_text(PAGE, RfsdAllocateFcb)
#pragma alloc_text(PAGE, RfsdFreeFcb)
#pragma alloc_text(PAGE, RfsdAllocateMcb)
#pragma alloc_text(PAGE, RfsdSearchMcbTree)
#pragma alloc_text(PAGE, RfsdSearchMcb)
#pragma alloc_text(PAGE, RfsdGetFullFileName)
#pragma alloc_text(PAGE, RfsdRefreshMcb)
#pragma alloc_text(PAGE, RfsdAddMcbNode)
#pragma alloc_text(PAGE, RfsdDeleteMcbNode)
#pragma alloc_text(PAGE, RfsdFreeMcbTree)

#if DISABLED
#pragma alloc_text(PAGE, RfsdCheckBitmapConsistency)
#pragma alloc_text(PAGE, RfsdCheckSetBlock)
#endif

#pragma alloc_text(PAGE, RfsdInitializeVcb)
#pragma alloc_text(PAGE, RfsdFreeCcb)
#pragma alloc_text(PAGE, RfsdAllocateCcb)
#pragma alloc_text(PAGE, RfsdFreeVcb)
#pragma alloc_text(PAGE, RfsdCreateFcbFromMcb)
#pragma alloc_text(PAGE, RfsdSyncUninitializeCacheMap)
#endif

PRFSD_IRP_CONTEXT
RfsdAllocateIrpContext (IN PDEVICE_OBJECT   DeviceObject,
                        IN PIRP             Irp )
{
    PIO_STACK_LOCATION   IoStackLocation;
    PRFSD_IRP_CONTEXT    IrpContext;
    
    ASSERT(DeviceObject != NULL);
    ASSERT(Irp != NULL);
    
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
    
    ExAcquireResourceExclusiveLite(
            &RfsdGlobal->LAResource,
            TRUE );

    IrpContext = (PRFSD_IRP_CONTEXT) (
        ExAllocateFromNPagedLookasideList(
            &(RfsdGlobal->RfsdIrpContextLookasideList)));

    ExReleaseResourceForThreadLite(
            &RfsdGlobal->LAResource,
            ExGetCurrentResourceThread() );

    if (IrpContext == NULL) {

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

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

        RtlZeroMemory(IrpContext, sizeof(RFSD_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(RFSD_IRP_CONTEXT) );
    }
    
    if (!IrpContext) {
        return NULL;
    }
    
    IrpContext->Identifier.Type = RFSDICX;
    IrpContext->Identifier.Size = sizeof(RFSD_IRP_CONTEXT);
    
    IrpContext->Irp = Irp;
    
    IrpContext->MajorFunction = IoStackLocation->MajorFunction;
    IrpContext->MinorFunction = IoStackLocation->MinorFunction;
    
    IrpContext->DeviceObject = DeviceObject;
    
    IrpContext->FileObject = IoStackLocation->FileObject;

    if (IrpContext->FileObject != NULL) {
        IrpContext->RealDevice = IrpContext->FileObject->DeviceObject;
    } else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) {
        if (IoStackLocation->Parameters.MountVolume.Vpb) {
            IrpContext->RealDevice = 
                IoStackLocation->Parameters.MountVolume.Vpb->RealDevice;
        }
    }

    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;
    }
#if (_WIN32_WINNT >= 0x0500)
    else if (IrpContext->MajorFunction == IRP_MJ_PNP) {
        if (IoGetCurrentIrpStackLocation(Irp)->FileObject == NULL) {
            IrpContext->IsSynchronous = TRUE;
        } else {
            IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
        }
    }
#endif //(_WIN32_WINNT >= 0x0500)
    else {
        IrpContext->IsSynchronous = IoIsOperationSynchronous(Irp);
    }

#if 0    
    //
    // 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;
    }
#endif
    
    IrpContext->IsTopLevel = (IoGetTopLevelIrp() == Irp);
    
    IrpContext->ExceptionInProgress = FALSE;
    
    return IrpContext;
}


NTSTATUS
RfsdCompleteIrpContext (
    IN PRFSD_IRP_CONTEXT IrpContext,
    IN NTSTATUS Status )
{
    PIRP    Irp = NULL;
    BOOLEAN bPrint;
    
    Irp = IrpContext->Irp;

    if (Irp != NULL) {

        if (NT_ERROR(Status)) {
            Irp->IoStatus.Information = 0;
        }
    
        Irp->IoStatus.Status = Status;
        bPrint = !IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);

        RfsdCompleteRequest(
            Irp, bPrint, (CCHAR)(NT_SUCCESS(Status)?
            IO_DISK_INCREMENT : IO_NO_INCREMENT) );

        IrpContext->Irp = NULL;               
    }

    RfsdFreeIrpContext(IrpContext);

    return Status;
}

VOID
RfsdFreeIrpContext (IN PRFSD_IRP_CONTEXT IrpContext)
{
    ASSERT(IrpContext != NULL);
    
    ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
        (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));

    RfsdUnpinRepinnedBcbs(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)) {

        IrpContext->Identifier.Type = 0;
        IrpContext->Identifier.Size = 0;

        ExFreePool( IrpContext );

    } else {

        IrpContext->Identifier.Type = 0;
        IrpContext->Identifier.Size = 0;

        ExAcquireResourceExclusiveLite(
                &RfsdGlobal->LAResource,
                TRUE );

        ExFreeToNPagedLookasideList(&(RfsdGlobal->RfsdIrpContextLookasideList), IrpContext);

        ExReleaseResourceForThreadLite(
                &RfsdGlobal->LAResource,
                ExGetCurrentResourceThread() );

    }
}

VOID
RfsdRepinBcb (
    IN PRFSD_IRP_CONTEXT IrpContext,
    IN PBCB Bcb
    )
{
    PRFSD_REPINNED_BCBS Repinned;

    Repinned = &IrpContext->Repinned;

    return;

#if 0

    ULONG i;

    while (Repinned)  {

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

        Repinned = Repinned->Next;
    }

    while (TRUE) {

        for (i = 0; i < RFSD_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 = ExAllocatePool( PagedPool, sizeof(RFSD_REPINNED_BCBS) );
            RtlZeroMemory( Repinned->Next, sizeof(RFSD_REPINNED_BCBS) );
        }

        Repinned = Repinned->Next;
    }

#endif

}

VOID
RfsdUnpinRepinnedBcbs (
    IN PRFSD_IRP_CONTEXT IrpContext
    )
{
    IO_STATUS_BLOCK RaiseIosb;
    PRFSD_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 < RFSD_REPINNED_BCBS_ARRAY_SIZE; i += 1) {
            if (Repinned->Bcb[i] != NULL) {
                IO_STATUS_BLOCK Iosb;

                ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);

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

                ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);

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

                ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);

                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) 
{
            PRFSD_REPINNED_BCBS Saved;

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

        } else {

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

    if (!NT_SUCCESS(RaiseIosb.Status)) {

        DbgBreak();

        if (ForceVerify && FileObject) {
            SetFlag(FileObject->DeviceObject->Flags, DO_VERIFY_VOLUME);
            IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
                                          FileObject->DeviceObject );
        }

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

    return;
}


PRFSD_FCB
RfsdAllocateFcb (IN PRFSD_VCB   Vcb,
         IN PRFSD_MCB           RfsdMcb,
         IN PRFSD_INODE         Inode )
{
    PRFSD_FCB Fcb;

    ExAcquireResourceExclusiveLite(
            &RfsdGlobal->LAResource,
            TRUE );

    Fcb = (PRFSD_FCB) ExAllocateFromNPagedLookasideList(
                            &(RfsdGlobal->RfsdFcbLookasideList));

    ExReleaseResourceForThreadLite(
            &RfsdGlobal->LAResource,
            ExGetCurrentResourceThread() );

    if (Fcb == NULL) {
        Fcb = (PRFSD_FCB)ExAllocatePool(NonPagedPool, sizeof(RFSD_FCB));

        RtlZeroMemory(Fcb, sizeof(RFSD_FCB));

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

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

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

#if DBG    

    Fcb->AnsiFileName.MaximumLength = (USHORT)
        RfsdUnicodeToOEMSize(&(RfsdMcb->ShortName)) + 1;

    Fcb->AnsiFileName.Buffer = (PUCHAR) 
        ExAllocatePool(PagedPool, Fcb->AnsiFileName.MaximumLength);

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

    RtlZeroMemory(Fcb->AnsiFileName.Buffer, Fcb->AnsiFileName.MaximumLength);

    RfsdUnicodeToOEM( &(Fcb->AnsiFileName),
                     &(RfsdMcb->ShortName));

#endif

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

    if ( IsFlagOn(Vcb->Flags, VCB_READ_ONLY) || 
         RfsdIsReadOnly(Inode->i_mode)) {
        SetFlag(RfsdMcb->FileAttr, FILE_ATTRIBUTE_READONLY);
    }
    
    Fcb->Inode = Inode;

    Fcb->RfsdMcb = RfsdMcb;
    RfsdMcb->RfsdFcb = Fcb;
    
    RtlZeroMemory(&Fcb->Header, sizeof(FSRTL_COMMON_FCB_HEADER));
    
    Fcb->Header.NodeTypeCode = (USHORT) RFSDFCB;
    Fcb->Header.NodeByteSize = sizeof(RFSD_FCB);
    Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
    Fcb->Header.Resource = &(Fcb->MainResource);
    Fcb->Header.PagingIoResource = &(Fcb->PagingIoResource);

    // NOTE: In EXT2, the low part was stored in i_size (a 32-bit value); the high part would be stored in the acl field...
	// However, on ReiserFS, the i_size is a 64-bit value.
	Fcb->Header.FileSize.QuadPart = Fcb->Inode->i_size;
    

    Fcb->Header.AllocationSize.QuadPart = 
        CEILING_ALIGNED(Fcb->Header.FileSize.QuadPart, (ULONGLONG)Vcb->BlockSize);

	Fcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff);
    
    Fcb->SectionObject.DataSectionObject = NULL;
    Fcb->SectionObject.SharedCacheMap = NULL;
    Fcb->SectionObject.ImageSectionObject = NULL;

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

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

#if DBG

    ExAcquireResourceExclusiveLite(
        &RfsdGlobal->CountResource,
        TRUE );

    RfsdGlobal->FcbAllocated++;

    ExReleaseResourceForThreadLite(
        &RfsdGlobal->CountResource,
        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 {

            ExAcquireResourceExclusiveLite(
                    &RfsdGlobal->LAResource,
                    TRUE );

            ExFreeToNPagedLookasideList(&(RfsdGlobal->RfsdFcbLookasideList), Fcb);

            ExReleaseResourceForThreadLite(
                    &RfsdGlobal->LAResource,
                    ExGetCurrentResourceThread() );
        }
        
    }

    return NULL;
}

VOID
RfsdFreeFcb (IN PRFSD_FCB Fcb)
{
    PRFSD_VCB       Vcb;
    ASSERT(Fcb != NULL);
    
    ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
        (Fcb->Identifier.Size == sizeof(RFSD_FCB)));

    Vcb = Fcb->Vcb;

    FsRtlUninitializeFileLock(&Fcb->FileLockAnchor);

⌨️ 快捷键说明

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