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

📄 prefxsup.c

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

        CdDissectName( IrpContext,
                       &LocalRemainingName,
                       &FinalName );

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

        if (IgnoreCase) {

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

            //
            //  Get the prefix entry from this NameLink.  Don't access any
            //  fields within it until we verify we have a name link.
            //

            PrefixEntry = (PPREFIX_ENTRY) CONTAINING_RECORD( NameLink,
                                                             PREFIX_ENTRY,
                                                             IgnoreCaseName );

        } else {

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

            PrefixEntry = (PPREFIX_ENTRY) CONTAINING_RECORD( NameLink,
                                                             PREFIX_ENTRY,
                                                             ExactCaseName );
        }

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

        if (NameLink == NULL) { return; }

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

        if (IgnoreCase) {

            RtlCopyMemory( FinalName.Buffer,
                           PrefixEntry->ExactCaseName.FileName.Buffer,
                           PrefixEntry->ExactCaseName.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.
        //

        if (!CdAcquireFcbExclusive( IrpContext, PrefixEntry->Fcb, TRUE )) {

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

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

                CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
            }

            CdLockVcb( IrpContext, IrpContext->Vcb );
            PrefixEntry->Fcb->FcbReference += 1;
            CdUnlockVcb( IrpContext, IrpContext->Vcb );

            CdReleaseFcb( IrpContext, *CurrentFcb );
            CdAcquireFcbExclusive( IrpContext, PrefixEntry->Fcb, FALSE );

            CdLockVcb( IrpContext, IrpContext->Vcb );
            PrefixEntry->Fcb->FcbReference -= 1;
            CdUnlockVcb( IrpContext, IrpContext->Vcb );

        } else {

            CdReleaseFcb( IrpContext, *CurrentFcb );
        }

        *CurrentFcb = PrefixEntry->Fcb;
    }
}


//
//  Local support routine
//

PNAME_LINK
CdFindNameLink (
    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:

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

--*/

{
    FSRTL_COMPARISON_RESULT Comparison;
    PNAME_LINK Node;
    PRTL_SPLAY_LINKS Links;

    PAGED_CODE();

    Links = *RootNode;

    while (Links != NULL) {

        Node = CONTAINING_RECORD( Links, NAME_LINK, Links );

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

        Comparison = CdFullCompareNames( 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
CdInsertNameLink (
    IN PIRP_CONTEXT IrpContext,
    IN PRTL_SPLAY_LINKS *RootNode,
    IN PNAME_LINK NameLink
    )

/*++

Routine Description:

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

    The name could already exist in this tree for a case-insensitive tree.
    In that case we simply return FALSE and do nothing.

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;
    PNAME_LINK Node;

    PAGED_CODE();

    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, NAME_LINK, Links );

    while (TRUE) {

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

        Comparison = CdFullCompareNames( 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 ),
                                          NAME_LINK,
                                          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 ),
                                          NAME_LINK,
                                          Links );
            }
        }
    }

    return TRUE;
}





⌨️ 快捷键说明

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