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

📄 strucsup.c

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

            CdLockFcb( IrpContext, Vcb->PathTableFcb );

            CdAddInitialAllocation( IrpContext,
                                    Vcb->PathTableFcb,
                                    StartingBlock,
                                    Vcb->PathTableFcb->AllocationSize.QuadPart );

            CdUnlockFcb( IrpContext, Vcb->PathTableFcb );

            //
            //  Point to the file resource.
            //

            Vcb->PathTableFcb->Resource = &Vcb->FileResource;

            //
            //  Mark the Fcb as initialized and create the stream file for this.
            //

            SetFlag( Vcb->PathTableFcb->FcbState, FCB_STATE_INITIALIZED );

            CdCreateInternalStream( IrpContext, Vcb, Vcb->PathTableFcb, &CdInternalStreamNames[0]);

            //
            //  Create the root index and reference it in the Vcb.
            //

            CdLockVcb( IrpContext, Vcb );
            UnlockVcb = TRUE;
            Vcb->RootIndexFcb = CdCreateFcb( IrpContext,
                                             *((PFILE_ID) &FileId),
                                             CDFS_NTC_FCB_INDEX,
                                             NULL );

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

            //
            //  Create the File id by hand for this Fcb.
            //

            CdSetFidPathTableOffset( Vcb->RootIndexFcb->FileId, Vcb->PathTableFcb->StreamOffset );
            CdFidSetDirectory( Vcb->RootIndexFcb->FileId );

            //
            //  Create a pseudo path table entry so we can call the initialization
            //  routine for the directory.
            //

            RawDirent = (PRAW_DIRENT) CdRvdDirent( RawIsoVd, Vcb->VcbState );

            CopyUchar4( &PathEntry.DiskOffset, RawDirent->FileLoc );

            PathEntry.DiskOffset += RawDirent->XarLen;
            PathEntry.Ordinal = 1;
            PathEntry.PathTableOffset = Vcb->PathTableFcb->StreamOffset;

            CdInitializeFcbFromPathEntry( IrpContext,
                                          Vcb->RootIndexFcb,
                                          NULL,
                                          &PathEntry );

            //
            //  Create the stream file for the root directory.
            //

            CdCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb, &CdInternalStreamNames[1] );

            //
            //  Now do the volume dasd Fcb.  Create this and reference it in the
            //  Vcb.
            //

            CdLockVcb( IrpContext, Vcb );
            UnlockVcb = TRUE;

            Vcb->VolumeDasdFcb = CdCreateFcb( IrpContext,
                                              *((PFILE_ID) &FileId),
                                              CDFS_NTC_FCB_DATA,
                                              NULL );

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

            //
            //  The file size is the full disk.
            //

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

            Vcb->VolumeDasdFcb->FileSize.QuadPart = LlBytesFromBlocks( Vcb, StartingBlock );

            Vcb->VolumeDasdFcb->AllocationSize.QuadPart =
            Vcb->VolumeDasdFcb->ValidDataLength.QuadPart = Vcb->VolumeDasdFcb->FileSize.QuadPart;

            //
            //  Now add the extent representing the volume 'by hand'.
            //

            CdLockFcb( IrpContext, Vcb->VolumeDasdFcb );

            McbEntry = Vcb->VolumeDasdFcb->Mcb.McbArray;

            McbEntry->FileOffset = 
            McbEntry->DiskOffset = 0;
            
            McbEntry->ByteCount = Vcb->VolumeDasdFcb->AllocationSize.QuadPart;
            
            McbEntry->DataBlockByteCount =
            McbEntry->TotalBlockByteCount = McbEntry->ByteCount;
            
            Vcb->VolumeDasdFcb->Mcb.CurrentEntryCount = 1;
    
            CdUnlockFcb( IrpContext, Vcb->VolumeDasdFcb );

            //
            //  Point to the file resource.
            //

            Vcb->VolumeDasdFcb->Resource = &Vcb->FileResource;

            Vcb->VolumeDasdFcb->FileAttributes = FILE_ATTRIBUTE_READONLY;

            //
            //  Mark the Fcb as initialized.
            //

            SetFlag( Vcb->VolumeDasdFcb->FcbState, FCB_STATE_INITIALIZED );

            //
            //  Check and see if this is an XA disk.
            //

            if (FlagOn( Vcb->VcbState, VCB_STATE_ISO | VCB_STATE_JOLIET)
                && RtlEqualMemory( CdXaId,
                                   Add2Ptr( RawIsoVd, 0x400, PCHAR ),
                                   8 )) {

                SetFlag( Vcb->VcbState, VCB_STATE_CDXA );
            }

        //
        //  If this is a music disk then we want to mock this disk to make it
        //  look like ISO disk.  We will create a pseudo root directory in
        //  that case.
        //

        } else if (FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK )) {

            ULONG RootDirectorySize;

            //
            //  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;

            //
            //  We only create a pseudo entry for the root.
            //

            Vcb->PathTableFcb->FileSize.QuadPart = (LONGLONG) (FIELD_OFFSET( RAW_PATH_ISO, DirId ) + 2);

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

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

            //
            //  Point to the file resource.
            //

            Vcb->PathTableFcb->Resource = &Vcb->FileResource;

            //
            //  Mark the Fcb as initialized and create the stream file for this.
            //

            SetFlag( Vcb->PathTableFcb->FcbState, FCB_STATE_INITIALIZED );

            CdCreateInternalStream( IrpContext, Vcb, Vcb->PathTableFcb, &CdInternalStreamNames[0]);

            //
            //  Create the root index and reference it in the Vcb.
            //

            CdLockVcb( IrpContext, Vcb );
            UnlockVcb = TRUE;
            Vcb->RootIndexFcb = CdCreateFcb( IrpContext,
                                             *((PFILE_ID) &FileId),
                                             CDFS_NTC_FCB_INDEX,
                                             NULL );

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

            //
            //  Create the File id by hand for this Fcb.
            //

            CdSetFidPathTableOffset( Vcb->RootIndexFcb->FileId, Vcb->PathTableFcb->StreamOffset );
            CdFidSetDirectory( Vcb->RootIndexFcb->FileId );

            //
            //  Create a pseudo path table entry so we can call the initialization
            //  routine for the directory.
            //

            RtlZeroMemory( &PathEntry, sizeof( PATH_ENTRY ));


            PathEntry.Ordinal = 1;
            PathEntry.PathTableOffset = Vcb->PathTableFcb->StreamOffset;

            CdInitializeFcbFromPathEntry( IrpContext,
                                          Vcb->RootIndexFcb,
                                          NULL,
                                          &PathEntry );

            //
            //  Set the sizes by hand for this Fcb.  It should have an entry for each track plus an
            //  entry for the root and parent.
            //

            RootDirectorySize = (Vcb->TrackCount + 2) * CdAudioDirentSize;
            RootDirectorySize = SectorAlign( RootDirectorySize );

            Vcb->RootIndexFcb->AllocationSize.QuadPart =
            Vcb->RootIndexFcb->ValidDataLength.QuadPart =
            Vcb->RootIndexFcb->FileSize.QuadPart = RootDirectorySize;

            SetFlag( Vcb->RootIndexFcb->FcbState, FCB_STATE_INITIALIZED );

            //
            //  Create the stream file for the root directory.
            //

            CdCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb, &CdInternalStreamNames[1] );

            //
            //  Now do the volume dasd Fcb.  Create this and reference it in the
            //  Vcb.
            //

            CdLockVcb( IrpContext, Vcb );
            UnlockVcb = TRUE;

            Vcb->VolumeDasdFcb = CdCreateFcb( IrpContext,
                                              *((PFILE_ID) &FileId),
                                              CDFS_NTC_FCB_DATA,
                                              NULL );

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

            //
            //  We won't allow raw reads on this Fcb so leave the size at
            //  zero.
            //

            //
            //  Point to the file resource.
            //

            Vcb->VolumeDasdFcb->Resource = &Vcb->FileResource;

            Vcb->VolumeDasdFcb->FileAttributes = FILE_ATTRIBUTE_READONLY;

            //
            //  Mark the Fcb as initialized.
            //

            SetFlag( Vcb->VolumeDasdFcb->FcbState, FCB_STATE_INITIALIZED );

            //
            //  We will store a hard-coded name in the Vpb and use the toc as
            //  the serial number.
            //

            Vcb->Vpb->VolumeLabelLength = CdAudioLabelLength;

            RtlCopyMemory( Vcb->Vpb->VolumeLabel,
                           CdAudioLabel,
                           CdAudioLabelLength );

            //
            //  Find the serial number for the audio disk.
            //

            Vcb->Vpb->SerialNumber = CdTocSerial( IrpContext, Vcb->CdromToc );

            //
            //  Set the ISO bit so we know how to treat the names.
            //

            SetFlag( Vcb->VcbState, VCB_STATE_ISO );
        }
        
    } finally {

        if (UnlockVcb) { CdUnlockVcb( IrpContext, Vcb ); }
    }
}


VOID
CdDeleteVcb (
    IN PIRP_CONTEXT IrpContext,
    IN OUT PVCB Vcb
    )

/*++

Routine Description:

    This routine is called to delete a Vcb which failed mount or has been
    dismounted.  The dismount code should have already removed all of the
    open Fcb's.  We do nothing here but clean up other auxilary structures.

Arguments:

    Vcb - Vcb to delete.

Return Value:

    None

--*/

{
    PAGED_CODE();

    ASSERT_EXCLUSIVE_CDDATA;
    ASSERT_EXCLUSIVE_VCB( Vcb );

    //
    //  Chuck the backpocket Vpb we kept just in case.
    //

    CdFreePool( &Vcb->SwapVpb );
    
    //
    //  If there is a Vpb then we must delete it ourselves.
    //

    CdFreePool( &Vcb->Vpb );

    //
    //  Dereference our target if we haven't already done so.
    //

    if (Vcb->TargetDeviceObject != NULL) {
    
        ObDereferenceObject( Vcb->TargetDeviceObject );
    }

    //
    //  Delete the XA Sector and sector cache buffer if allocated.
    //

    CdFreePool( &Vcb->XASector );
    CdFreePool( &Vcb->SectorCacheBuffer);

    if (Vcb->SectorCacheIrp != NULL) {

        IoFreeIrp( Vcb->SectorCacheIrp);
        Vcb->SectorCacheIrp = NULL;

        ExDeleteResource( &Vcb->SectorCacheResource);
    }

    //
    //  Remove this entry from the global queue.
    //

    RemoveEntryList( &Vcb->VcbLinks );

    //
    //  Delete the Vcb and File resources.
    //

    ExDeleteResourceLite( &Vcb->VcbResource );
    ExDeleteResourceLite( &Vcb->FileResource );

    //
    //  Delete the TOC if present.
    //

    CdFreePool( &Vcb->CdromToc );

    //
    //  Uninitialize the notify structures.
    //

    if (Vcb->NotifySync != NULL) {

        FsRtlNotifyUninitializeSync( &Vcb->NotifySync );
    }

    //
    //  Now delete the volume device object.
    //

    IoDeleteDevice( (PDEVICE_OBJECT) CONTAINING_RECORD( Vcb,
                                                        VOLUME_DEVICE_OBJECT,
                                                        Vcb ));

    return;
}


PFCB
CdCreateFcb (
    IN PIRP_CONTEXT IrpContext,
    IN FILE_ID FileId,
    IN NODE_TYPE_CODE NodeTypeCode,
    OUT PBOOLEAN FcbExisted OPTIONAL
    )

/*++

Routine Description:

    This routine is called to find the Fcb for the given FileId.  We will
    look this up first in the Fcb table and if not found we will create
    an Fcb.  We don't initialize it or insert it into the FcbTable in this
    routine.

    This routine is called while the Vcb is locked.

Arguments:

    FileId - This is the Id for the target Fcb.

    NodeTypeCode - Node type for this Fcb if we need to create.

    FcbExisted - If specified, we store whether the Fcb existed.

Return Value:

    PFCB - The Fcb found in the table or created if needed.

--*/

{
    PFCB NewFcb;
    BOOLEAN LocalFcbExisted;

    PAGED_CODE();

    //
    //  Use the local boolean if one was not passed in.
    //

    if (!ARGUMENT_PRESENT( FcbExisted )) {

        FcbExisted = &LocalFcbExisted;
    }

    //
    //  Maybe this is already in the table.
    //

    NewFcb = CdLookupFcbTable( IrpContext, IrpContext->Vcb, FileId );

    //
    //  If not then create the Fcb is requested by our caller.
    //

    if (NewFcb == NULL) {

        //
        //  Allocate and initialize the structure depending on the
        //  type code.
        //

        switch (NodeTypeCode) {

        case CDFS_NTC_FCB_PATH_TABLE:
        case CDFS_NTC_FCB_INDEX:

            NewFcb = CdAllocateFcbIndex( IrpContext );

            RtlZeroMemory( NewFcb, SIZEOF_FCB_INDEX );

            NewFcb->NodeByteSize = SIZEOF_FCB_INDEX;

            InitializeListHead( &NewFcb->FcbQueue );

            break;

        case CDFS_NTC_FCB_DATA :

            NewFcb = CdAllocateFcbData( IrpContext );

            RtlZeroMemory( NewFcb, SIZEOF_FCB_DATA );

            NewFcb->NodeByteSize = SIZEOF_FCB_DATA;

            break;

        default:

            CdBugCheck( 0, 0, 0 );
        }

        //
        //  Now do the common initialization.
        //

        NewFcb->NodeTypeCode = NodeTypeCode;

        NewFcb->Vcb = IrpContext->Vcb;
        NewFcb->FileId = FileId;

        CdInitializeMcb( IrpContext, NewFcb );

        //
        //  Now create the non-paged section object.
        //

        NewFcb->FcbNonpaged = CdCreateFcbNonpaged( IrpContext );

        //
        //  Deallocate the Fcb and raise if the allocation failed.
        //

⌨️ 快捷键说明

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