コード例 #1
0
/*
 * @implemented
 */
PVOID
NTAPI
RtlEnumerateGenericTableWithoutSplaying(IN PRTL_GENERIC_TABLE Table,
                                        IN OUT PVOID *RestartKey)
{
    PRTL_SPLAY_LINKS FoundNode;

    /* Check if the table is empty */
    if (RtlIsGenericTableEmpty(Table)) return NULL;

    /* Check if we have to restart */
    if (!(*RestartKey))
    {
        /* Then find the leftmost element */
        FoundNode = Table->TableRoot;
        do
        {
            /* Get the left child */
            FoundNode = RtlLeftChild(FoundNode);
        } while(RtlLeftChild(FoundNode));

        /* Splay it */
        *RestartKey = FoundNode;
    }
    else
    {
        /* Otherwise, try using the real successor */
        FoundNode = RtlRealSuccessor(*RestartKey);
        if (FoundNode) *RestartKey = FoundNode;
    }

    /* Check if we found the node and return it */
    return FoundNode ? &((PTABLE_ENTRY_HEADER)FoundNode)->UserData : NULL;
}
コード例 #2
0
TABLE_SEARCH_RESULT
NTAPI
RtlpFindGenericTableNodeOrParent(IN PRTL_GENERIC_TABLE Table,
                                 IN PVOID Buffer,
                                 OUT PRTL_SPLAY_LINKS *NodeOrParent)
{
    PRTL_SPLAY_LINKS CurrentNode, ChildNode;
    RTL_GENERIC_COMPARE_RESULTS Result;

    /* Quick check to see if the table is empty */
    if (RtlIsGenericTableEmpty(Table))
    {
        *NodeOrParent = NULL;
        return TableEmptyTree;
    }

    /* Set the current node */
    CurrentNode = Table->TableRoot;

    /* Start compare loop */
    while (TRUE)
    {
        /* Do the compare */
        Result = Table->CompareRoutine(Table,
                                       Buffer,
                                       &((PTABLE_ENTRY_HEADER)CurrentNode)->
                                       UserData);
        if (Result == GenericLessThan)
        {
            /* We're less, check if this is the left child */
            if ((ChildNode = RtlLeftChild(CurrentNode)))
            {
                /* Continue searching from this node */
                CurrentNode = ChildNode;
            }
            else
            {
                /* Otherwise, the element isn't in this tree */
                *NodeOrParent = CurrentNode;
                return TableInsertAsLeft;
            }
        }
        else if (Result == GenericGreaterThan)
        {
            /* We're more, check if this is the right child */
            if ((ChildNode = RtlRightChild(CurrentNode)))
            {
                /* Continue searching from this node */
                CurrentNode = ChildNode;
            }
            else
            {
                /* Otherwise, the element isn't in this tree */
                *NodeOrParent = CurrentNode;
                return TableInsertAsRight;
            }
        }
        else
        {
            /* We should've found the node */
            ASSERT(Result == GenericEqual);

            /* Return node found */
            *NodeOrParent = CurrentNode;
            return TableFoundNode;
        }
    }
}
コード例 #3
0
ファイル: gentable.c プロジェクト: Gaikokujin/WinNT4
PVOID
RtlEnumerateGenericTable (
    IN PRTL_GENERIC_TABLE Table,
    IN BOOLEAN Restart
    )

/*++

Routine Description:

    The function EnumerateGenericTable will return to the caller one-by-one
    the elements of of a table.  The return value is a pointer to the user
    defined structure associated with the element.  The input parameter
    Restart indicates if the enumeration should start from the beginning
    or should return the next element.  If the are no more new elements to
    return the return value is NULL.  As an example of its use, to enumerate
    all of the elements in a table the user would write:

        for (ptr = EnumerateGenericTable(Table,TRUE);
             ptr != NULL;
             ptr = EnumerateGenericTable(Table, FALSE)) {
                :
        }

Arguments:

    Table - Pointer to the generic table to enumerate.

    Restart - Flag that if true we should start with the least
              element in the tree otherwise, return we return
              a pointer to the user data for the root and make
              the real successor to the root the new root.

Return Value:

    PVOID - Pointer to the user data.

--*/

{

    if (RtlIsGenericTableEmpty(Table)) {

        //
        // Nothing to do if the table is empty.
        //

        return NULL;

    } else {

        //
        // Will be used as the "iteration" through the tree.
        //
        PRTL_SPLAY_LINKS NodeToReturn;

        //
        // If the restart flag is true then go to the least element
        // in the tree.
        //

        if (Restart) {

            //
            // We just loop until we find the leftmost child of the root.
            //

            for (
                NodeToReturn = Table->TableRoot;
                RtlLeftChild(NodeToReturn);
                NodeToReturn = RtlLeftChild(NodeToReturn)
                ) {
                ;
            }

            Table->TableRoot = RtlSplay(NodeToReturn);

        } else {

            //
            // The assumption here is that the root of the
            // tree is the last node that we returned.  We
            // find the real successor to the root and return
            // it as next element of the enumeration.  The
            // node that is to be returned is splayed (thereby
            // making it the root of the tree).  Note that we
            // need to take care when there are no more elements.
            //

            NodeToReturn = RtlRealSuccessor(Table->TableRoot);

            if (NodeToReturn) {

                Table->TableRoot = RtlSplay(NodeToReturn);

            }

        }

        //
        // If there actually is a next element in the enumeration
        // then the pointer to return is right after the list links.
        //

        return ((NodeToReturn)?
                   ((PVOID)((PLIST_ENTRY)((PVOID)(NodeToReturn+1))+1))
                  :((PVOID)(NULL)));

    }

}
コード例 #4
0
ファイル: gentable.c プロジェクト: Gaikokujin/WinNT4
PVOID
RtlEnumerateGenericTableWithoutSplaying (
    IN PRTL_GENERIC_TABLE Table,
    IN PVOID *RestartKey
    )

/*++

Routine Description:

    The function EnumerateGenericTableWithoutSplaying will return to the
    caller one-by-one the elements of of a table.  The return value is a
    pointer to the user defined structure associated with the element.
    The input parameter RestartKey indicates if the enumeration should
    start from the beginning or should return the next element.  If the
    are no more new elements to return the return value is NULL.  As an
    example of its use, to enumerate all of the elements in a table the
    user would write:

        *RestartKey = NULL;

        for (ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey);
             ptr != NULL;
             ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey)) {
                :
        }

Arguments:

    Table - Pointer to the generic table to enumerate.

    RestartKey - Pointer that indicates if we should restart or return the next
                element.  If the contents of RestartKey is NULL, the search
                will be started from the beginning.

Return Value:

    PVOID - Pointer to the user data.

--*/

{

    if (RtlIsGenericTableEmpty(Table)) {

        //
        // Nothing to do if the table is empty.
        //

        return NULL;

    } else {

        //
        // Will be used as the "iteration" through the tree.
        //
        PRTL_SPLAY_LINKS NodeToReturn;

        //
        // If the restart flag is true then go to the least element
        // in the tree.
        //

        if (*RestartKey == NULL) {

            //
            // We just loop until we find the leftmost child of the root.
            //

            for (
                NodeToReturn = Table->TableRoot;
                RtlLeftChild(NodeToReturn);
                NodeToReturn = RtlLeftChild(NodeToReturn)
                ) {
                ;
            }

            *RestartKey = NodeToReturn;

        } else {

            //
            // The caller has passed in the previous entry found
            // in the table to enable us to continue the search.  We call
            // RtlRealSuccessor to step to the next element in the tree.
            //

            NodeToReturn = RtlRealSuccessor(*RestartKey);

            if (NodeToReturn) {

                *RestartKey = NodeToReturn;

            }

        }

        //
        // If there actually is a next element in the enumeration
        // then the pointer to return is right after the list links.
        //

        return ((NodeToReturn)?
                   ((PVOID)((PLIST_ENTRY)((PVOID)(NodeToReturn+1))+1))
                  :((PVOID)(NULL)));

    }

}
コード例 #5
0
ファイル: gentable.c プロジェクト: Gaikokujin/WinNT4
static
SEARCH_RESULT
FindNodeOrParent(
    IN PRTL_GENERIC_TABLE Table,
    IN PVOID Buffer,
    OUT PRTL_SPLAY_LINKS *NodeOrParent
    )

/*++

Routine Description:

    This routine is used by all of the routines of the generic
    table package to locate the a node in the tree.  It will
    find and return (via the NodeOrParent parameter) the node
    with the given key, or if that node is not in the tree it
    will return (via the NodeOrParent parameter) a pointer to
    the parent.

Arguments:

    Table - The generic table to search for the key.

    Buffer - Pointer to a buffer holding the key.  The table
             package doesn't examine the key itself.  It leaves
             this up to the user supplied compare routine.

    NodeOrParent - Will be set to point to the node containing the
                   the key or what should be the parent of the node
                   if it were in the tree.  Note that this will *NOT*
                   be set if the search result is EmptyTree.

Return Value:

    SEARCH_RESULT - EmptyTree: The tree was empty.  NodeOrParent
                               is *not* altered.

                    FoundNode: A node with the key is in the tree.
                               NodeOrParent points to that node.

                    InsertAsLeft: Node with key was not found.
                                  NodeOrParent points to what would be
                                  parent.  The node would be the left
                                  child.

                    InsertAsRight: Node with key was not found.
                                   NodeOrParent points to what would be
                                   parent.  The node would be the right
                                   child.

--*/



{

    if (RtlIsGenericTableEmpty(Table)) {

        return EmptyTree;

    } else {

        //
        // Used as the iteration variable while stepping through
        // the generic table.
        //
        PRTL_SPLAY_LINKS NodeToExamine = Table->TableRoot;

        //
        // Just a temporary.  Hopefully a good compiler will get
        // rid of it.
        //
        PRTL_SPLAY_LINKS Child;

        //
        // Holds the value of the comparasion.
        //
        RTL_GENERIC_COMPARE_RESULTS Result;

        while (TRUE) {

            //
            // Compare the buffer with the key in the tree element.
            //

            Result = Table->CompareRoutine(
                         Table,
                         Buffer,
                         ((PLIST_ENTRY)((PVOID)(NodeToExamine+1)))+1
                         );

            if (Result == GenericLessThan) {

                if (Child = RtlLeftChild(NodeToExamine)) {

                    NodeToExamine = Child;

                } else {

                    //
                    // Node is not in the tree.  Set the output
                    // parameter to point to what would be its
                    // parent and return which child it would be.
                    //

                    *NodeOrParent = NodeToExamine;
                    return InsertAsLeft;

                }

            } else if (Result == GenericGreaterThan) {

                if (Child = RtlRightChild(NodeToExamine)) {

                    NodeToExamine = Child;

                } else {

                    //
                    // Node is not in the tree.  Set the output
                    // parameter to point to what would be its
                    // parent and return which child it would be.
                    //

                    *NodeOrParent = NodeToExamine;
                    return InsertAsRight;

                }


            } else {

                //
                // Node is in the tree (or it better be because of the
                // assert).  Set the output parameter to point to
                // the node and tell the caller that we found the node.
                //

                ASSERT(Result == GenericEqual);
                *NodeOrParent = NodeToExamine;
                return FoundNode;

            }

        }

    }

}