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

📄 node.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    case SDP_TYPE_LISTHEAD:
        InsertTailList(&Parent->hdr.Link, &Node->hdr.Link);
        break;

    default:
        return STATUS_INVALID_PARAMETER;
    }

    return STATUS_SUCCESS;
}

ULONG GetListLength(PLIST_ENTRY Head)
{
    PLIST_ENTRY current;
    ULONG size = 0;

    current = Head->Flink;

    while (1) {
        size++;
        current = current->Flink;
        if (current == Head) {
            return size;
        }
    }
}

NTSTATUS SdpFreeTree(PSDP_NODE Tree)
{
    if (Tree->hdr.Type != SDP_TYPE_LISTHEAD) {
        return STATUS_INVALID_PARAMETER;
    }

    if (!IsListEmpty(&Tree->hdr.Link)) {
        SdpFreeNode(CONTAINING_RECORD(Tree->hdr.Link.Flink, SDP_NODE, hdr.Link));
    }

    if (Tree->Reserved != NULL) {
        DecrementNodeRef((PSDP_NODE_REF) Tree->Reserved);
    }
    else {
        //
        // We have freed everything that is attached to this, free it
        //
        SdpFreePool(Tree);
    }

    return STATUS_SUCCESS;
}

NTSTATUS SdpFreeOrphanedNode(PSDP_NODE Node)
{
    SDP_NODE tmpHead;

    SdpInitializeNodeTree(&tmpHead);
    SdpAppendNodeToContainerNode(&tmpHead, Node);

    return SdpFreeNode(Node);
}

NTSTATUS SdpFreeNode(PSDP_NODE Node)
{
    SdpStack stack;
    SD_STACK_ENTRY *stackEntry;

    PLIST_ENTRY current;
    PSDP_NODE node;

    current = &Node->hdr.Link;

    while (1) {
        node = CONTAINING_RECORD(current, SDP_NODE, hdr.Link);

        if ((node->hdr.Type == SDP_TYPE_SEQUENCE ||
             node->hdr.Type == SDP_TYPE_ALTERNATIVE) 
                                                &&
            (!IsListEmpty(&node->u.sequence.Link) ||
             !IsListEmpty(&node->u.alternative.Link))
             ) {

            if (!NT_SUCCESS(stack.Push(node))) {
                //
                // recover as gracefully as possible
                //
                return STATUS_INSUFFICIENT_RESOURCES;
            }
                    
            if (node->hdr.Type == SDP_TYPE_ALTERNATIVE) {
                current = node->u.alternative.Link.Flink;
            }
            else {
                current = node->u.sequence.Link.Flink;
            }

            continue;
        }

        //
        // Advance to the next link in the list
        //
        current = current->Flink;

        //
        // Remove the node from the list.  
        //
        RemoveEntryList(&node->hdr.Link);

        // When a container is created by a user APP, it doesn't matter what
        // its SpecificType is, most likely it will by SDP_ST_NONE.  In the
        // SdpInitializeNodeContainer we set Type=SDP_TYPE_CONTAINER and
        // SpecificType = SDP_ST_CONTAINER_STREAM and have this be a pointer
        // to a stream, rather than an ISdpNodeContainer.  In this case we
        // can't release ISdpNodeContainer object.
        
        if ((node->hdr.Type == SDP_TYPE_CONTAINER) && (node->hdr.SpecificType != SDP_ST_CONTAINER_STREAM)) {
            // hitting this ASSERT shouldn't be harmful, but it means someone is 
            // setting up their node in an unexpected way (and possibly wrong way), 
            // needs investigation. 
            SVSUTIL_ASSERT((node->hdr.SpecificType == SDP_ST_CONTAINER_INTERFACE) || (node->hdr.SpecificType == SDP_ST_NONE));
            SdpReleaseContainer(node->u.container);
        }

        //
        // Finally, free the node
        //
        if (node->Reserved == NULL) {
            SdpFreePool(node);
        } else {
			DecrementNodeRef((PSDP_NODE_REF) node->Reserved);
        }

        //
        // Check to see if we have reached the end of the linked list
        //
        while (IsListEmpty(current)) {
            //
            // Check to see if we have pushed any items.  If not, then we are 
            // done.
            //
            if (stack.Depth() == 0) {
                return STATUS_SUCCESS;
            }

            //
            // Get the stored values.  Since we are now removing an node,
            // decrement size.
            //
            stackEntry = stack.Pop();

            node = stackEntry->Node;

            //
            // Get the next link in the chain before removing the node from the
            // list
            //
            current = node->hdr.Link.Flink;
            RemoveEntryList(&node->hdr.Link);
        
            //
            // Finally, free the node
            //
            if (node->Reserved == NULL) {
                SdpFreePool(node);
            } else {
				DecrementNodeRef((PSDP_NODE_REF) node->Reserved);
            }
        }
    }
}

NTSTATUS SdpAddAttributeToNodeHeader(PSDP_NODE_HEADER Header, USHORT AttribId, PSDP_NODE AttribValue)
{
    PSDP_NODE nodeId, nodeValue, attrib;
    PLIST_ENTRY current;

    nodeId = CONTAINING_RECORD(Header->Link.Flink, SDP_NODE, hdr.Link);
    nodeValue = CONTAINING_RECORD(nodeId->hdr.Link.Flink, SDP_NODE, hdr.Link);

    current = &nodeValue->hdr.Link;

    //
    // iterate over the attribute id / value pairs  in the list and see where 
    // this entry goes.
    //
    // Attribute IDs are added in increasing numerical order!
    //
    while (1) {
        //
        // Do the following
        // 1 make sure we have a USHORT node AND
        // 2 if we are replacing a value OR
        // 3 if we are inserting a value OR
        // 4 going to the next pair in the list AND
        // 5 checking if we are at the end of the list, and if so, appending
        //   the pair
        //


        // Initial insertion
        if (IsListEmpty(&Header->Link)) {
            if (AttribValue == NULL) {
                return STATUS_NOT_FOUND;
            }

            attrib = SdpCreateNodeUInt16(AttribId);
            if (attrib == NULL) {
                return STATUS_INSUFFICIENT_RESOURCES;
            }

            InsertTailList(&Header->Link, &attrib->hdr.Link);
            InsertTailList(&Header->Link, &AttribValue->hdr.Link);

            return STATUS_SUCCESS;
        }
        //
        // Check to see if we have a valid attrib id node
        //         
        else if (nodeId->hdr.Type != SDP_TYPE_UINT ||
            nodeId->hdr.SpecificType != SDP_ST_UINT16 ||
            nodeId->DataSize != sizeof(AttribId)) {
            return STATUS_INVALID_PARAMETER;
        }
        else if (AttribId == nodeId->u.uint16) {
            //
            // We are replacing or removing a value
            //

            //
            // Remove the value from the tree in both cases
            //
            RemoveEntryList(&nodeValue->hdr.Link);
            SdpFreeOrphanedNode(nodeValue);

            //
            // Check to see if we are removing
            //
            if (AttribValue == NULL) {
                //
                // Remove the ID as well
                //
                RemoveEntryList(&nodeId->hdr.Link);
                SdpFreeOrphanedNode(nodeId);
            }
            else {
                InsertEntryList(&nodeId->hdr.Link, &AttribValue->hdr.Link); 
            }

            return STATUS_SUCCESS;
        }
        else if (AttribId < nodeId->u.uint16) {

            //
            // We are inserting a value into the middle of the list
            //

            //
            // Must have a valid AttribValue in this case
            //
            if (AttribValue == NULL) {
                return STATUS_INVALID_PARAMETER;
            }

            attrib = SdpCreateNodeUInt16(AttribId);
            if (attrib == NULL) {
                return STATUS_INSUFFICIENT_RESOURCES;
            }

            //
            // hdr.Link in the attribute ID before the current entry and
            // then link in the attribute value after the newly placed
            // ID
            //
            InsertEntryList(nodeId->hdr.Link.Blink, &attrib->hdr.Link);
            InsertEntryList(&attrib->hdr.Link, &AttribValue->hdr.Link);

            return STATUS_SUCCESS;
        }
        else {
            current = current->Flink;

            //
            // Check to see if we have wrapped to the end of the list.  If 
            // so, insert the ID / value pair at the end of the list
            //
            if (current == &Header->Link) {
                if (AttribValue == NULL) {
                    return STATUS_NOT_FOUND;
                }

                attrib = SdpCreateNodeUInt16(AttribId);
                if (attrib == NULL) {
                    return STATUS_INSUFFICIENT_RESOURCES;
                }

                InsertTailList(&Header->Link, &attrib->hdr.Link);
                InsertTailList(&Header->Link, &AttribValue->hdr.Link);

                return STATUS_SUCCESS;
            }
            else {
                nodeId = CONTAINING_RECORD(current, SDP_NODE, hdr.Link);
                ASSERT(nodeId->hdr.Type != SDP_TYPE_LISTHEAD);

                current = current->Flink;
                nodeValue = CONTAINING_RECORD(current, SDP_NODE, hdr.Link);
            }
        }
    }
}

NTSTATUS SdpAddAttributeToTree(PSDP_NODE Root, USHORT AttribId, PSDP_NODE AttribValue)
{
    PSDP_NODE attrib, sequence;

    if (IsListEmpty(&Root->hdr.Link)) {
        if (AttribValue == NULL) {
            return STATUS_INVALID_PARAMETER;
        }

        sequence = SdpCreateNodeSequence();
        SdpAppendNodeToContainerNode((PSDP_NODE) Root, sequence);
    }
    else {
        sequence = CONTAINING_RECORD(Root->hdr.Link.Flink, SDP_NODE, hdr.Link);
    }

	if (sequence->hdr.Type != SDP_TYPE_SEQUENCE) {
		return STATUS_INVALID_PARAMETER;
	}

    if (IsListEmpty(&sequence->u.sequence.Link)) {
        if (AttribValue == NULL) {
            return STATUS_INVALID_PARAMETER;
        }

        attrib = SdpCreateNodeUInt16(AttribId);
        if (attrib == NULL) {
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        SdpAppendNodeToContainerNode(sequence, attrib);
        SdpAppendNodeToContainerNode(sequence, AttribValue);

        return STATUS_SUCCESS;
    }
    else {
//      PLIST_ENTRY current;
//      PSDP_NODE nodeId, nodeValue;

        if ((GetListLength(&sequence->u.sequence.Link) % 2) != 0) {
            //
            // Invalid list, must be a multiple of 2
            //
            return STATUS_INVALID_PARAMETER;
        }

        return SdpAddAttributeToNodeHeader(&sequence->u.sequence, AttribId, AttribValue);
    }
}

void DecrementNodeRef(PSDP_NODE_REF NodeRef)
{
	if (SdpInterlockedDecrement(&NodeRef->RefCount) == 0) {
		SdpFreePool(NodeRef->Alloc);
        SdpFreePool(NodeRef);
	}
}

⌨️ 快捷键说明

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