298 lines
7 KiB
C++
298 lines
7 KiB
C++
//---------------------------------------------------------------------------
|
|
//
|
|
// Module: tn.cpp
|
|
//
|
|
// Description:
|
|
//
|
|
// Topology Node Class
|
|
//
|
|
//@@BEGIN_MSINTERNAL
|
|
// Development Team:
|
|
// Mike McLaughlin
|
|
//
|
|
// History: Date Author Comment
|
|
//
|
|
// To Do: Date Author Comment
|
|
//
|
|
//@@END_MSINTERNAL
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
|
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
|
// PURPOSE.
|
|
//
|
|
// Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include "common.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
CTopologyNode::Create(
|
|
PTOPOLOGY_NODE *ppTopologyNode,
|
|
PFILTER_NODE pFilterNode,
|
|
ULONG ulNodeNumber,
|
|
GUID *pguidType
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
PTOPOLOGY_NODE pTopologyNode;
|
|
|
|
pTopologyNode = new TOPOLOGY_NODE(pFilterNode, ulNodeNumber, pguidType);
|
|
if(pTopologyNode == NULL) {
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
Trap();
|
|
goto exit;
|
|
}
|
|
DPF2(70, "CTopologyNode::Create: %08x, FN: %08x",
|
|
pTopologyNode,
|
|
pFilterNode);
|
|
exit:
|
|
*ppTopologyNode = pTopologyNode;
|
|
return(Status);
|
|
}
|
|
|
|
CTopologyNode::CTopologyNode(
|
|
PFILTER_NODE pFilterNode,
|
|
ULONG ulNodeNumber,
|
|
GUID *pguidType
|
|
)
|
|
{
|
|
Assert(pFilterNode);
|
|
this->pFilterNode = pFilterNode;
|
|
this->ulRealNodeNumber = ulNodeNumber;
|
|
this->ulSysaudioNodeNumber = MAXULONG;
|
|
this->iVirtualSource = MAXULONG;
|
|
this->pguidType = pguidType;
|
|
AddList(&pFilterNode->lstTopologyNode);
|
|
DPF2(70, "CTopologyNode: %08x, FN: %08x", this, pFilterNode);
|
|
}
|
|
|
|
CTopologyNode::~CTopologyNode(
|
|
)
|
|
{
|
|
DPF1(70, "~CTopologyNode: %08x", this);
|
|
Assert(this);
|
|
}
|
|
|
|
NTSTATUS
|
|
CreateTopology(
|
|
PFILTER_NODE pFilterNode,
|
|
PKSTOPOLOGY pTopology
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
PTOPOLOGY_CONNECTION pTopologyConnection;
|
|
PTOPOLOGY_NODE *papTopologyNode = NULL;
|
|
PTOPOLOGY_NODE pTopologyNodeFrom;
|
|
PTOPOLOGY_NODE pTopologyNodeTo;
|
|
PTOPOLOGY_PIN pTopologyPinFrom;
|
|
PTOPOLOGY_PIN pTopologyPinTo;
|
|
PPIN_INFO pPinInfoFrom;
|
|
PPIN_INFO pPinInfoTo;
|
|
PPIN_INFO pPinInfo;
|
|
ULONG ulTopologyPinNumberFrom;
|
|
ULONG ulTopologyPinNumberTo;
|
|
ULONG n, c;
|
|
|
|
// If no topology, return error
|
|
if(pTopology->TopologyNodesCount == 0) {
|
|
if(pTopology->TopologyConnectionsCount == 0) {
|
|
DPF2(5,
|
|
"CreateTopology: FAILED, %s has no topology FN: %08x",
|
|
pFilterNode->DumpName(),
|
|
pFilterNode);
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto exit;
|
|
}
|
|
}
|
|
else {
|
|
papTopologyNode = new PTOPOLOGY_NODE[pTopology->TopologyNodesCount];
|
|
if(papTopologyNode == NULL) {
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
goto exit;
|
|
}
|
|
for(n = 0; n < pTopology->TopologyNodesCount; n++) {
|
|
|
|
Status = CTopologyNode::Create(
|
|
&papTopologyNode[n],
|
|
pFilterNode,
|
|
n,
|
|
(GUID *)&pTopology->TopologyNodes[n]);
|
|
|
|
if(!NT_SUCCESS(Status)) {
|
|
Trap();
|
|
goto exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(c = 0; c < pTopology->TopologyConnectionsCount; c++) {
|
|
|
|
pTopologyNodeFrom = pTopologyNodeTo = NULL;
|
|
pTopologyPinFrom = pTopologyPinTo = NULL;
|
|
pPinInfoFrom = pPinInfoTo = NULL;
|
|
|
|
if(pTopology->TopologyConnections[c].FromNode != KSFILTER_NODE) {
|
|
if(pTopology->TopologyConnections[c].FromNode >=
|
|
pTopology->TopologyNodesCount) {
|
|
DPF2(5,
|
|
"CreateTopology: FAILED, %s invalid 'from' node # %08x",
|
|
pFilterNode->DumpName(),
|
|
pTopology->TopologyConnections[c].FromNode);
|
|
Trap();
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto exit;
|
|
}
|
|
pTopologyNodeFrom =
|
|
papTopologyNode[pTopology->TopologyConnections[c].FromNode];
|
|
|
|
ulTopologyPinNumberFrom =
|
|
pTopology->TopologyConnections[c].FromNodePin;
|
|
}
|
|
|
|
if(pTopology->TopologyConnections[c].ToNode != KSFILTER_NODE) {
|
|
if(pTopology->TopologyConnections[c].ToNode >=
|
|
pTopology->TopologyNodesCount) {
|
|
DPF2(5,
|
|
"CreateTopology: FAILED, %s invalid 'to' node # %08x",
|
|
pFilterNode->DumpName(),
|
|
pTopology->TopologyConnections[c].ToNode);
|
|
Trap();
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto exit;
|
|
}
|
|
pTopologyNodeTo =
|
|
papTopologyNode[pTopology->TopologyConnections[c].ToNode];
|
|
|
|
ulTopologyPinNumberTo =
|
|
pTopology->TopologyConnections[c].ToNodePin;
|
|
}
|
|
|
|
if(pTopologyNodeFrom == NULL) {
|
|
|
|
FOR_EACH_LIST_ITEM(&pFilterNode->lstPinInfo, pPinInfo) {
|
|
|
|
if(pPinInfo->PinId ==
|
|
pTopology->TopologyConnections[c].FromNodePin) {
|
|
pPinInfoFrom = pPinInfo;
|
|
break;
|
|
}
|
|
|
|
} END_EACH_LIST_ITEM
|
|
|
|
if(pPinInfoFrom == NULL) {
|
|
DPF2(5,
|
|
"CreateTopology: FAILED, %s invalid 'from' node pin # %08x",
|
|
pFilterNode->DumpName(),
|
|
pTopology->TopologyConnections[c].FromNodePin);
|
|
Trap();
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto exit;
|
|
}
|
|
}
|
|
else {
|
|
Status = CTopologyPin::Create(
|
|
&pTopologyPinFrom,
|
|
ulTopologyPinNumberFrom,
|
|
pTopologyNodeFrom);
|
|
|
|
if(!NT_SUCCESS(Status)) {
|
|
Trap();
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
if(pTopologyNodeTo == NULL) {
|
|
|
|
FOR_EACH_LIST_ITEM(&pFilterNode->lstPinInfo, pPinInfo) {
|
|
|
|
if(pPinInfo->PinId ==
|
|
pTopology->TopologyConnections[c].ToNodePin) {
|
|
pPinInfoTo = pPinInfo;
|
|
break;
|
|
}
|
|
|
|
} END_EACH_LIST_ITEM
|
|
|
|
if(pPinInfoTo == NULL) {
|
|
DPF2(5,
|
|
"CreateTopology: FAILED, %s invalid 'to' node pin # %08x",
|
|
pFilterNode->DumpName(),
|
|
pTopology->TopologyConnections[c].ToNodePin);
|
|
Trap();
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto exit;
|
|
}
|
|
}
|
|
else {
|
|
Status = CTopologyPin::Create(
|
|
&pTopologyPinTo,
|
|
ulTopologyPinNumberTo,
|
|
pTopologyNodeTo);
|
|
|
|
if(!NT_SUCCESS(Status)) {
|
|
Trap();
|
|
goto exit;
|
|
}
|
|
}
|
|
Status = CTopologyConnection::Create(
|
|
&pTopologyConnection,
|
|
pFilterNode,
|
|
NULL,
|
|
pTopologyPinFrom,
|
|
pTopologyPinTo,
|
|
pPinInfoFrom,
|
|
pPinInfoTo);
|
|
|
|
if(!NT_SUCCESS(Status)) {
|
|
Trap();
|
|
goto exit;
|
|
}
|
|
ASSERT(IS_CONNECTION_TYPE(pTopologyConnection, FILTER));
|
|
}
|
|
exit:
|
|
delete [] papTopologyNode;
|
|
return(Status);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
#ifdef DEBUG
|
|
|
|
ENUMFUNC
|
|
CTopologyNode::Dump(
|
|
)
|
|
{
|
|
PLOGICAL_FILTER_NODE pLogicalFilterNode;
|
|
|
|
Assert(this);
|
|
dprintf("TN: %08x FN %08x R#%-2d S#%-2d I%-2d %s %s\n",
|
|
this,
|
|
pFilterNode,
|
|
ulRealNodeNumber,
|
|
ulSysaudioNodeNumber,
|
|
iVirtualSource,
|
|
DbgGuid2Sz(pguidType),
|
|
ulFlags & TN_FLAGS_DONT_FORWARD ? "DONT_FORWARD" : "");
|
|
|
|
if(ulDebugFlags & (DEBUG_FLAGS_VERBOSE | DEBUG_FLAGS_OBJECT)) {
|
|
dprintf(" ulFlags: %08x ", ulFlags);
|
|
if(ulFlags & TN_FLAGS_DONT_FORWARD) {
|
|
dprintf("DONT_FORWARD");
|
|
}
|
|
dprintf("\n lstLFN: ");
|
|
lstLogicalFilterNode.DumpAddress();
|
|
dprintf("\n");
|
|
}
|
|
lstTopologyPin.Dump();
|
|
return(STATUS_CONTINUE);
|
|
}
|
|
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------
|