|
|
//---------------------------------------------------------------------------
//
// Module: pi.cpp
//
// 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"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
DATARANGES DataRangesNull = { { sizeof(KSMULTIPLE_ITEM) + sizeof(KSDATARANGE), 1 }, { sizeof(KSDATARANGE), 0, STATICGUIDOF(GUID_NULL), STATICGUIDOF(GUID_NULL), STATICGUIDOF(GUID_NULL), } };
IDENTIFIERS IdentifiersNull = { { sizeof(KSMULTIPLE_ITEM) + sizeof(KSIDENTIFIER), 1 }, { STATICGUIDOF(GUID_NULL), 0, 0 } };
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
CPinInfo::CPinInfo( PFILTER_NODE pFilterNode, ULONG PinId ) { Assert(pFilterNode); this->pFilterNode = pFilterNode; this->PinId = PinId; AddList(&pFilterNode->lstPinInfo); }
CPinInfo::~CPinInfo() { Assert(this);
// Free physical connection data
delete pPhysicalConnection; delete pwstrName;
}
ENUMFUNC CPinInfo::CreatePhysicalConnection( ) { NTSTATUS Status;
Assert(this); if(pPhysicalConnection != NULL) { PFILTER_NODE pFilterNodeConnect; PPIN_INFO pPinInfoConnect;
ASSERT(pPhysicalConnection->Size != 0); Status = AddFilter( pPhysicalConnection->SymbolicLinkName, &pFilterNodeConnect);
if(!NT_SUCCESS(Status)) { DPF1(10, "CreatePhysicalConnection: AddFilter FAILED: %08x", Status); goto exit; } Assert(pFilterNodeConnect);
FOR_EACH_LIST_ITEM(&pFilterNodeConnect->lstPinInfo, pPinInfoConnect) {
if(pPhysicalConnection->Pin == pPinInfoConnect->PinId) {
DPF2(50, "CreatePhysicalConnection: From %d %s", PinId, pFilterNode->DumpName());
DPF2(50, "CreatePhysicalConnection: To %d %s", pPinInfoConnect->PinId, pPinInfoConnect->pFilterNode->DumpName());
if(DataFlow == KSPIN_DATAFLOW_OUT && pPinInfoConnect->DataFlow == KSPIN_DATAFLOW_IN) { PTOPOLOGY_CONNECTION pTopologyConnection;
Status = CreatePinInfoConnection( &pTopologyConnection, pFilterNode, NULL, this, pPinInfoConnect);
if(!NT_SUCCESS(Status)) { Trap(); goto exit; } } else { DPF(50, "CreatePhysicalConnection: rejected"); } break; }
} END_EACH_LIST_ITEM
delete pPhysicalConnection; pPhysicalConnection = NULL; } Status = STATUS_CONTINUE; exit: return(Status); }
NTSTATUS CPinInfo::GetPinInstances( PFILE_OBJECT pFileObject, PKSPIN_CINSTANCES pcInstances ) { NTSTATUS Status;
Status = GetPinProperty( pFileObject, KSPROPERTY_PIN_CINSTANCES, PinId, sizeof(KSPIN_CINSTANCES), (PVOID) pcInstances);
return Status; } // GetPinInstances
NTSTATUS CPinInfo::Create( PFILE_OBJECT pFileObject ) { NTSTATUS Status = STATUS_SUCCESS; PDATARANGES pDataRanges; PIDENTIFIERS pInterfaces; PIDENTIFIERS pMediums;
Assert(this); Assert(pFilterNode);
Status = GetPinInstances(pFileObject, &cPinInstances); if(!NT_SUCCESS(Status)) { Trap(); goto exit; }
Status = GetPinProperty( pFileObject, KSPROPERTY_PIN_DATAFLOW, PinId, sizeof(KSPIN_DATAFLOW), (PVOID)&DataFlow);
if(!NT_SUCCESS(Status)) { Trap(); goto exit; }
Status = GetPinProperty( pFileObject, KSPROPERTY_PIN_COMMUNICATION, PinId, sizeof(KSPIN_COMMUNICATION), (PVOID)&Communication);
if(!NT_SUCCESS(Status)) { Trap(); goto exit; } pguidCategory = new GUID; if(pguidCategory == NULL) { Trap(); Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; } Status = GetPinProperty( pFileObject, KSPROPERTY_PIN_CATEGORY, PinId, sizeof(GUID), (PVOID)pguidCategory);
if(NT_SUCCESS(Status)) { Status = pFilterNode->lstFreeMem.AddList(pguidCategory); if(!NT_SUCCESS(Status)) { Trap(); delete pguidCategory; pguidCategory = NULL; goto exit; } } else { delete pguidCategory; pguidCategory = NULL; if(Status != STATUS_NOT_FOUND) { Trap(); goto exit; } }
Status = GetPinPropertyEx( pFileObject, KSPROPERTY_PIN_NAME, PinId, (PVOID*)&pwstrName);
if(!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) { Trap(); goto exit; }
Status = GetPinPropertyEx( pFileObject, KSPROPERTY_PIN_PHYSICALCONNECTION, PinId, (PVOID*)&pPhysicalConnection);
if(!NT_SUCCESS(Status)) { Trap(); goto exit; }
Status = GetPinPropertyEx( pFileObject, KSPROPERTY_PIN_INTERFACES, PinId, (PVOID*)&pInterfaces);
if(!NT_SUCCESS(Status)) { Trap(); goto exit; }
if(pInterfaces == NULL || pInterfaces->MultipleItem.Count == 0) { delete pInterfaces; pInterfaces = &IdentifiersNull; } else { Status = pFilterNode->lstFreeMem.AddList(pInterfaces); if(!NT_SUCCESS(Status)) { Trap(); delete pInterfaces; goto exit; } }
Status = GetPinPropertyEx( pFileObject, KSPROPERTY_PIN_MEDIUMS, PinId, (PVOID*)&pMediums);
if(!NT_SUCCESS(Status)) { Trap(); goto exit; }
if(pMediums == NULL || pMediums->MultipleItem.Count == 0) { delete pMediums; pMediums = &IdentifiersNull; } else { Status = pFilterNode->lstFreeMem.AddList(pMediums); if(!NT_SUCCESS(Status)) { Trap(); delete pMediums; goto exit; } }
Status = GetPinPropertyEx( pFileObject, KSPROPERTY_PIN_DATARANGES, PinId, (PVOID*)&pDataRanges);
if(!NT_SUCCESS(Status)) { Trap(); goto exit; }
if(pDataRanges == NULL || pDataRanges->MultipleItem.Count == 0) { Trap(); delete pDataRanges; pDataRanges = &DataRangesNull; } else { Status = pFilterNode->lstFreeMem.AddList(pDataRanges); if(!NT_SUCCESS(Status)) { Trap(); delete pDataRanges; goto exit; } }
Status = CPinNode::CreateAll( this, pDataRanges, pInterfaces, pMediums);
if(!NT_SUCCESS(Status)) { Trap(); goto exit; }
// ISSUE-2001/05/15-alpers
// This is a temporary low risk solution to reverse DataRange problem.
// This needs to be implemented properly in the future.
//
if (pFilterNode->GetType() & FILTER_TYPE_AEC) { DPF(10, "AEC Filter Pin : Reversing Data Ranges"); lstPinNode.ReverseList(); }
if (pFilterNode->GetType() & FILTER_TYPE_GFX) { DPF(10, "GFX Filter Pin : Reversing Data Ranges"); lstPinNode.ReverseList(); }
exit: return(Status); }
|