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

📄 strucsup.c

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

        ExInitializeFastMutex( &Vcb->AdvancedFcbHeaderMutex );
        FsRtlSetupAdvancedHeader( &Vcb->VolumeFileHeader,
                                  &Vcb->AdvancedFcbHeaderMutex );

        //
        //  With the Vcb now set up, set the IrpContext Vcb field.
        //

        IrpContext->Vcb = Vcb;

    } finally {

        DebugUnwind( FatInitializeVcb );

        //
        //  If this is an abnormal termination then undo our work
        //

        if (AbnormalTermination()) {

            if (UnwindCacheMap != NULL) { FatSyncUninitializeCacheMap( IrpContext, UnwindCacheMap ); }
            if (UnwindFileObject != NULL) { ObDereferenceObject( UnwindFileObject ); }
            if (UnwindResource != NULL) { FatDeleteResource( UnwindResource ); }
            if (UnwindResource2 != NULL) { FatDeleteResource( UnwindResource2 ); }
            if (UnwindWeAllocatedMcb) { FsRtlUninitializeLargeMcb( &Vcb->DirtyFatMcb ); }
            if (UnwindEntryList != NULL) {
                (VOID)FatAcquireExclusiveGlobal( IrpContext );
                RemoveEntryList( UnwindEntryList );
                FatReleaseGlobal( IrpContext );
            }
            if (UnwindStatistics != NULL) { ExFreePool( UnwindStatistics ); }

            if (Vcb->CloseContext != NULL) {

                ExFreePool( Vcb->CloseContext );
                Vcb->CloseContext = NULL;
            }
        }

        DebugTrace(-1, Dbg, "FatInitializeVcb -> VOID\n", 0);
    }

    //
    //  and return to our caller
    //

    UNREFERENCED_PARAMETER( IrpContext );

    return;
}


VOID
FatTearDownVcb (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb
    )

/*++

Routine Description:

    This routine tries to remove all internal opens from the volume.

Arguments:

    IrpContext - Supplies the context for the overall request.

    Vcb - Supplies the Vcb to be torn down.

Return Value:

    None

--*/

{
    PFILE_OBJECT DirectoryFileObject;


    PAGED_CODE();

    //
    //  Get rid of the virtual volume file, if we need to.
    //

    if (Vcb->VirtualVolumeFile != NULL) {

        //
        //  Uninitialize the cache
        //

        FatSyncUninitializeCacheMap( IrpContext, Vcb->VirtualVolumeFile );

        //
        //  Dereference the virtual volume file.  This will cause a close
        //  Irp to be processed, so we need to do this before we destory
        //  the Vcb
        //

        FsRtlTeardownPerStreamContexts( &Vcb->VolumeFileHeader );

        ObDereferenceObject( Vcb->VirtualVolumeFile );

        Vcb->VirtualVolumeFile = NULL;
    }

    //
    //  Close down the EA file.
    //

    FatCloseEaFile( IrpContext, Vcb, FALSE );

    //
    //  Close down the root directory stream..
    //

    if (Vcb->RootDcb != NULL) {

        DirectoryFileObject = Vcb->RootDcb->Specific.Dcb.DirectoryFile;

        if (DirectoryFileObject != NULL) {

            //
            //  Tear down this directory file.
            //

            FatSyncUninitializeCacheMap( IrpContext,
                                         DirectoryFileObject );

            Vcb->RootDcb->Specific.Dcb.DirectoryFile = NULL;
            ObDereferenceObject( DirectoryFileObject );
        }
    }

    //
    //  The VCB can no longer be used.
    //

    FatSetVcbCondition( Vcb, VcbBad );
}


VOID
FatDeleteVcb (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb
    )

/*++

Routine Description:

    This routine removes the Vcb record from Fat's in-memory data
    structures.  It also will remove all associated underlings
    (i.e., FCB records).

Arguments:

    Vcb - Supplies the Vcb to be removed

Return Value:

    None

--*/

{
    PFCB Fcb;

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

    //
    //  If the IrpContext points to the VCB being deleted NULL out the stail
    //  pointer.
    //

    if (IrpContext->Vcb == Vcb) {

        IrpContext->Vcb = NULL;

    }

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

    if (Vcb->SwapVpb) {

        ExFreePool( Vcb->SwapVpb );

    }

    //
    //  Free the VPB, if we need to.
    //

    if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VPB_MUST_BE_FREED )) {

        //
        //  We swapped the VPB, so we need to free the main one.
        //

        ExFreePool( Vcb->Vpb );
    }
    
    //
    //  Free the close context for the virtual volume file, if it is still
    //  present.  If this is the case, it means the last close that came
    //  through was for the virtual volume file, and we are processing that
    //  close right now.
    //

    if (Vcb->CloseContext != NULL) {

        ExFreePool( Vcb->CloseContext );
    }

    //
    //  Remove this record from the global list of all Vcb records.
    //  Note that the global lock must already be held when calling
    //  this function.
    //

    RemoveEntryList( &(Vcb->VcbLinks) );

    //
    //  Make sure the direct access open count is zero, and the open file count
    //  is also zero.
    //

    if ((Vcb->DirectAccessOpenCount != 0) || (Vcb->OpenFileCount != 0)) {

        FatBugCheck( 0, 0, 0 );
    }

    //
    //  Remove the EaFcb and dereference the Fcb for the Ea file if it
    //  exists.
    //

    if (Vcb->EaFcb != NULL) {

        Vcb->EaFcb->OpenCount = 0;
        FatDeleteFcb( IrpContext, &Vcb->EaFcb );
    }

    //
    //  Remove the Root Dcb
    //

    if (Vcb->RootDcb != NULL) {

        //
        //  Rundown stale child Fcbs that may be hanging around.  Yes, this
        //  can happen.  No, the create path isn't perfectly defensive about
        //  tearing down branches built up on creates that don't wind up
        //  succeeding.  Normal system operation usually winds up having
        //  cleaned them out through re-visiting, but ...
        //
        //  Just pick off Fcbs from the bottom of the tree until we run out.
        //  Then we delete the root Dcb.
        //

        while( (Fcb = FatGetNextFcbBottomUp( IrpContext, NULL, Vcb->RootDcb )) != Vcb->RootDcb ) {

            FatDeleteFcb( IrpContext, &Fcb );
        }

        FatDeleteFcb( IrpContext, &Vcb->RootDcb );
    }

    //
    //  Uninitialize the notify sychronization object.
    //

    FsRtlNotifyUninitializeSync( &Vcb->NotifySync );

    //
    //  Uninitialize the resource variable for the Vcb
    //

    FatDeleteResource( &Vcb->Resource );
    FatDeleteResource( &Vcb->ChangeBitMapResource );

    //
    //  If allocation support has been setup, free it.
    //

    if (Vcb->FreeClusterBitMap.Buffer != NULL) {

        FatTearDownAllocationSupport( IrpContext, Vcb );
    }

    //
    //  UnInitialize the Mcb structure that kept track of dirty fat sectors.
    //

    FsRtlUninitializeLargeMcb( &Vcb->DirtyFatMcb );

    //
    //  Free the pool for the stached copy of the boot sector
    //

    if ( Vcb->First0x24BytesOfBootSector ) {

        ExFreePool( Vcb->First0x24BytesOfBootSector );
        Vcb->First0x24BytesOfBootSector = NULL;
    }

    //
    //  Cancel the CleanVolume Timer and Dpc
    //

    (VOID)KeCancelTimer( &Vcb->CleanVolumeTimer );

    (VOID)KeRemoveQueueDpc( &Vcb->CleanVolumeDpc );

    //
    //  Free the performance counters memory
    //

    ExFreePool( Vcb->Statistics );

    //
    //  Clean out the tunneling cache
    //

    FsRtlDeleteTunnelCache(&Vcb->Tunnel);

    //
    // Dereference the target device object.
    //

    ObDereferenceObject( Vcb->TargetDeviceObject );

    //
    //  We better have used all the close contexts we allocated. There could be
    //  one remaining if we're doing teardown due to a final close coming in on
    //  a directory file stream object.  It will be freed on the way back up.
    //

    ASSERT( Vcb->CloseContextCount <= 1);

    //
    //  And zero out the Vcb, this will help ensure that any stale data is
    //  wiped clean
    //

    RtlZeroMemory( Vcb, sizeof(VCB) );

    //
    //  return and tell the caller
    //

    DebugTrace(-1, Dbg, "FatDeleteVcb -> VOID\n", 0);

    return;
}


VOID
FatCreateRootDcb (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb
    )

/*++

Routine Description:

    This routine allocates, initializes, and inserts a new root DCB record
    into the in memory data structure.

Arguments:

    Vcb - Supplies the Vcb to associate the new DCB under

Return Value:

    None. The Vcb is modified in-place.

--*/

{
    PDCB Dcb;

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

    PVOID UnwindStorage[2] = { NULL, NULL };
    PERESOURCE UnwindResource = NULL;
    PERESOURCE UnwindResource2 = NULL;
    PLARGE_MCB UnwindMcb = NULL;
    PFILE_OBJECT UnwindFileObject = NULL;

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

    try {

        //
        //  Make sure we don't already have a root dcb for this vcb
        //

        if (Vcb->RootDcb != NULL) {

            DebugDump("Error trying to create multiple root dcbs\n", 0, Vcb);
            FatBugCheck( 0, 0, 0 );
        }

        //
        //  Allocate a new DCB and zero it out, we use Dcb locally so we don't
        //  have to continually reference through the Vcb
        //

        UnwindStorage[0] = Dcb = Vcb->RootDcb = FsRtlAllocatePoolWithTag( NonPagedPool,
                                                                          sizeof(DCB),
                                                                          TAG_FCB );

        RtlZeroMemory( Dcb, sizeof(DCB));

        UnwindStorage[1] =
        Dcb->NonPaged = FatAllocateNonPagedFcb();

        RtlZeroMemory( Dcb->NonPaged, sizeof( NON_PAGED_FCB ) );

        //
        //  Set the proper node type code, node byte size, and call backs
        //

        Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB;
        Dcb->Header.NodeByteSize = sizeof(DCB);

        Dcb->FcbCondition = FcbGood;

        //
        //  The parent Dcb, initial state, open count, dirent location
        //  information, and directory change count fields are already zero so
        //  we can skip setting them
        //

        //
        //  Initialize the resource variable
        //

        UnwindResource =
        Dcb->Header.Resource = FatAllocateResource();

        //
        //  Initialize the PagingIo Resource.  We no longer use the FsRtl common
        //  shared pool because this led to a) deadlocks due to cases where files
        //  and their parent directories shared a resource and b) there is no way
        //  to anticipate inter-driver induced deadlock via recursive operation.
        //

        UnwindResource2 =
        Dcb->Header.PagingIoResource = FatAllocateResource();

        //
        //  The root Dcb has an empty parent dcb links field
        //

        InitializeListHead( &Dcb->ParentDcbLinks );

        //
        //  Set the Vcb
        //

        Dcb->Vcb = Vcb;

        //
        //  initialize the parent dcb queue.
        //

        InitializeListHead( &Dcb->Specific.Dcb.ParentDcbQueue );

        //
        //  Set the full file name up.
        //

        Dcb->FullFileName.Buffer = L"\\";
        Dcb->FullFileName.Length = (USHORT)2;
        Dcb->FullFileName.MaximumLength = (USHORT)4;

        Dcb->ShortName.Name.Oem.Buffer = "\\";
        Dcb->ShortName.Name.Oem.Length = (USHORT)1;
        Dcb->ShortName.Name.Oem.MaximumLength = (USHORT)2;

        //
        //  Construct a lie about file properties since we don't
        //  have a proper "." entry to look at.
        //

        Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY;

        //
        //  Initialize Advanced FCB Header fields
        //

        ExInitializeFastMutex( &Dcb->NonPaged->AdvancedFcbHeaderMutex );
        FsRtlSetupAdvancedHeader( &Dcb->Header,
                                  &Dcb->NonPaged->AdvancedFcbHeaderMutex );

⌨️ 快捷键说明

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