windows-nt/Source/XPSP1/NT/drivers/wdm/audio/sysaudio/tn.cpp
2020-09-26 16:20:57 +08:00

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
//---------------------------------------------------------------------------