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

📄 strucsup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c) 1989-2000 Microsoft Corporation

Module Name:

    StrucSup.c

Abstract:

    This module implements the Fat in-memory data structure manipulation
    routines


--*/

#include "FatProcs.h"

//
//  The Bug check file id for this module
//

#define BugCheckFileId                   (FAT_BUG_CHECK_STRUCSUP)

//
//  The debug trace level
//

#define Dbg                              (DEBUG_TRACE_STRUCSUP)

#define FillMemory(BUF,SIZ,MASK) {                          \
    ULONG i;                                                \
    for (i = 0; i < (((SIZ)/4) - 1); i += 2) {              \
        ((PULONG)(BUF))[i] = (MASK);                        \
        ((PULONG)(BUF))[i+1] = (ULONG)PsGetCurrentThread(); \
    }                                                       \
}

#define IRP_CONTEXT_HEADER (sizeof( IRP_CONTEXT ) * 0x10000 + FAT_NTC_IRP_CONTEXT)

//
//  Local macros.
//
//  Define our lookaside list allocators.  For the time being, and perhaps
//  permanently, the paged structures don't come off of lookasides.  This
//  is due to complications with clean unload as FAT can be in the paging
//  path, making it really hard to find the right time to empty them.
//
//  Fortunately, the hit rates on the Fcb/Ccb lists weren't stunning.
//

#define FAT_FILL_FREE 0

INLINE
PCCB
FatAllocateCcb (
    )
{
    return (PCCB) FsRtlAllocatePoolWithTag( PagedPool, sizeof(CCB), TAG_CCB );
}

INLINE
VOID
FatFreeCcb (
    IN PCCB Ccb
    )
{
#if FAT_FILL_FREE
    RtlFillMemoryUlong(Ccb, sizeof(CCB), FAT_FILL_FREE);
#endif

    ExFreePool( Ccb );
}

INLINE
PFCB
FatAllocateFcb (
    )
{
    return (PFCB) FsRtlAllocatePoolWithTag( PagedPool, sizeof(FCB), TAG_FCB );
}

INLINE
VOID
FatFreeFcb (
    IN PFCB Fcb
    )
{
#if FAT_FILL_FREE
    RtlFillMemoryUlong(Fcb, sizeof(FCB), FAT_FILL_FREE);
#endif

    ExFreePool( Fcb );
}

INLINE
PNON_PAGED_FCB
FatAllocateNonPagedFcb (
    )
{
    return (PNON_PAGED_FCB) ExAllocateFromNPagedLookasideList( &FatNonPagedFcbLookasideList );
}

INLINE
VOID
FatFreeNonPagedFcb (
    PNON_PAGED_FCB NonPagedFcb
    )
{
#if FAT_FILL_FREE
    RtlFillMemoryUlong(NonPagedFcb, sizeof(NON_PAGED_FCB), FAT_FILL_FREE);
#endif

    ExFreeToNPagedLookasideList( &FatNonPagedFcbLookasideList, (PVOID) NonPagedFcb );
}

INLINE
PERESOURCE
FatAllocateResource (
    )
{
    PERESOURCE Resource;

    Resource = (PERESOURCE) ExAllocateFromNPagedLookasideList( &FatEResourceLookasideList );

    ExInitializeResourceLite( Resource );

    return Resource;
}

INLINE
VOID
FatFreeResource (
    IN PERESOURCE Resource
    )
{
    ExDeleteResourceLite( Resource );

#if FAT_FILL_FREE
    RtlFillMemoryUlong(Resource, sizeof(ERESOURCE), FAT_FILL_FREE);
#endif

    ExFreeToNPagedLookasideList( &FatEResourceLookasideList, (PVOID) Resource );
}

INLINE
PIRP_CONTEXT
FatAllocateIrpContext (
    )
{
    return (PIRP_CONTEXT) ExAllocateFromNPagedLookasideList( &FatIrpContextLookasideList );
}

INLINE
VOID
FatFreeIrpContext (
    IN PIRP_CONTEXT IrpContext
    )
{
#if FAT_FILL_FREE
    RtlFillMemoryUlong(IrpContext, sizeof(IRP_CONTEXT), FAT_FILL_FREE);
#endif

    ExFreeToNPagedLookasideList( &FatIrpContextLookasideList, (PVOID) IrpContext );
}

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FatInitializeVcb)
#pragma alloc_text(PAGE, FatTearDownVcb)
#pragma alloc_text(PAGE, FatDeleteVcb)
#pragma alloc_text(PAGE, FatCreateRootDcb)
#pragma alloc_text(PAGE, FatCreateFcb)
#pragma alloc_text(PAGE, FatCreateDcb)
#pragma alloc_text(PAGE, FatDeleteFcb)
#pragma alloc_text(PAGE, FatCreateCcb)
#pragma alloc_text(PAGE, FatDeallocateCcbStrings)
#pragma alloc_text(PAGE, FatDeleteCcb)
#pragma alloc_text(PAGE, FatGetNextFcbTopDown)
#pragma alloc_text(PAGE, FatGetNextFcbBottomUp)
#pragma alloc_text(PAGE, FatConstructNamesInFcb)
#pragma alloc_text(PAGE, FatCheckFreeDirentBitmap)
#pragma alloc_text(PAGE, FatCreateIrpContext)
#pragma alloc_text(PAGE, FatDeleteIrpContext_Real)
#pragma alloc_text(PAGE, FatIsHandleCountZero)
#pragma alloc_text(PAGE, FatPreallocateCloseContext)
#endif


VOID
FatInitializeVcb (
    IN PIRP_CONTEXT IrpContext,
    IN OUT PVCB Vcb,
    IN PDEVICE_OBJECT TargetDeviceObject,
    IN PVPB Vpb,
    IN PDEVICE_OBJECT FsDeviceObject
    )

/*++

Routine Description:

    This routine initializes and inserts a new Vcb record into the in-memory
    data structure.  The Vcb record "hangs" off the end of the Volume device
    object and must be allocated by our caller.

Arguments:

    Vcb - Supplies the address of the Vcb record being initialized.

    TargetDeviceObject - Supplies the address of the target device object to
        associate with the Vcb record.

    Vpb - Supplies the address of the Vpb to associate with the Vcb record.

    FsDeviceObject - The filesystem device object that the mount was directed
                     too.

Return Value:

    None.

--*/

{
    CC_FILE_SIZES FileSizes;
    PDEVICE_OBJECT RealDevice;
    LONG i;

    STORAGE_HOTPLUG_INFO HotplugInfo;
    NTSTATUS Status;

    //
    //  The following variables are used for abnormal unwind
    //

    PLIST_ENTRY UnwindEntryList = NULL;
    PERESOURCE UnwindResource = NULL;
    PERESOURCE UnwindResource2 = NULL;
    PFILE_OBJECT UnwindFileObject = NULL;
    PFILE_OBJECT UnwindCacheMap = NULL;
    BOOLEAN UnwindWeAllocatedMcb = FALSE;
    PFILE_SYSTEM_STATISTICS UnwindStatistics = NULL;

    DebugTrace(+1, Dbg, "FatInitializeVcb, Vcb = %08lx\n", Vcb);

    try {

        //
        //  We start by first zeroing out all of the VCB, this will guarantee
        //  that any stale data is wiped clean
        //

        RtlZeroMemory( Vcb, sizeof(VCB) );

        //
        //  Set the proper node type code and node byte size
        //

        Vcb->VolumeFileHeader.NodeTypeCode = FAT_NTC_VCB;
        Vcb->VolumeFileHeader.NodeByteSize = sizeof(VCB);

        //
        //  Initialize the tunneling cache
        //

        FsRtlInitializeTunnelCache(&Vcb->Tunnel);

        //
        //  Insert this Vcb record on the FatData.VcbQueue
        //

        ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

        (VOID)FatAcquireExclusiveGlobal( IrpContext );
        InsertTailList( &FatData.VcbQueue, &Vcb->VcbLinks );
        FatReleaseGlobal( IrpContext );
        UnwindEntryList = &Vcb->VcbLinks;

        //
        //  Set the Target Device Object, Vpb, and Vcb State fields
        //


        ObReferenceObject( TargetDeviceObject );
        Vcb->TargetDeviceObject = TargetDeviceObject;
        Vcb->Vpb = Vpb;

        Vcb->CurrentDevice = Vpb->RealDevice;

        //
        //  Set the removable media and defflush flags based on the storage
        //  inquiry and the old characteristic bits.
        //

        Status = FatPerformDevIoCtrl( IrpContext,
                                      IOCTL_STORAGE_GET_HOTPLUG_INFO,
                                      TargetDeviceObject,
                                      &HotplugInfo,
                                      sizeof(HotplugInfo),
                                      FALSE,
                                      TRUE,
                                      NULL );

        if (NT_SUCCESS( Status )) {

            if (HotplugInfo.MediaRemovable) {

                SetFlag( Vcb->VcbState, VCB_STATE_FLAG_REMOVABLE_MEDIA );
            }

            if (!HotplugInfo.WriteCacheEnableOverride) {

                //
                //  If the device or media is hotplug and the override is not
                //  set, force defflush behavior for the device.
                //

                if (HotplugInfo.MediaHotplug || HotplugInfo.DeviceHotplug) {

                    SetFlag( Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH );

                //
                //  Now, for removables that claim to be lockable, lob a lock
                //  request and see if it works.  There can unfortunately be
                //  transient, media dependent reasons that it can fail.  If
                //  it does not, we must force defflush on.
                //

                } else if (HotplugInfo.MediaRemovable &&
                           !HotplugInfo.MediaHotplug) {

                    Status = FatToggleMediaEjectDisable( IrpContext, Vcb, TRUE );

                    if (!NT_SUCCESS( Status )) {

                        SetFlag( Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH );

                    }

                    Status = FatToggleMediaEjectDisable( IrpContext, Vcb, FALSE );
                }
            }
        }

        if (FlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA)) {

            SetFlag( Vcb->VcbState, VCB_STATE_FLAG_REMOVABLE_MEDIA );
        }

        //
        //  Make sure we turn on deferred flushing for floppies like we always
        //  have.
        //

        if (FlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE)) {

            SetFlag( Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH );
        }

        FatSetVcbCondition( Vcb, VcbGood);

        //
        //  Initialize the resource variable for the Vcb
        //

        ExInitializeResourceLite( &Vcb->Resource );
        UnwindResource = &Vcb->Resource;

        ExInitializeResourceLite( &Vcb->ChangeBitMapResource );
        UnwindResource2 = &Vcb->ChangeBitMapResource;

        //
        //  Initialize the free cluster bitmap mutex.
        //

        ExInitializeFastMutex( &Vcb->FreeClusterBitMapMutex );

        //
        //  Create the special file object for the virtual volume file with a close
        //  context, its pointers back to the Vcb and the section object pointer.
        //
        //  We don't have to unwind the close context.  That will happen in the close
        //  path automatically.
        //

        RealDevice = Vcb->CurrentDevice;

        Vcb->VirtualVolumeFile = UnwindFileObject = IoCreateStreamFileObject( NULL, RealDevice );

        Vcb->CloseContext = FsRtlAllocatePoolWithTag( PagedPool,
                                                      sizeof(CLOSE_CONTEXT),
                                                      TAG_FAT_CLOSE_CONTEXT );

        FatSetFileObject( Vcb->VirtualVolumeFile,
                          VirtualVolumeFile,
                          Vcb,
                          NULL );

        //
        //  Remember this internal, residual open.
        //

        InterlockedIncrement( &(Vcb->InternalOpenCount) );
        InterlockedIncrement( &(Vcb->ResidualOpenCount) );

        Vcb->VirtualVolumeFile->SectionObjectPointer = &Vcb->SectionObjectPointers;

        Vcb->VirtualVolumeFile->ReadAccess = TRUE;
        Vcb->VirtualVolumeFile->WriteAccess = TRUE;
        Vcb->VirtualVolumeFile->DeleteAccess = TRUE;

        //
        //  Initialize the notify structures.
        //

        InitializeListHead( &Vcb->DirNotifyList );

        FsRtlNotifyInitializeSync( &Vcb->NotifySync );

        //
        //  Initialize the Cache Map for the volume file.  The size is
        //  initially set to that of our first read.  It will be extended
        //  when we know how big the Fat is.
        //

        FileSizes.AllocationSize.QuadPart =
        FileSizes.FileSize.QuadPart = sizeof(PACKED_BOOT_SECTOR);
        FileSizes.ValidDataLength = FatMaxLarge;

        CcInitializeCacheMap( Vcb->VirtualVolumeFile,
                              &FileSizes,
                              TRUE,
                              &FatData.CacheManagerNoOpCallbacks,
                              Vcb );
        UnwindCacheMap = Vcb->VirtualVolumeFile;

        //
        //  Initialize the structure that will keep track of dirty fat sectors.
        //  The largest possible Mcb structures are less than 1K, so we use
        //  non paged pool.
        //

        FsRtlInitializeLargeMcb( &Vcb->DirtyFatMcb, PagedPool );

        UnwindWeAllocatedMcb = TRUE;

        //
        //  Set the cluster index hint to the first valid cluster of a fat: 2
        //

        Vcb->ClusterHint = 2;

        //
        //  Initialize the directory stream file object creation event.
        //  This event is also "borrowed" for async non-cached writes.
        //

        ExInitializeFastMutex( &Vcb->DirectoryFileCreationMutex );

        //
        //  Initialize the clean volume callback Timer and DPC.
        //

        KeInitializeTimer( &Vcb->CleanVolumeTimer );

        KeInitializeDpc( &Vcb->CleanVolumeDpc, FatCleanVolumeDpc, Vcb );

        //
        //  Initialize the performance counters.
        //

        Vcb->Statistics = FsRtlAllocatePoolWithTag( NonPagedPool,
                                                    sizeof(FILE_SYSTEM_STATISTICS) * KeNumberProcessors,
                                                    TAG_VCB_STATS );
        UnwindStatistics = Vcb->Statistics;

        RtlZeroMemory( Vcb->Statistics, sizeof(FILE_SYSTEM_STATISTICS) * KeNumberProcessors );

        for (i = 0; i < KeNumberProcessors; i += 1) {
            Vcb->Statistics[i].Common.FileSystemType = FILESYSTEM_STATISTICS_TYPE_FAT;
            Vcb->Statistics[i].Common.Version = 1;
            Vcb->Statistics[i].Common.SizeOfCompleteStructure =
                sizeof(FILE_SYSTEM_STATISTICS);
        }

        //
        //  Pick up a VPB right now so we know we can pull this filesystem stack off
        //  of the storage stack on demand.
        //

        Vcb->SwapVpb = FsRtlAllocatePoolWithTag( NonPagedPool,
                                                 sizeof( VPB ),
                                                 TAG_VPB );

        RtlZeroMemory( Vcb->SwapVpb, sizeof( VPB ) );

        //
        //  Initialize the close queue listheads.
        //

        InitializeListHead( &Vcb->AsyncCloseList );
        InitializeListHead( &Vcb->DelayedCloseList );

        //
        //  Initialize the Advanced FCB Header

⌨️ 快捷键说明

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