📄 sdpnodelist.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include "stdafx.h"
#include "BthApi.h"
#include "sdplib.h"
#include "SdpNodeList.h"
#include "util.h"
SdpNodeList::SdpNodeList()
{
nodeCount = 0;
SdpInitializeNodeHeader(this);
}
SdpNodeList::~SdpNodeList()
{
Destroy();
}
HRESULT SdpNodeList::CreateFromStream(UCHAR *pStream, ULONG size)
{
NTSTATUS status;
HRESULT err = S_OK;
//
// clear out previous contents
//
Destroy();
status = SdpTreeFromStream(pStream,
size,
this,
NULL,
FALSE);
if (NT_SUCCESS(status)) {
// PSDP_NODE pNode;
nodeCount = 0;
for (PLIST_ENTRY entry = Link.Flink;
entry != &Link;
) {
nodeCount++;
PSDP_NODE pNode = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
if (pNode->hdr.Type == SDP_TYPE_CONTAINER) {
CComPtr<ISdpNodeContainer> container;
#ifdef UNDER_CE
// WinCE uses ATL 2.1, no contaiener support.
err = CoCreateInstance(CLSID_SdpNodeContainer,NULL,CLSCTX_ALL,
__uuidof(ISdpNodeContainer),(void**)&container);
#else
err = container.CoCreateInstance(CLSID_SdpNodeContainer);
#endif
if (SUCCEEDED(err)) {
err = container->CreateFromStream(pNode->u.stream, pNode->u.streamLength);
if (SUCCEEDED(err)) {
//
// Must AddRef because when CComPtr goes out of
// scope it will call Release()
//
pNode->u.container = container;
pNode->u.container->AddRef();
pNode->hdr.SpecificType = SDP_ST_CONTAINER_INTERFACE;
}
else {
break;
}
}
else {
break;
}
}
entry = entry->Flink;
}
}
else {
err = MapNtStatusToHresult(status);
}
if (!SUCCEEDED(err)) {
Destroy();
}
return err;
}
void SdpNodeList::Lock(UCHAR lock)
{
PLIST_ENTRY entry;
for (entry = Link.Flink;
entry != &Link;
entry = entry->Flink) {
PSDP_NODE pNode = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
if (pNode->hdr.Type == SDP_TYPE_CONTAINER) {
pNode->u.container->LockContainer(lock);
}
}
}
PSDP_NODE SdpNodeList::GetNode(ULONG nodeIndex)
{
PLIST_ENTRY entry = Link.Flink;
while (nodeIndex > 0) {
entry = entry->Flink;
nodeIndex--;
}
return CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
}
void SdpNodeList::Destroy()
{
PSDP_NODE pNode;
if (!Sdp_IsListEmpty(&Link)) {
//
// SdpFreeNode will iteratively free all the nodes in the list and call
// Release() on all the container interfaces
//
pNode = CONTAINING_RECORD(Link.Flink, SDP_NODE, hdr.Link);
SdpFreeNode(pNode);
}
nodeCount = 0;
}
ULONG SdpNodeList::WriteStream(PUCHAR pStream)
{
PUCHAR pTmp;
ULONG numBytes = 0;
for (PLIST_ENTRY entry = Link.Flink;
entry != &Link;
entry = entry->Flink) {
PSDP_NODE pNode = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
if (pNode->hdr.Type == SDP_TYPE_CONTAINER) {
ULONG bytes = 0;
pNode->u.container->WriteStream(pStream, &bytes);
numBytes += bytes;
pStream += bytes;
}
else {
pTmp = WriteLeafToStream(pNode, pStream);
numBytes += (ULONG) (pTmp - pStream);
pStream = pTmp;
}
}
return numBytes;
}
ULONG SdpNodeList::GetStreamSize()
{
PLIST_ENTRY entry = Link.Flink;
PSDP_NODE pNode = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
ULONG size = 0;
//
// This will compute the size of all the nodes this container holds that
// are not containers themselvesj
//
ComputeNodeListSize(pNode, &size);
for ( ; entry != &Link; entry = entry->Flink) {
pNode = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
if (pNode->hdr.Type == SDP_TYPE_CONTAINER) {
ULONG tmp = 0;
pNode->u.container->GetStreamSize(&tmp);
pNode->DataSize = tmp;
size += tmp;
}
}
//
// We are interested in the size of the contents of the container itself
// and not the amount of storage required for the header and variable
// size
//
return size;
}
HRESULT SdpNodeList::Walk(ISdpWalk *pWalk)
{
HRESULT err = S_OK;
for (PLIST_ENTRY entry = Link.Flink;
entry != &Link;
entry = entry->Flink) {
NodeData nd;
PSDP_NODE pNode;
PCHAR str = NULL;
ZeroMemory(&nd, sizeof(nd));
pNode = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
CreateNodeDataFromSdpNode(pNode, &nd);
if (pNode->hdr.Type == SDP_TYPE_CONTAINER) {
err = pNode->u.container->Walk(pWalk);
if (!SUCCEEDED(err)) {
break;
}
}
else {
if (pNode->hdr.Type == SDP_TYPE_URL) {
CopyStringDataToNodeData(pNode->u.url,
pNode->DataSize,
&nd.u.url);
str = nd.u.url.val;
nd.type = pNode->hdr.Type;
nd.specificType = pNode->hdr.SpecificType;
}
else if (pNode->hdr.Type == SDP_TYPE_STRING) {
CopyStringDataToNodeData(pNode->u.url,
pNode->DataSize,
&nd.u.str);
str = nd.u.str.val;
nd.type = pNode->hdr.Type;
nd.specificType = pNode->hdr.SpecificType;
}
err = pWalk->WalkNode(&nd, 0);
if (str) {
CoTaskMemFree(str);
}
if (!SUCCEEDED(err)) {
break;
}
}
}
return err;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -