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

📄 prefxsup.c

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

        UdfDissectName( IrpContext,
                        &LocalRemainingName,
                        &FinalName );

        //
        //  Check if this name is in the splay tree for this Scb.
        //

        if (IgnoreCase) {

            NameLink = UdfFindNameLink( IrpContext,
                                        &(*CurrentFcb)->IgnoreCaseRoot,
                                        &FinalName );

        } else {

            NameLink = UdfFindNameLink( IrpContext,
                                        &(*CurrentFcb)->ExactCaseRoot,
                                        &FinalName );
        }

        //
        //  If we didn't find a match then exit.
        //

        if (NameLink == NULL) { 

            break;
        }

        CurrentLcb = NameLink;

        //
        //  If this is a case-insensitive match then copy the exact case of the name into
        //  the input buffer.
        //

        if (IgnoreCase) {

            RtlCopyMemory( FinalName.Buffer,
                           NameLink->FileName.Buffer,
                           NameLink->FileName.Length );
        }

        //
        //  Update the caller's remaining name string to reflect the fact that we found
        //  a match.
        //

        *RemainingName = LocalRemainingName;

        //
        //  Move down to the next component in the tree.  Acquire without waiting.
        //  If this fails then lock the Fcb to reference this Fcb and then drop
        //  the parent and acquire the child.
        //

        ASSERT( NameLink->ParentFcb == *CurrentFcb );

        if (!UdfAcquireFcbExclusive( IrpContext, NameLink->ChildFcb, TRUE )) {

            //
            //  If we can't wait then raise CANT_WAIT.
            //

            if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {

                UdfRaiseStatus( IrpContext, STATUS_CANT_WAIT );
            }

            UdfLockVcb( IrpContext, IrpContext->Vcb );
            NameLink->ChildFcb->FcbReference += 1;
            NameLink->Reference += 1;
            UdfUnlockVcb( IrpContext, IrpContext->Vcb );

            UdfReleaseFcb( IrpContext, *CurrentFcb );
            UdfAcquireFcbExclusive( IrpContext, NameLink->ChildFcb, FALSE );

            UdfLockVcb( IrpContext, IrpContext->Vcb );
            NameLink->ChildFcb->FcbReference -= 1;
            NameLink->Reference -= 1;
            UdfUnlockVcb( IrpContext, IrpContext->Vcb );

        } else {

            UdfReleaseFcb( IrpContext, *CurrentFcb );
        }

        *CurrentFcb = NameLink->ChildFcb;
    }

    return CurrentLcb;
}



VOID            
UdfInitializeLcbFromDirContext (
    IN PIRP_CONTEXT IrpContext,
    IN PLCB Lcb,
    IN PDIR_ENUM_CONTEXT DirContext
    )

/*++

Routine Description:

    This routine performs common initialization of Lcbs from found directory
    entries.

Arguments:

    Lcb - the Lcb to initialize.
    
    DirContext - the directory enumeration context, enumerated to the FID associated
        with this Lcb.
    
Return Value:

    None.

--*/

{
    PAGED_CODE();

    //
    //  Check inputs.
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_LCB( Lcb );

    ASSERT( DirContext->Fid != NULL );

    //
    //  This is falling down trivial now.  Simply update the hidden flag in the Lcb.
    //

    if (FlagOn( DirContext->Fid->Flags, NSR_FID_F_HIDDEN )) {

        SetFlag( Lcb->FileAttributes, FILE_ATTRIBUTE_HIDDEN );
    }
}


//
//  Local support routine
//

PLCB
UdfFindNameLink (
    IN PIRP_CONTEXT IrpContext,
    IN PRTL_SPLAY_LINKS *RootNode,
    IN PUNICODE_STRING Name
    )

/*++

Routine Description:

    This routine searches through a splay link tree looking for a match for the
    input name.  If we find the corresponding name we will rebalance the
    tree.

Arguments:

    RootNode - Supplies the parent to search.

    Name - This is the name to search for.  Note if we are doing a case
        insensitive search the name would have been upcased already.

Return Value:

    PLCB - The name link found or NULL if there is no match.

--*/

{
    FSRTL_COMPARISON_RESULT Comparison;
    PLCB Node;
    PRTL_SPLAY_LINKS Links;

    PAGED_CODE();

    Links = *RootNode;

    while (Links != NULL) {

        Node = CONTAINING_RECORD( Links, LCB, Links );

        //
        //  Compare the prefix in the tree with the full name
        //

        Comparison = UdfFullCompareNames( IrpContext, &Node->FileName, Name );

        //
        //  See if they don't match
        //

        if (Comparison == GreaterThan) {

            //
            //  The prefix is greater than the full name
            //  so we go down the left child
            //

            Links = RtlLeftChild( Links );

            //
            //  And continue searching down this tree
            //

        } else if (Comparison == LessThan) {

            //
            //  The prefix is less than the full name
            //  so we go down the right child
            //

            Links = RtlRightChild( Links );

            //
            //  And continue searching down this tree
            //

        } else {

            //
            //  We found it.
            //
            //  Splay the tree and save the new root.
            //

            *RootNode = RtlSplay( Links );

            return Node;
        }
    }

    //
    //  We didn't find the Link.
    //

    return NULL;
}


//
//  Local support routine
//

BOOLEAN
UdfInsertNameLink (
    IN PIRP_CONTEXT IrpContext,
    IN PRTL_SPLAY_LINKS *RootNode,
    IN PLCB NameLink
    )

/*++

Routine Description:

    This routine will insert a name in the splay tree pointed to
    by RootNode.

Arguments:

    RootNode - Supplies a pointer to the table.

    NameLink - Contains the new link to enter.

Return Value:

    BOOLEAN - TRUE if the name is inserted, FALSE otherwise.

--*/

{
    FSRTL_COMPARISON_RESULT Comparison;
    PLCB Node;

    PAGED_CODE();

    //
    //  Check inputs.
    //

    ASSERT_IRP_CONTEXT( IrpContext );

    RtlInitializeSplayLinks( &NameLink->Links );

    //
    //  If we are the first entry in the tree, just become the root.
    //

    if (*RootNode == NULL) {

        *RootNode = &NameLink->Links;

        return TRUE;
    }

    Node = CONTAINING_RECORD( *RootNode, LCB, Links );

    while (TRUE) {

        //
        //  Compare the prefix in the tree with the prefix we want
        //  to insert.
        //

        Comparison = UdfFullCompareNames( IrpContext, &Node->FileName, &NameLink->FileName );

        //
        //  If we found the entry, return immediately.
        //

        if (Comparison == EqualTo) { return FALSE; }

        //
        //  If the tree prefix is greater than the new prefix then
        //  we go down the left subtree
        //

        if (Comparison == GreaterThan) {

            //
            //  We want to go down the left subtree, first check to see
            //  if we have a left subtree
            //

            if (RtlLeftChild( &Node->Links ) == NULL) {

                //
                //  there isn't a left child so we insert ourselves as the
                //  new left child
                //

                RtlInsertAsLeftChild( &Node->Links, &NameLink->Links );

                //
                //  and exit the while loop
                //

                break;

            } else {

                //
                //  there is a left child so simply go down that path, and
                //  go back to the top of the loop
                //

                Node = CONTAINING_RECORD( RtlLeftChild( &Node->Links ),
                                          LCB,
                                          Links );
            }

        } else {

            //
            //  The tree prefix is either less than or a proper prefix
            //  of the new string.  We treat both cases as less than when
            //  we do insert.  So we want to go down the right subtree,
            //  first check to see if we have a right subtree
            //

            if (RtlRightChild( &Node->Links ) == NULL) {

                //
                //  These isn't a right child so we insert ourselves as the
                //  new right child
                //

                RtlInsertAsRightChild( &Node->Links, &NameLink->Links );

                //
                //  and exit the while loop
                //

                break;

            } else {

                //
                //  there is a right child so simply go down that path, and
                //  go back to the top of the loop
                //

                Node = CONTAINING_RECORD( RtlRightChild( &Node->Links ),
                                          LCB,
                                          Links );
            }
        }
    }

    return TRUE;
}

⌨️ 快捷键说明

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