|
|
//---------------------------------------------------------------------------
//
// Module: topology.c
//
// Description:
//
//
//@@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"
//---------------------------------------------------------------------------
ENUMFUNC EnumerateTopology( IN PPIN_INFO pPinInfo, IN NTSTATUS (*Function)( IN PTOPOLOGY_CONNECTION pTopologyConnection, IN BOOL fToDirection, IN OUT PVOID pReference ), IN OUT PVOID pReference ) { ENUM_TOPOLOGY EnumTopology; NTSTATUS Status;
Assert(pPinInfo); EnumTopology.cTopologyRecursion = 0; EnumTopology.Function = Function; EnumTopology.fToDirection = (pPinInfo->DataFlow == KSPIN_DATAFLOW_IN); EnumTopology.pReference = pReference; Status = EnumeratePinInfoTopology(pPinInfo, &EnumTopology); return(Status); }
ENUMFUNC EnumerateGraphTopology( IN PSTART_INFO pStartInfo, IN NTSTATUS (*Function)( IN PTOPOLOGY_CONNECTION pTopologyConnection, IN BOOL fToDirection, IN OUT PVOID pReference ), IN OUT PVOID pReference ) { PCONNECT_INFO pConnectInfo; NTSTATUS Status;
Assert(pStartInfo); Assert(pStartInfo->GetPinInfo());
Status = EnumerateTopology( pStartInfo->GetPinInfo(), Function, pReference);
if(Status != STATUS_CONTINUE) { goto exit; } for(pConnectInfo = pStartInfo->GetFirstConnectInfo(); pConnectInfo != NULL; pConnectInfo = pConnectInfo->GetNextConnectInfo()) {
Assert(pConnectInfo); Status = EnumerateTopology( pConnectInfo->pPinInfoSink, Function, pReference);
if(Status != STATUS_CONTINUE) { goto exit; } } exit: return(Status); }
ENUMFUNC EnumeratePinInfoTopology( IN PPIN_INFO pPinInfo, IN PENUM_TOPOLOGY pEnumTopology ) { PTOPOLOGY_CONNECTION pTopologyConnection; NTSTATUS Status = STATUS_CONTINUE;
Assert(pPinInfo); Assert(pEnumTopology); DPF2(110, "EnumerateTopologyPinInfo %08x #%x", pPinInfo, pPinInfo->PinId);
FOR_EACH_LIST_ITEM( &pPinInfo->lstTopologyConnection, pTopologyConnection) {
Assert(pTopologyConnection); if(pEnumTopology->fToDirection) { if(pTopologyConnection->pPinInfoFrom != pPinInfo) { continue; } ASSERT(pTopologyConnection->pPinInfoTo != pPinInfo); } else { if(pTopologyConnection->pPinInfoTo != pPinInfo) { continue; } ASSERT(pTopologyConnection->pPinInfoFrom != pPinInfo); } Status = EnumerateTopologyConnection( pTopologyConnection, pEnumTopology);
if(Status != STATUS_CONTINUE) { goto exit; }
} END_EACH_LIST_ITEM exit: return(Status); }
ENUMFUNC EnumerateTopologyPin( IN PTOPOLOGY_PIN pTopologyPin, IN PENUM_TOPOLOGY pEnumTopology ) { PTOPOLOGY_CONNECTION pTopologyConnection; PTOPOLOGY_PIN pTopologyPin2; NTSTATUS Status = STATUS_CONTINUE; BOOL fFromPinEqual = TRUE; ULONG ulFromPinNumber = MAXULONG; BOOL fToPinEqual = TRUE; ULONG ulToPinNumber = MAXULONG; BOOL fPinEqual; ULONG ulPinNumber;
Assert(pTopologyPin); Assert(pEnumTopology); DPF3(110, "EnumerateTopologyPin %08x TP #%x TN #%x", pTopologyPin, pTopologyPin->ulPinNumber, pTopologyPin->pTopologyNode->ulRealNodeNumber);
if(IsEqualGUID( &KSNODETYPE_ACOUSTIC_ECHO_CANCEL, pTopologyPin->pTopologyNode->pguidType)) { switch(pTopologyPin->ulPinNumber) { case KSNODEPIN_AEC_RENDER_OUT: ASSERT(!pEnumTopology->fToDirection); case KSNODEPIN_AEC_RENDER_IN: ulFromPinNumber = KSNODEPIN_AEC_RENDER_IN; ulToPinNumber = KSNODEPIN_AEC_RENDER_OUT; break;
case KSNODEPIN_AEC_CAPTURE_OUT: ASSERT(!pEnumTopology->fToDirection); case KSNODEPIN_AEC_CAPTURE_IN: ulFromPinNumber = KSNODEPIN_AEC_CAPTURE_IN; ulToPinNumber = KSNODEPIN_AEC_CAPTURE_OUT; break; } } else if(IsEqualGUID( &KSNODETYPE_SUM, pTopologyPin->pTopologyNode->pguidType) ||
IsEqualGUID( &KSNODETYPE_MUX, pTopologyPin->pTopologyNode->pguidType)) {
ulFromPinNumber = KSNODEPIN_SUM_MUX_IN; fFromPinEqual = FALSE; ulToPinNumber = KSNODEPIN_SUM_MUX_OUT; } else if(IsEqualGUID( &KSNODETYPE_DEMUX, pTopologyPin->pTopologyNode->pguidType)) {
ulFromPinNumber = KSNODEPIN_DEMUX_IN; ulToPinNumber = KSNODEPIN_DEMUX_OUT; fToPinEqual = FALSE; } else { ulFromPinNumber = KSNODEPIN_STANDARD_IN; ulToPinNumber = KSNODEPIN_STANDARD_OUT; }
// Swap pin numbers and flags
if(!pEnumTopology->fToDirection) { ulPinNumber = ulToPinNumber; ulToPinNumber = ulFromPinNumber; ulFromPinNumber = ulPinNumber; fPinEqual = fToPinEqual; fToPinEqual = fFromPinEqual; fFromPinEqual = fPinEqual; } ASSERT(ulToPinNumber != MAXULONG); ASSERT(ulFromPinNumber != MAXULONG);
// Validate input/from pin(s)
if(fFromPinEqual) { if(pTopologyPin->ulPinNumber != ulFromPinNumber) { DPF2(5, "EnumerateTopologyPin: %s bad 'from' pin number %08x", pTopologyPin->pTopologyNode->pFilterNode->DumpName(), pTopologyPin->ulPinNumber); Status = STATUS_INVALID_DEVICE_REQUEST; goto exit; } } else { if(pTopologyPin->ulPinNumber < ulFromPinNumber) { DPF2(5, "EnumerateTopologyPin: %s bad 'from' pin number %08x", pTopologyPin->pTopologyNode->pFilterNode->DumpName(), pTopologyPin->ulPinNumber); Status = STATUS_INVALID_DEVICE_REQUEST; goto exit; } }
FOR_EACH_LIST_ITEM( &pTopologyPin->pTopologyNode->lstTopologyPin, pTopologyPin2) {
if(pTopologyPin == pTopologyPin2) { continue; }
// Pick the right output/to pin(s)
if(fToPinEqual) { if(pTopologyPin2->ulPinNumber != ulToPinNumber) { continue; } } else { if(pTopologyPin2->ulPinNumber < ulToPinNumber) { continue; } }
FOR_EACH_LIST_ITEM( &pTopologyPin2->lstTopologyConnection, pTopologyConnection) {
Assert(pTopologyConnection); if(pEnumTopology->fToDirection) { if(pTopologyConnection->pTopologyPinFrom != pTopologyPin2) { continue; } ASSERT(pTopologyConnection->pTopologyPinTo != pTopologyPin2); } else { if(pTopologyConnection->pTopologyPinTo != pTopologyPin2) { continue; } ASSERT(pTopologyConnection->pTopologyPinFrom != pTopologyPin2); } Status = EnumerateTopologyConnection( pTopologyConnection, pEnumTopology);
if(Status != STATUS_CONTINUE) { goto exit; }
} END_EACH_LIST_ITEM
} END_EACH_LIST_ITEM exit: return(Status); }
ENUMFUNC EnumerateTopologyConnection( IN PTOPOLOGY_CONNECTION pTopologyConnection, IN PENUM_TOPOLOGY pEnumTopology ) { PTOPOLOGY_PIN pTopologyPin; PPIN_INFO pPinInfo; NTSTATUS Status;
Assert(pEnumTopology); Assert(pTopologyConnection); DPF1(110, "EnumerateTopologyConnection %08x", pTopologyConnection);
if(pEnumTopology->cTopologyRecursion++ > (gcTopologyConnections + 16)) { Trap(); DPF(5, "EnumerateTopologyConnection: recursion too deep"); Status = STATUS_STACK_OVERFLOW; goto exit; } // Have we visited this topology connection already?
Status = VisitedTopologyConnection(pTopologyConnection, pEnumTopology); if(Status != STATUS_CONTINUE) { if(Status == STATUS_DEAD_END) { Status = STATUS_CONTINUE; } goto exit; } Status = (*pEnumTopology->Function)( pTopologyConnection, pEnumTopology->fToDirection, pEnumTopology->pReference);
if(Status != STATUS_CONTINUE) { if(Status == STATUS_DEAD_END) { Status = STATUS_CONTINUE; } goto exit; } if(pEnumTopology->fToDirection) { pTopologyPin = pTopologyConnection->pTopologyPinTo; pPinInfo = pTopologyConnection->pPinInfoTo; } else { pTopologyPin = pTopologyConnection->pTopologyPinFrom; pPinInfo = pTopologyConnection->pPinInfoFrom; } if(pTopologyPin != NULL) {
Status = EnumerateTopologyPin(pTopologyPin, pEnumTopology); if(Status != STATUS_CONTINUE) { goto exit; } } if(pPinInfo != NULL) {
Status = EnumeratePinInfoTopology(pPinInfo, pEnumTopology); if(Status != STATUS_CONTINUE) { goto exit; } } exit: pEnumTopology->cTopologyRecursion--; return(Status); }
ENUMFUNC VisitedTopologyConnection( IN PTOPOLOGY_CONNECTION pTopologyConnection, IN PENUM_TOPOLOGY pEnumTopology ) { NTSTATUS Status;
Assert(pEnumTopology); Assert(pTopologyConnection);
// Have we visited this topology connection already?
if(pTopologyConnection->CheckDupList( &pEnumTopology->lstTopologyConnection)) { DPF1(100, "VisitedTopologyConnection: %08x already visited", pTopologyConnection); Status = STATUS_DEAD_END; goto exit; // yes, break cycle in topology
} // Add topology pin to list of pin's visited
Status = pTopologyConnection->AddList( &pEnumTopology->lstTopologyConnection); if(!NT_SUCCESS(Status)) { goto exit; } Status = STATUS_CONTINUE; exit: return(Status); }
//---------------------------------------------------------------------------
|