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

📄 stream.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                SdpInitializeNodeInt8(node, (CHAR) *Stream);
                break;

            case 1:  
                dataSize = 2; 
                RtlRetrieveUshort(&uint16, Stream);
                SdpInitializeNodeInt16(node, (SHORT) RtlUshortByteSwap(uint16));
                break;

            case 2:  
                dataSize = 4; 
                RtlRetrieveUlong(&uint32, Stream);
                SdpInitializeNodeInt32(node, (LONG) RtlUlongByteSwap(uint32));
                break;

            case 3:  
                dataSize = 8; 
                SdpRetrieveUlonglong(&uint64, Stream);
                SdpInitializeNodeInt64(node, (LONGLONG) SdpUlonglongByteSwap(uint64));
                break;

            case 4:  
                dataSize = 16; 

                SdpRetrieveUint128(Stream, (PSDP_ULARGE_INTEGER_16) &int128);

                int128.HighPart =
                    (LONGLONG) SdpUlonglongByteSwap((LONGLONG) int128.HighPart);
                int128.LowPart = SdpUlonglongByteSwap(int128.LowPart);

                SdpInitializeNodeInt128(node, &int128);
                break;

            default:
                ASSERT(FALSE); 
                return NULL;
            }

            LINK_IN_NODE(head, node);
            INC_STREAM(dataSize);
            break;

        case SDP_TYPE_UUID:
            //
            // valid indecies are 1,2,4
            //
            switch (sizeIndex) {
            case 1:  
                dataSize = 2; 
                RtlRetrieveUshort(&uint16, Stream);
                SdpInitializeNodeUUID16(node, RtlUshortByteSwap(uint16));
                break;

            case 2:  
                dataSize = 4; 
                RtlRetrieveUlong(&uint32, Stream);
                SdpInitializeNodeUUID32(node, RtlUlongByteSwap(uint32));
                break;

            case 4:  
                dataSize = 16; 

                //
                // Retrieve the whole structure ...
                //
                SdpRetrieveUuid128(Stream, &uuid128Tmp);

                //
                // ... and then convert into little endian
                //
                SdpByteSwapUuid128(&uuid128Tmp, &uuid128);

                SdpInitializeNodeUUID128(node, &uuid128);
                break;

            default: 
                ASSERT(FALSE);
                return NULL;
            }

            LINK_IN_NODE(head, node);
            INC_STREAM(dataSize);
            break;

        case SDP_TYPE_URL:
        case SDP_TYPE_STRING:
        case SDP_TYPE_SEQUENCE:
        case SDP_TYPE_ALTERNATIVE:
            //
            // valid indecies are 5, 6 ,7
            //
            // Retrieve the size, convert it to little endian, and then compute
            // the total size for this element (amount of storage for the size
            // + the size itself).  
            //
            // Furthermore, make sure we have enough storage for the stored size.
            //
            SdpRetrieveVariableSize(Stream, sizeIndex, &elementSize, &storageSize);

            switch (type) {
            case SDP_TYPE_URL:
                SdpInitializeNodeUrl(node,
                                     (PCHAR) Stream + storageSize,
                                      elementSize,
                                      ExtraPool);
                ExtraPool += ROUND_SIZE(elementSize);
                break;

            case SDP_TYPE_STRING:
                SdpInitializeNodeString(node,
                                        (PCHAR) Stream + storageSize,
                                         elementSize,
                                         ExtraPool);
                ExtraPool += ROUND_SIZE(elementSize);
                break;

            case SDP_TYPE_SEQUENCE:
            case SDP_TYPE_ALTERNATIVE:
                if (FullParse) {
                    if (type == SDP_TYPE_SEQUENCE) {
                        SdpInitializeNodeSequence(node);
                        newHead = &node->u.sequence.Link;
                    }
                    else {
                        SdpInitializeNodeAlternative(node);
                        newHead = &node->u.alternative.Link;
                    }

                    node->DataSize = elementSize;

                    if (elementSize > 0) {
                        INC_STREAM(storageSize);
                        status = stack.Push(node, Size, head);
                        if (!NT_SUCCESS(status)) {
                            return NULL;
                        }

                        LINK_IN_NODE(head, node);

                        //
                        // LINK_IN_NODE incremented node, so it is now pointing to a
                        // new and unused slot in the array
                        //
                        head = newHead;
                        Size = elementSize;
                        continue;
                    }
                }
                else {
                    //
                    // don't recurse on the container, just store the stream for
                    // it, including the element header (which we just incremented
                    // past)
                    //
                    SdpInitializeNodeContainer(
                        node,
                        Stream - 1,
                        elementSize + 1 // we subtracted 1 for element header above
                                    + storageSize
                        );
                }
                break;
            }

            LINK_IN_NODE(head, node);
            INC_STREAM(storageSize + elementSize);
            break;

        default:
            // there is an error in the stream
            ASSERT(FALSE);
            return NULL;
        }

        if ((int) Size < 0) {
        	return NULL;
        }

        while (Size == 0) {
            //
            // Check to see if we have pushed any items.  If not, then we are 
            // done
            //
            if (stack.Depth() == 0) {
                return Nodes;
            }

            stackEntry = stack.Pop();            

            Size = stackEntry->Size - stackEntry->Node->DataSize;
            head = stackEntry->Head;
        }
    }

    return Nodes;
#undef INC_STREAM
#undef LINK_IN_NODE
}


NTSTATUS
SdpTreeFromStream(
    PUCHAR Stream,
    ULONG Size,
    PSDP_NODE_HEADER Header,
    PSDP_NODE *Root,
    UCHAR FullParse
    )
{
    PSDP_NODE_REF ref;
    PSDP_NODE node, result;
    PCHAR extra;
    ULONG numEntries, extraPool, i, nodeSize; // valid,
    NTSTATUS status;
    ULONG_PTR errorByte;

    numEntries = 0;
    extraPool = 0;

    status = ValidateStream(Stream, Size, &numEntries, &extraPool, &errorByte);

    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // recompute the number of required entries if we are not parsing the entire
    // tree
    //
    if (!FullParse) {
        numEntries = ComputeNumberOfEntries(Stream, Size, FullParse);
    }

    //
    // Need to have a tree head as well if the caller doesn't provide a list head
    //
    if (Header == NULL) {
        numEntries++;
    }

    ref = (PSDP_NODE_REF) SdpAllocatePool(sizeof(SDP_NODE_REF));
    if (!ref) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    nodeSize = ROUND_SIZE(sizeof(SDP_NODE) * numEntries);
    node = (PSDP_NODE) SdpAllocatePool(nodeSize + extraPool);

    if (!node) {
        SdpFreePool(ref);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    extra = NULL;
    if (extraPool > 0) {
        extra = ((PCHAR) node) + nodeSize;
    }

    ref->Alloc = node;
    ref->RefCount = (LONG) numEntries;

    for (i = 0; i < numEntries; i++) {
        InitializeListHead(&node[i].hdr.Link);
        node[i].Reserved = ref;
    }

    result = StreamToNode(Stream, Size, Header, node, extra, FullParse);
    if (result) {
        if (Root) {
            *Root = result;
        }
        return STATUS_SUCCESS;
    }
    else {
        if (Header) {
            SdpInitializeNodeHeader(Header);
        }

        SdpFreePool(node);

        if (Root) {
            *Root = NULL;
        }

        return STATUS_INVALID_PARAMETER;
    }
}

NTSTATUS NodeToStream(PSDP_NODE Node, PUCHAR Stream)
{
    PSD_STACK_ENTRY stackEntry;
	PSDP_NODE_HEADER header;
    PLIST_ENTRY current; 
    PSDP_NODE node;

    SdpStack stack;
    NTSTATUS status;
    UCHAR byte;
    
    current = &Node->hdr.Link;

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

        switch (node->hdr.Type) {
        case SDP_TYPE_SEQUENCE:
        case SDP_TYPE_ALTERNATIVE:
            Stream = WriteVariableSizeToStream((UCHAR) node->hdr.Type,
                                               node->DataSize,
                                               Stream);

            //
            // node->DataSize == 0 if there is no sublist
            //
            if (node->DataSize) {
                status = stack.Push(node);

                if (!NT_SUCCESS(status)) {
                    return status;
                }

                if (node->hdr.Type == SDP_TYPE_SEQUENCE) {
                    node = CONTAINING_RECORD(node->u.sequence.Link.Flink,
                                             SDP_NODE, 
                                             hdr.Link);
                }
                else {
                    node = CONTAINING_RECORD(node->u.alternative.Link.Flink,
                                             SDP_NODE, 
                                             hdr.Link);
                }

                current = &node->hdr.Link;    
                continue;
            }
            break;

        default:
            Stream = WriteLeafToStream(node, Stream);
            break;
        }

        //
        // Advance to the next 
        //
        current = current->Flink;
		header = CONTAINING_RECORD(current, SDP_NODE_HEADER, Link);

        while (header->Type == SDP_TYPE_LISTHEAD) {
            //
            // Check to see if we have pushed any items.  If not, then we are 
            // done
            //
            if (stack.Depth() == 0) {
                return STATUS_SUCCESS;
            }

            stackEntry = stack.Pop();            

            node = stackEntry->Node;
            current = node->hdr.Link.Flink;
			header = CONTAINING_RECORD(current, SDP_NODE_HEADER, Link);
        }
    } 

    return STATUS_SUCCESS;
}

NTSTATUS SdpStreamFromTree(PSDP_NODE Root, PUCHAR *Stream, PULONG Size)
{
    return SdpStreamFromTreeEx(Root, Stream, Size, 0, 0);
}

NTSTATUS SdpStreamFromTreeEx(PSDP_NODE Root, PUCHAR *Stream, PULONG Size, ULONG HeaderSize, ULONG TailSize)
{
    PUCHAR stream;
    PSDP_NODE first;
    NTSTATUS status;

    *Stream = NULL;

    if (Root->hdr.Type != SDP_TYPE_LISTHEAD) {
        return STATUS_INVALID_PARAMETER;
    }

    if (IsListEmpty(&Root->hdr.Link)) {
        *Size = 0;
        return STATUS_SUCCESS;
    }

    first = CONTAINING_RECORD(Root->hdr.Link.Flink, SDP_NODE, hdr.Link);
    status = ComputeNodeListSize(first, Size);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    stream = (PUCHAR) SdpAllocatePool(HeaderSize + *Size + TailSize);  
    if (stream == NULL) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = NodeToStream(first, stream + HeaderSize);
    if (!NT_SUCCESS(status)) {
        SdpFreePool(stream);
        return status;
    }

    *Stream = stream;
    return STATUS_SUCCESS;
}

⌨️ 快捷键说明

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