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

📄 dirsup.c

📁 windows 2000中的UDF文件系统的驱动程序.只有读的功能,不支持未关闭的盘片.只支持UDF2.0以下版本,不支持VAT格式的UDF.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

Copyright (c) 1996  Microsoft Corporation

Module Name:

    DirSup.c

Abstract:

    This module implements the support for walking across on-disk directory
    structures.

Author:

    Dan Lovinger    [DanLo]   11-Jun-1996

Revision History:

--*/

#include "UdfProcs.h"

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

#define BugCheckFileId                   (UDFS_BUG_CHECK_DIRSUP)

//
//  The local debug trace level
//

#define Dbg                              (UDFS_DEBUG_LEVEL_DIRSUP)

//
//  Local support routines.
//

BOOLEAN
UdfLookupDirEntryPostProcessing (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PDIR_ENUM_CONTEXT DirContext,
    IN BOOLEAN ReturnError
    );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, UdfCleanupDirContext)
#pragma alloc_text(PAGE, UdfFindDirEntry)
#pragma alloc_text(PAGE, UdfInitializeDirContext)
#pragma alloc_text(PAGE, UdfLookupDirEntryPostProcessing)
#pragma alloc_text(PAGE, UdfLookupInitialDirEntry)
#pragma alloc_text(PAGE, UdfLookupNextDirEntry)
#pragma alloc_text(PAGE, UdfUpdateDirNames)
#endif


VOID
UdfInitializeDirContext (
    IN PIRP_CONTEXT IrpContext,
    IN PDIR_ENUM_CONTEXT DirContext
    )

/*++

Routine Description:

    This routine initializes a directory enumeartion context.
    
    Call this exactly once in the lifetime of a context.

Arguments:

    DirContext - a context to initialize

Return Value:

    None.

--*/

{
    //
    //  Check inputs.
    //

    ASSERT_IRP_CONTEXT( IrpContext );

    //
    //  Provide defaults for fields, nothing too special.
    //

    RtlZeroMemory( DirContext, sizeof(DIR_ENUM_CONTEXT) );
}


VOID
UdfCleanupDirContext (
    IN PIRP_CONTEXT IrpContext,
    IN PDIR_ENUM_CONTEXT DirContext
    )

/*++

Routine Description:

    This routine cleans up a directory enumeration context for reuse.

Arguments:

    DirContext - a context to clean.

Return Value:

    None.

--*/

{
    PAGED_CODE();

    //
    //  Check input.
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    
    //
    //  Dump the allocation we store the triple of names in.
    //

    UdfFreePool( &DirContext->NameBuffer );

    //
    //  And the short name.
    //

    UdfFreePool( &DirContext->ShortObjectName.Buffer );

    //
    //  Unpin the view.
    //

    UdfUnpinData( IrpContext, &DirContext->Bcb );

    //
    //  Free a buffered Fid that may remain.
    //
    
    if (FlagOn( DirContext->Flags, DIR_CONTEXT_FLAG_FID_BUFFERED )) {

        UdfFreePool( &DirContext->Fid );
    }
    
    //
    //  Zero everything else out.
    //

    RtlZeroMemory( DirContext, sizeof( DIR_ENUM_CONTEXT ) );
}


BOOLEAN
UdfLookupInitialDirEntry (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PDIR_ENUM_CONTEXT DirContext,
    IN PLONGLONG InitialOffset OPTIONAL
    )

/*++

Routine Description:

    This routine begins the enumeration of a directory by setting the context
    at the first avaliable directory entry.

Arguments:

    Fcb - the directory being enumerated.
    
    DirContext - a corresponding context for the enumeration.
    
    InitialOffset - an optional starting byte offset to base the enumeration.

Return Value:

    If InitialOffset is unspecified, TRUE will always be returned.  Failure will result
    in a raised status indicating corruption.
    
    If InitialOffset is specified, TRUE will be returned if a valid entry is found at this
    offset, FALSE otherwise.

--*/

{
    BOOLEAN Result;

    PAGED_CODE();
    
    //
    //  Check inputs.
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_FCB_INDEX( Fcb );
    
    //
    //  Create the internal stream if it isn't already in place.
    //

    if (Fcb->FileObject == NULL) {

        UdfCreateInternalStream( IrpContext, Fcb->Vcb, Fcb );
    }

    //
    //  Reset the flags.
    //

    DirContext->Flags = 0;
    
    if (InitialOffset) {

        //
        //  If we are beginning in the middle of the stream, adjust the sanity check flags.
        //
        
        if (*InitialOffset != 0) {

            DirContext->Flags = DIR_CONTEXT_FLAG_SEEN_NONCONSTANT | DIR_CONTEXT_FLAG_SEEN_PARENT;
        }

        //
        //  Now set up the range we will map.  This is constrained by the size of a cache view.
        //
        
        DirContext->BaseOffset.QuadPart = GenericTruncate( *InitialOffset, VACB_MAPPING_GRANULARITY );
        DirContext->ViewOffset = (ULONG) GenericOffset( *InitialOffset, VACB_MAPPING_GRANULARITY );

    } else {
        
        //
        //  Map at the beginning.
        //
    
        DirContext->BaseOffset.QuadPart = 0;
        DirContext->ViewOffset = 0;
    }

    //
    //  Contain the view length by the size of the stream and map.
    //

    DirContext->ViewLength = VACB_MAPPING_GRANULARITY;

    if (DirContext->BaseOffset.QuadPart + DirContext->ViewLength > Fcb->FileSize.QuadPart) {

        DirContext->ViewLength = (ULONG) (Fcb->FileSize.QuadPart - DirContext->BaseOffset.QuadPart);
    }
    
    UdfUnpinData( IrpContext, &DirContext->Bcb );
    
    CcMapData( Fcb->FileObject,
               &DirContext->BaseOffset,
               DirContext->ViewLength,
               TRUE,
               &DirContext->Bcb,
               &DirContext->View );

    DirContext->Fid = Add2Ptr( DirContext->View, DirContext->ViewOffset, PNSR_FID );

    //
    //  The state of the context is now valid.  Tail off into our common post-processor
    //  to finish the work.
    //

    return UdfLookupDirEntryPostProcessing( IrpContext,
                                            Fcb,
                                            DirContext,
                                            (BOOLEAN) (InitialOffset != NULL));
}


BOOLEAN
UdfLookupNextDirEntry (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PDIR_ENUM_CONTEXT DirContext
    )

/*++

Routine Description:

    This routine advances the enumeration of a directory by one entry.

Arguments:

    Fcb - the directory being enumerated.
    
    DirContext - a corresponding context for the enumeration.

Return Value:

    BOOLEAN True if another Fid is avaliable, False if we are at the end.

--*/

{
    PAGED_CODE();
    
    //
    //  Check inputs.
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_FCB_INDEX( Fcb );

    //
    //  If we have reached the end, stop.
    //
    
    if (DirContext->BaseOffset.QuadPart + DirContext->NextFidOffset == Fcb->FileSize.QuadPart) {

        return FALSE;
    }

    //
    //  If the previous Fid was buffered, dismantle it now.
    //
    
    if (FlagOn( DirContext->Flags, DIR_CONTEXT_FLAG_FID_BUFFERED )) {

        ClearFlag( DirContext->Flags, DIR_CONTEXT_FLAG_FID_BUFFERED );
        UdfFreePool( &DirContext->Fid );
    }
    
    //
    //  Move the pointers based on the knowledge generated in the previous iteration.
    //

    DirContext->ViewOffset = DirContext->NextFidOffset;
    DirContext->Fid = Add2Ptr( DirContext->View, DirContext->ViewOffset, PNSR_FID );

    //
    //  The state of the context is now valid.  Tail off into our common post-processor
    //  to finish the work.
    //

    return UdfLookupDirEntryPostProcessing( IrpContext,
                                            Fcb,
                                            DirContext,
                                            FALSE );
}


VOID
UdfUpdateDirNames (
    IN PIRP_CONTEXT IrpContext,
    IN PDIR_ENUM_CONTEXT DirContext,
    IN BOOLEAN IgnoreCase
    )

/*++

Routine Description:

    This routine fills in the non-short names of a directory enumeration context
    for the Fid currently referenced.

Arguments:

    DirContext - a corresponding context to fill in.
    
    IgnoreCase - whether the caller wants to be insensitive to case.

Return Value:

    None.
    
--*/

{
    PUCHAR NameDstring;
    BOOLEAN ContainsIllegal;
    
    USHORT NameLength;
    USHORT BufferLength;
    USHORT PresentLength;
     
    PAGED_CODE();

    //
    //  Check input.
    //

    ASSERT_IRP_CONTEXT( IrpContext );

    DebugTrace(( +1, Dbg, "UdfUpdateDirNames\n" ));

    //
    //  Handle the case of the self directory entry.
    //

    if (DirContext->Fid == NULL) {

        //
        //  Simply synthesize
        //
        
        //

⌨️ 快捷键说明

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