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

📄 strucsup.c

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

Copyright (c) 1989-2000 Microsoft Corporation

Module Name:

    StrucSup.c

Abstract:

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


--*/

#include "CdProcs.h"

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

#define BugCheckFileId                   (CDFS_BUG_CHECK_STRUCSUP)

//
//  Local macros
//

//
//  PFCB
//  CdAllocateFcbData (
//      IN PIRP_CONTEXT IrpContext
//      );
//
//  VOID
//  CdDeallocateFcbData (
//      IN PIRP_CONTEXT IrpContext,
//      IN PFCB Fcb
//      );
//
//  PFCB
//  CdAllocateFcbIndex (
//      IN PIRP_CONTEXT IrpContext
//      );
//
//  VOID
//  CdDeallocateFcbIndex (
//      IN PIRP_CONTEXT IrpContext,
//      IN PFCB Fcb
//      );
//
//  PFCB_NONPAGED
//  CdAllocateFcbNonpaged (
//      IN PIRP_CONTEXT IrpContext
//      );
//
//  VOID
//  CdDeallocateFcbNonpaged (
//      IN PIRP_CONTEXT IrpContext,
//      IN PFCB_NONPAGED FcbNonpaged
//      );
//
//  PCCB
//  CdAllocateCcb (
//      IN PIRP_CONTEXT IrpContext
//      );
//
//  VOID
//  CdDeallocateCcb (
//      IN PIRP_CONTEXT IrpContext,
//      IN PCCB Ccb
//      );
//

#define CdAllocateFcbData(IC) \
    FsRtlAllocatePoolWithTag( CdPagedPool, SIZEOF_FCB_DATA, TAG_FCB_DATA )

#define CdDeallocateFcbData(IC,F) \
    CdFreePool( &(F) )

#define CdAllocateFcbIndex(IC) \
    FsRtlAllocatePoolWithTag( CdPagedPool, SIZEOF_FCB_INDEX, TAG_FCB_INDEX )

#define CdDeallocateFcbIndex(IC,F) \
    CdFreePool( &(F) )

#define CdAllocateFcbNonpaged(IC) \
    ExAllocatePoolWithTag( CdNonPagedPool, sizeof( FCB_NONPAGED ), TAG_FCB_NONPAGED )

#define CdDeallocateFcbNonpaged(IC,FNP) \
    CdFreePool( &(FNP) )

#define CdAllocateCcb(IC) \
    FsRtlAllocatePoolWithTag( CdPagedPool, sizeof( CCB ), TAG_CCB )

#define CdDeallocateCcb(IC,C) \
    CdFreePool( &(C) )

//
//  Local structures
//

typedef struct _FCB_TABLE_ELEMENT {

    FILE_ID FileId;
    PFCB Fcb;

} FCB_TABLE_ELEMENT, *PFCB_TABLE_ELEMENT;

//
//  Local macros
//

//
//  VOID
//  CdInsertFcbTable (
//      IN PIRP_CONTEXT IrpContext,
//      IN PFCB Fcb
//      );
//
//  VOID
//  CdDeleteFcbTable (
//      IN PIRP_CONTEXT IrpContext,
//      IN PFCB Fcb
//      );
//


#define CdInsertFcbTable(IC,F) {                                    \
    FCB_TABLE_ELEMENT _Key;                                         \
    _Key.Fcb = (F);                                                 \
    _Key.FileId = (F)->FileId;                                      \
    RtlInsertElementGenericTable( &(F)->Vcb->FcbTable,              \
                                  &_Key,                            \
                                  sizeof( FCB_TABLE_ELEMENT ),      \
                                  NULL );                           \
}

#define CdDeleteFcbTable(IC,F) {                                    \
    FCB_TABLE_ELEMENT _Key;                                         \
    _Key.FileId = (F)->FileId;                                      \
    RtlDeleteElementGenericTable( &(F)->Vcb->FcbTable, &_Key );     \
}

//
//  Local support routines
//

VOID
CdDeleteFcb (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb
    );

PFCB_NONPAGED
CdCreateFcbNonpaged (
    IN PIRP_CONTEXT IrpContext
    );

VOID
CdDeleteFcbNonpaged (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB_NONPAGED FcbNonpaged
    );

RTL_GENERIC_COMPARE_RESULTS
CdFcbTableCompare (
    IN PRTL_GENERIC_TABLE FcbTable,
    IN PVOID Fid1,
    IN PVOID Fid2
    );

PVOID
CdAllocateFcbTable (
    IN PRTL_GENERIC_TABLE FcbTable,
    IN CLONG ByteSize
    );

VOID
CdDeallocateFcbTable (
    IN PRTL_GENERIC_TABLE FcbTable,
    IN PVOID Buffer
    );

ULONG
CdTocSerial (
    IN PIRP_CONTEXT IrpContext,
    IN PCDROM_TOC_LARGE CdromToc
    );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CdAllocateFcbTable)
#pragma alloc_text(PAGE, CdCleanupIrpContext)
#pragma alloc_text(PAGE, CdCreateCcb)
#pragma alloc_text(PAGE, CdCreateFcb)
#pragma alloc_text(PAGE, CdCreateFcbNonpaged)
#pragma alloc_text(PAGE, CdCreateFileLock)
#pragma alloc_text(PAGE, CdCreateIrpContext)
#pragma alloc_text(PAGE, CdDeallocateFcbTable)
#pragma alloc_text(PAGE, CdDeleteCcb)
#pragma alloc_text(PAGE, CdDeleteFcb)
#pragma alloc_text(PAGE, CdDeleteFcbNonpaged)
#pragma alloc_text(PAGE, CdDeleteFileLock)
#pragma alloc_text(PAGE, CdDeleteVcb)
#pragma alloc_text(PAGE, CdFcbTableCompare)
#pragma alloc_text(PAGE, CdGetNextFcb)
#pragma alloc_text(PAGE, CdInitializeFcbFromFileContext)
#pragma alloc_text(PAGE, CdInitializeFcbFromPathEntry)
#pragma alloc_text(PAGE, CdInitializeStackIrpContext)
#pragma alloc_text(PAGE, CdInitializeVcb)
#pragma alloc_text(PAGE, CdLookupFcbTable)
#pragma alloc_text(PAGE, CdProcessToc)
#pragma alloc_text(PAGE, CdTeardownStructures)
#pragma alloc_text(PAGE, CdTocSerial)
#pragma alloc_text(PAGE, CdUpdateVcbFromVolDescriptor)
#endif

//
//  Some static names for volume streams
//

UNICODE_STRING CdInternalStreamNames[] = {
        { 24, 24, L"$PATH_TABLE$"},
        { 2,  2,  L"\\"}
};


VOID
CdInitializeVcb (
    IN PIRP_CONTEXT IrpContext,
    IN OUT PVCB Vcb,
    IN PDEVICE_OBJECT TargetDeviceObject,
    IN PVPB Vpb,
    IN PCDROM_TOC_LARGE CdromToc,
    IN ULONG TocLength,
    IN ULONG TocTrackCount,
    IN ULONG TocDiskFlags,
    IN ULONG BlockFactor,
    IN ULONG MediaChangeCount
    )

/*++

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.

    CdromToc - Buffer to hold table of contents.  NULL if TOC command not
        supported.

    TocLength - Byte count length of TOC.  We use this as the TOC length to
        return on a user query.

    TocTrackCount - Count of tracks in TOC.  Used to create pseudo files for
        audio disks.

    TocDiskFlags - Flag field to indicate the type of tracks on the disk.

    BlockFactor - Used to decode any multi-session information.

    MediaChangeCount - Initial media change count of the target device

Return Value:

    None.

--*/

{
    PAGED_CODE();

    //
    //  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->NodeTypeCode = CDFS_NTC_VCB;
    Vcb->NodeByteSize = sizeof( VCB );

    //
    //  Initialize the DirNotify structs.  FsRtlNotifyInitializeSync can raise.
    //

    InitializeListHead( &Vcb->DirNotifyList );
    FsRtlNotifyInitializeSync( &Vcb->NotifySync );
    
    //
    //  Pick up a VPB right now so we know we can pull this filesystem stack
    //  off of the storage stack on demand.  This can raise - if it does,  
    //  uninitialize the notify structures before returning.
    //
    
    try  {

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

        if (AbnormalTermination())  {
        
            FsRtlNotifyUninitializeSync( &Vcb->NotifySync );
        }
    }

    //
    //  Nothing beyond this point should raise.
    //

    RtlZeroMemory( Vcb->SwapVpb, sizeof( VPB ) );
    
    //
    //  Initialize the resource variable for the Vcb and files.
    //

    ExInitializeResourceLite( &Vcb->VcbResource );
    ExInitializeResourceLite( &Vcb->FileResource );
    ExInitializeFastMutex( &Vcb->VcbMutex );

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

    InsertHeadList( &CdData.VcbQueue, &Vcb->VcbLinks );

    //
    //  Set the Target Device Object and Vpb fields, referencing the
    //  Target device for the mount.
    //

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

    //
    //  Set the removable media flag based on the real device's
    //  characteristics
    //

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

        SetFlag( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA );
    }

    //
    //  Initialize the generic Fcb Table.
    //

    RtlInitializeGenericTable( &Vcb->FcbTable,
                               (PRTL_GENERIC_COMPARE_ROUTINE) CdFcbTableCompare,
                               (PRTL_GENERIC_ALLOCATE_ROUTINE) CdAllocateFcbTable,
                               (PRTL_GENERIC_FREE_ROUTINE) CdDeallocateFcbTable,
                               NULL );

    //
    //  Show that we have a mount in progress.
    //

    CdUpdateVcbCondition( Vcb, VcbMountInProgress);

    //
    //  Refererence the Vcb for two reasons.  The first is a reference
    //  that prevents the Vcb from going away on the last close unless
    //  dismount has already occurred.  The second is to make sure
    //  we don't go into the dismount path on any error during mount
    //  until we get to the Mount cleanup.
    //

    Vcb->VcbReference = 1 + CDFS_RESIDUAL_REFERENCE;

    //
    //  Update the TOC information in the Vcb.
    //

    Vcb->CdromToc = CdromToc;
    Vcb->TocLength = TocLength;
    Vcb->TrackCount = TocTrackCount;
    Vcb->DiskFlags = TocDiskFlags;

    //
    //  If this disk contains audio tracks only then set the audio flag.
    //

    if (TocDiskFlags == CDROM_DISK_AUDIO_TRACK) {

        SetFlag( Vcb->VcbState, VCB_STATE_AUDIO_DISK | VCB_STATE_CDXA );
    }

    //
    //  Set the block factor.
    //

    Vcb->BlockFactor = BlockFactor;

    //
    //  Set the media change count on the device
    //

    CdUpdateMediaChangeCount( Vcb, MediaChangeCount);
}


VOID
CdUpdateVcbFromVolDescriptor (
    IN PIRP_CONTEXT IrpContext,
    IN OUT PVCB Vcb,
    IN PCHAR RawIsoVd OPTIONAL
    )

/*++

Routine Description:

    This routine is called to perform the final initialization of a Vcb from the
    volume descriptor on the disk.

Arguments:

    Vcb - Vcb for the volume being mounted.  We have already set the flags for the
        type of descriptor.

    RawIsoVd - If specified this is the volume descriptor to use to mount the
        volume.  Not specified for a raw disk.

Return Value:

    None

--*/

{
    ULONG Shift;
    ULONG StartingBlock;
    ULONG ByteCount;

    LONGLONG FileId = 0;

    PRAW_DIRENT RawDirent;
    PATH_ENTRY PathEntry;
    PCD_MCB_ENTRY McbEntry;

    BOOLEAN UnlockVcb = FALSE;

    PAGED_CODE();

    //
    //  Use a try-finally to facilitate cleanup.
    //

    try {

        //
        //  Copy the block size and compute the various block masks.
        //  Block size must not be larger than the sector size.  We will
        //  use a default of the CD physical sector size if we are not
        //  on a data-full disc.
        //
        //  This must always be set.
        //

        Vcb->BlockSize = ( ARGUMENT_PRESENT( RawIsoVd ) ?
                            CdRvdBlkSz( RawIsoVd, Vcb->VcbState ) :
                            SECTOR_SIZE );

        //
        //  We no longer accept media where blocksize != sector size.
        //
        
        if (Vcb->BlockSize != SECTOR_SIZE)  {

            CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR );
        }

        Vcb->BlocksPerSector = SECTOR_SIZE / Vcb->BlockSize;
        Vcb->BlockMask = Vcb->BlockSize - 1;
        Vcb->BlockInverseMask = ~Vcb->BlockMask;
     
        Vcb->BlockToSectorShift = 0;
        Vcb->BlockToByteShift = SECTOR_SHIFT;

        //
        //  If there is a volume descriptor then do the internal Fcb's and
        //  other Vcb fields.
        //

        if (ARGUMENT_PRESENT( RawIsoVd )) {

            //
            //  Create the path table Fcb and refererence it and the Vcb.
            //

            CdLockVcb( IrpContext, Vcb );
            UnlockVcb = TRUE;

            Vcb->PathTableFcb = CdCreateFcb( IrpContext,
                                             *((PFILE_ID) &FileId),
                                             CDFS_NTC_FCB_PATH_TABLE,
                                             NULL );

            CdIncrementReferenceCounts( IrpContext, Vcb->PathTableFcb, 1, 1 );
            CdUnlockVcb( IrpContext, Vcb );
            UnlockVcb = FALSE;

            //
            //  Compute the stream offset and size of this path table.
            //

            StartingBlock = CdRvdPtLoc( RawIsoVd, Vcb->VcbState );

            ByteCount = CdRvdPtSz( RawIsoVd, Vcb->VcbState );

            Vcb->PathTableFcb->StreamOffset = BytesFromBlocks( Vcb,
                                                               SectorBlockOffset( Vcb, StartingBlock ));

            Vcb->PathTableFcb->FileSize.QuadPart = (LONGLONG) (Vcb->PathTableFcb->StreamOffset +
                                                               ByteCount);

            Vcb->PathTableFcb->ValidDataLength.QuadPart = Vcb->PathTableFcb->FileSize.QuadPart;

            Vcb->PathTableFcb->AllocationSize.QuadPart = LlSectorAlign( Vcb->PathTableFcb->FileSize.QuadPart );

            //
            //  Now add the mapping information.

⌨️ 快捷键说明

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