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

📄 strucsup.c

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

Return Value:

    PDCB - Returns a pointer to the newly allocated DCB

--*/

{
    PDCB Dcb;

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

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

    DebugTrace(+1, Dbg, "FatCreateDcb\n", 0);


    try {

        //
        //  assert that the only time we are called is if wait is true
        //

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

        //
        //  Allocate a new DCB, and zero it out
        //

        UnwindStorage[0] = Dcb = FatAllocateFcb();

        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_DCB;
        Dcb->Header.NodeByteSize = sizeof(DCB);

        Dcb->FcbCondition = FcbGood;

        //
        //  The initial state, open count, 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();

        //
        //  Insert this Dcb into our parent dcb's queue
        //
        //  There is a deep reason why this goes on the head, to allow us
        //  to easily enumerate all child directories before child files.
        //  This is important to let us maintain whole-volume lockorder
        //  via BottomUp enumeration.
        //

        InsertHeadList( &ParentDcb->Specific.Dcb.ParentDcbQueue,
                        &Dcb->ParentDcbLinks );
        UnwindEntryList = &Dcb->ParentDcbLinks;

        //
        //  Point back to our parent dcb
        //

        Dcb->ParentDcb = ParentDcb;

        //
        //  Set the Vcb
        //

        Dcb->Vcb = Vcb;

        //
        //  Set the dirent offset within the directory
        //

        Dcb->LfnOffsetWithinDirectory = LfnOffsetWithinDirectory;
        Dcb->DirentOffsetWithinDirectory = DirentOffsetWithinDirectory;

        //
        //  Set the DirentFatFlags and LastWriteTime
        //

        Dcb->DirentFatFlags = Dirent->Attributes;

        Dcb->LastWriteTime = FatFatTimeToNtTime( IrpContext,
                                                 Dirent->LastWriteTime,
                                                 0 );

        //
        //  These fields are only non-zero when in Chicago mode.
        //

        if (FatData.ChicagoMode) {

            LARGE_INTEGER FatSystemJanOne1980;

            //
            //  If either date is possibly zero, get the system
            //  version of 1/1/80.
            //

            if ((((PUSHORT)Dirent)[9] & ((PUSHORT)Dirent)[8]) == 0) {

                ExLocalTimeToSystemTime( &FatJanOne1980,
                                         &FatSystemJanOne1980 );
            }

            //
            //  Only do the really hard work if this field is non-zero.
            //

            if (((PUSHORT)Dirent)[9] != 0) {

                Dcb->LastAccessTime =
                    FatFatDateToNtTime( IrpContext,
                                        Dirent->LastAccessDate );

            } else {

                Dcb->LastAccessTime = FatSystemJanOne1980;
            }

            //
            //  Only do the really hard work if this field is non-zero.
            //

            if (((PUSHORT)Dirent)[8] != 0) {

                Dcb->CreationTime =
                    FatFatTimeToNtTime( IrpContext,
                                        Dirent->CreationTime,
                                        Dirent->CreationMSec );

            } else {

                Dcb->CreationTime = FatSystemJanOne1980;
            }
        }

        //
        //  Initialize Advanced FCB Header fields
        //

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

        //
        //  Initialize the Mcb
        //

        FsRtlInitializeLargeMcb( &Dcb->Mcb, PagedPool );
        UnwindMcb = &Dcb->Mcb;

        //
        //  Set the file size, first cluster of file, and allocation size
        //  based on the information stored in the dirent
        //

        Dcb->FirstClusterOfFile = (ULONG)Dirent->FirstClusterOfFile;

        if ( FatIsFat32(Dcb->Vcb) ) {

            Dcb->FirstClusterOfFile += Dirent->FirstClusterOfFileHi << 16;
        }

        if ( Dcb->FirstClusterOfFile == 0 ) {

            Dcb->Header.AllocationSize.QuadPart = 0;

        } else {

            Dcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
        }

        //  initialize the notify queues, and the parent dcb queue.
        //

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

        //
        //  Setup the free dirent bitmap buffer.  Since we don't know the
        //  size of the directory, leave it zero for now.
        //

        RtlInitializeBitMap( &Dcb->Specific.Dcb.FreeDirentBitmap,
                             NULL,
                             0 );

        //
        //  Set our two create dirent aids to represent that we have yet to
        //  enumerate the directory for never used or deleted dirents.
        //

        Dcb->Specific.Dcb.UnusedDirentVbo = 0xffffffff;
        Dcb->Specific.Dcb.DeletedDirentHint = 0xffffffff;

        //
        //  Postpone initializing the cache map until we need to do a read/write
        //  of the directory file.


        //
        //  set the file names.  This must be the last thing we do.
        //

        FatConstructNamesInFcb( IrpContext,
                                Dcb,
                                Dirent,
                                Lfn );

    } finally {

        DebugUnwind( FatCreateDcb );

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

        if (AbnormalTermination()) {

            ULONG i;

            if (UnwindMcb != NULL) { FsRtlUninitializeLargeMcb( UnwindMcb ); }
            if (UnwindEntryList != NULL) { RemoveEntryList( UnwindEntryList ); }
            if (UnwindResource != NULL) { FatFreeResource( UnwindResource ); }
            if (UnwindResource2 != NULL) { FatFreeResource( UnwindResource2 ); }

            for (i = 0; i < sizeof(UnwindStorage)/sizeof(PVOID); i += 1) {
                if (UnwindStorage[i] != NULL) { ExFreePool( UnwindStorage[i] ); }
            }
        }

        DebugTrace(-1, Dbg, "FatCreateDcb -> %08lx\n", Dcb);
    }

    //
    //  return and tell the caller
    //

    DebugTrace(-1, Dbg, "FatCreateDcb -> %08lx\n", Dcb);

    return Dcb;
}


VOID
FatDeleteFcb (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB *FcbPtr
    )

/*++

Routine Description:

    This routine deallocates and removes an FCB, DCB, or ROOT DCB record
    from Fat's in-memory data structures.  It also will remove all
    associated underlings (i.e., Notify irps, and child FCB/DCB records).

Arguments:

    Fcb - Supplies the FCB/DCB/ROOT DCB to be removed

Return Value:

    None

--*/

{
    PFCB Fcb = *FcbPtr;
    
    DebugTrace(+1, Dbg, "FatDeleteFcb, Fcb = %08lx\n", Fcb);

    //
    //  We can only delete this record if the open count is zero.
    //

    if (Fcb->OpenCount != 0) {

        DebugDump("Error deleting Fcb, Still Open\n", 0, Fcb);
        FatBugCheck( 0, 0, 0 );
    }
    
    //
    //  Better be an FCB/DCB.
    //

    if ((Fcb->Header.NodeTypeCode != FAT_NTC_DCB) &&
        (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) &&
        (Fcb->Header.NodeTypeCode != FAT_NTC_FCB)) {
        
        FatBugCheck( 0, 0, 0 );
    }

    //
    //  If this is a DCB then remove every Notify record from the two
    //  notify queues
    //

    if ((Fcb->Header.NodeTypeCode == FAT_NTC_DCB) ||
        (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) {

        //
        //  If we allocated a free dirent bitmap buffer, free it.
        //

        if ((Fcb->Specific.Dcb.FreeDirentBitmap.Buffer != NULL) &&
            (Fcb->Specific.Dcb.FreeDirentBitmap.Buffer !=
             &Fcb->Specific.Dcb.FreeDirentBitmapBuffer[0])) {

            ExFreePool(Fcb->Specific.Dcb.FreeDirentBitmap.Buffer);
        }

        ASSERT( Fcb->Specific.Dcb.DirectoryFileOpenCount == 0 );
        ASSERT( IsListEmpty(&Fcb->Specific.Dcb.ParentDcbQueue) );
        ASSERT( NULL == Fcb->Specific.Dcb.DirectoryFile);

    } else {

        //
        //  Uninitialize the byte range file locks and opportunistic locks
        //

        FsRtlUninitializeFileLock( &Fcb->Specific.Fcb.FileLock );
        FsRtlUninitializeOplock( &Fcb->Specific.Fcb.Oplock );
    }

    //
    //  Release any Filter Context structures associated with this FCB
    //

    FsRtlTeardownPerStreamContexts( &Fcb->Header );

    //
    //  Uninitialize the Mcb
    //

    FsRtlUninitializeLargeMcb( &Fcb->Mcb );

    //
    //  If this is not the root dcb then we need to remove ourselves from
    //  our parents Dcb queue
    //

    if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) {

        RemoveEntryList( &(Fcb->ParentDcbLinks) );
    }

    //
    //  Remove the entry from the splay table if there is still is one.
    //

    if (FlagOn( Fcb->FcbState, FCB_STATE_NAMES_IN_SPLAY_TREE )) {

        FatRemoveNames( IrpContext, Fcb );
    }

    //
    //  Free the file name pool if allocated.
    //

    if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) {

        //
        //  If we blew up at inconvenient times, the shortname
        //  could be null even though you will *never* see this
        //  normally.  Rename is a good example of this case.
        //

        if (Fcb->ShortName.Name.Oem.Buffer) {

            ExFreePool( Fcb->ShortName.Name.Oem.Buffer );
        }

        if (Fcb->FullFileName.Buffer) {

            ExFreePool( Fcb->FullFileName.Buffer );
        }
    }

    if (Fcb->ExactCaseLongName.Buffer) {

        ExFreePool(Fcb->ExactCaseLongName.Buffer);
    }

#ifdef SYSCACHE_COMPILE

    if (Fcb->WriteMask) {

        ExFreePool( Fcb->WriteMask );
    }

#endif

    //
    //  Finally deallocate the Fcb and non-paged fcb records
    //

    FatFreeResource( Fcb->Header.Resource );

    if (Fcb->Header.PagingIoResource != Fcb->Header.Resource) {

        FatFreeResource( Fcb->Header.PagingIoResource );
    }

    //
    //  If an Event was allocated, get rid of it.
    //

    if (Fcb->NonPaged->OutstandingAsyncEvent) {

        ExFreePool( Fcb->NonPaged->OutstandingAsyncEvent );
    }

    FatFreeNonPagedFcb( Fcb->NonPaged );

    Fcb->Header.NodeTypeCode = NTC_UNDEFINED;

    FatFreeFcb( Fcb );
    *FcbPtr = NULL;
    
    //
    //  and return to our caller
    //

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


PCCB
FatCreateCcb (
    IN PIRP_CONTEXT IrpContext
    )

/*++

Routine Description:

    This routine creates a new CCB record

Arguments:

Return Value:

    CCB - returns a pointer to the newly allocate CCB

--*/

{
    PCCB Ccb;

    DebugTrace(+1, Dbg, "FatCreateCcb\n", 0);

    //
    //  Allocate a new CCB Record
    //

    Ccb = FatAllocateCcb();

    RtlZeroMemory( Ccb, sizeof(CCB) );

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

    Ccb->NodeTypeCode = FAT_NTC_CCB;
    Ccb->NodeByteSize = sizeof(CCB);

    //
    //  return and tell the caller
    //

⌨️ 快捷键说明

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