Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

413 lines
9.6 KiB

//---------------------------------------------------------------------------
// Bda Topology Implementation Internal Structures
//
// Minidriver code should not attempt to access these structures
// directly.
//
//---------------------------------------------------------------------------
#define FILTERNAME "BdaTopology"
#define DYNAMIC_TOPOLOGY TRUE
#if defined(__cplusplus)
extern "C" {
#endif // defined(__cplusplus)
//===========================================================================
//
// MACRO definitions
//
//===========================================================================
#define BDA_PIN_STORAGE_INCREMENT 5
//===========================================================================
//
// Advance declarations
//
//===========================================================================
typedef struct _BDA_PIN_FACTORY_CONTEXT BDA_PIN_FACTORY_CONTEXT,
*PBDA_PIN_FACTORY_CONTEXT;
//===========================================================================
//
// BDA Object Context Structures
//
//===========================================================================
typedef struct _BDA_CONTEXT_ENTRY
{
PVOID pvReference;
PVOID pvContext;
ULONG ulcbContext;
} BDA_CONTEXT_ENTRY, * PBDA_CONTEXT_ENTRY;
typedef struct _BDA_CONTEXT_LIST
{
ULONG ulcListEntries;
ULONG ulcMaxListEntries;
ULONG ulcListEntriesPerBlock;
PBDA_CONTEXT_ENTRY pListEntries;
KSPIN_LOCK lock;
BOOLEAN fInitialized;
} BDA_CONTEXT_LIST, * PBDA_CONTEXT_LIST;
typedef struct _BDA_TEMPLATE_PATH
{
LIST_ENTRY leLinkage;
ULONG ulInputPinType;
ULONG ulOutputPinType;
ULONG uliJoint;
ULONG ulcControlNodesInPath;
PULONG argulControlNodesInPath;
} BDA_TEMPLATE_PATH, * PBDA_TEMPLATE_PATH;
__inline NTSTATUS
NewBdaTemplatePath(
PBDA_TEMPLATE_PATH * ppTemplatePath
)
{
NTSTATUS status = STATUS_SUCCESS;
if (!ppTemplatePath)
{
status = STATUS_INVALID_PARAMETER;
goto errExit;
}
*ppTemplatePath = (PBDA_TEMPLATE_PATH) ExAllocatePool(
NonPagedPool,
sizeof( BDA_TEMPLATE_PATH)
);
if (!*ppTemplatePath)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto errExit;
}
RtlZeroMemory( *ppTemplatePath, sizeof( BDA_TEMPLATE_PATH));
InitializeListHead( &(*ppTemplatePath)->leLinkage);
errExit:
return status;
}
__inline NTSTATUS
DeleteBdaTemplatePath(
PBDA_TEMPLATE_PATH pTemplatePath
)
{
NTSTATUS status = STATUS_SUCCESS;
if (!pTemplatePath)
{
status = STATUS_INVALID_PARAMETER;
goto errExit;
}
if (pTemplatePath->argulControlNodesInPath)
{
ExFreePool( pTemplatePath->argulControlNodesInPath);
pTemplatePath->argulControlNodesInPath = NULL;
}
RtlZeroMemory( pTemplatePath, sizeof( BDA_TEMPLATE_PATH));
ExFreePool( pTemplatePath);
errExit:
return status;
}
typedef struct _BDA_DEVICE_CONTEXT
{
ULONG ulStartEmpty;
//$BUG Add global statistics
} BDA_DEVICE_CONTEXT, *PBDA_DEVICE_CONTEXT;
typedef struct _BDA_PATH_STACK_ENTRY
{
ULONG ulHop;
ULONG uliConnection;
BOOLEAN fJoint;
} BDA_PATH_STACK_ENTRY, *PBDA_PATH_STACK_ENTRY;
typedef struct _BDA_NODE_CONTROL_INFO
{
ULONG ulNodeType;
ULONG ulControllingPinType;
} BDA_NODE_CONTROL_INFO, * PBDA_NODE_CONTROL_INFO;
typedef struct _BDA_PATH_INFO
{
ULONG ulInputPin;
ULONG ulOutputPin;
ULONG ulcPathEntries;
BDA_PATH_STACK_ENTRY rgPathEntries[MIN_DIMENSION];
} BDA_PATH_INFO, * PBDA_PATH_INFO;
typedef struct _BDA_FILTER_FACTORY_CONTEXT
{
const BDA_FILTER_TEMPLATE * pBdaFilterTemplate;
const KSFILTER_DESCRIPTOR * pInitialFilterDescriptor;
PKSFILTERFACTORY pKSFilterFactory;
} BDA_FILTER_FACTORY_CONTEXT, *PBDA_FILTER_FACTORY_CONTEXT;
typedef struct _BDA_FILTER_CONTEXT
{
PKSFILTER pKSFilter;
const BDA_FILTER_TEMPLATE * pBdaFilterTemplate;
// Pins are added as they are created.
// Note! If the filter has m pin factories included in the
// initial filter descriptor then the first m entries in this array
// will contain null pointers.
//
ULONG ulcPinFactories;
ULONG ulcPinFactoriesMax;
PBDA_PIN_FACTORY_CONTEXT argPinFactoryCtx;
// One node path will exist for each pin pairing.
//
//$REVIEW - Should we allow more than one path per pin pair?
//
ULONG ulcPathInfo;
PBDA_PATH_INFO * argpPathInfo;
} BDA_FILTER_CONTEXT, *PBDA_FILTER_CONTEXT;
typedef struct _BDA_PIN_FACTORY_CONTEXT
{
ULONG ulPinType;
ULONG ulPinFactoryId;
} BDA_PIN_FACTORY_CONTEXT, *PBDA_PIN_FACTORY_CONTEXT;
typedef struct _BDA_NODE_CONTEXT
{
ULONG ulStartEmpty;
} BDA_NODE_CONTEXT, *PBDA_NODE_CONTEXT;
//---------------------------------------------------------------------------
// BDA Topology Implementation Internal Functions
//
// Minidriver code should not call these routines directly.
//
//---------------------------------------------------------------------------
/*
** BdaFindPinPair()
**
** Returns a pointer to the BDA_PIN_PAIRING that corresponds
** to the given input and output pins.
**
** Arguments:
**
** pTopology Pointer to the BDA topology that contains the
** pin pairing.
**
** InputPinId Id of the input Pin to match
**
** OutputPinId Id of the output Pin to match
**
** Returns:
**
** pPinPairing Pointer to a valid BDA Pin Pairing structure
**
** NULL If no valid pin pairing exists with the
** given input and output pins.
**
** Side Effects: none
*/
PBDA_PIN_PAIRING
BdaFindPinPair(
PBDA_FILTER_TEMPLATE pFilterTemplate,
ULONG InputPinId,
ULONG OutputPinId
);
/*
** BdaGetPinFactoryContext()
**
** Finds a BDA PinFactory Context that corresponds
** to the given KS Pin Instance.
**
** Arguments:
**
**
** Returns:
**
**
**
** Side Effects: none
*/
STDMETHODIMP_(NTSTATUS)
BdaGetPinFactoryContext(
PKSPIN pKSPin,
PBDA_PIN_FACTORY_CONTEXT pPinFactoryCtx
);
/*
** BdaInitFilterFactoryContext()
**
** Initializes a BDA Filter Factory Context based on the filter's
** template descriptor.
**
**
** Arguments:
**
**
** pFilterFactoryCtx
**
** Returns:
**
** NULL If no valid pin pairing exists with the
** given input and output pins.
**
** Side Effects: none
*/
STDMETHODIMP_(NTSTATUS)
BdaInitFilterFactoryContext(
PBDA_FILTER_FACTORY_CONTEXT pFilterFactoryCtx
);
/*
** BdaAddNodeAutomationToPin()
**
** Merges the automation tables for each node type that is controlled
** by the pin type being created into the automation table for the
** the pin factory. This is how the automation tables for BDA
** control nodes get linked to the controlling pin. Otherwise the
** nodes would not be accesable.
**
**
** Arguments:
**
**
** pFilterCtx The BDA filter context to which the pin factory
** belongs. Must have this to get at the template
** topology.
**
** ulPinType BDA Pin Type of the pin being created. Need this
** to figure out which nodes are controlled by the
** pin.
**
** Returns:
**
**
** Side Effects: none
*/
STDMETHODIMP_(NTSTATUS)
BdaAddNodeAutomationToPin(
PBDA_FILTER_CONTEXT pFilterCtx,
ULONG ulControllingPinType,
KSOBJECT_BAG ObjectBag,
const KSAUTOMATION_TABLE * pOriginalAutomationTable,
PKSAUTOMATION_TABLE * ppNewAutomationTable
);
/*
** BdaCreateTemplatePaths()
**
** Creates a list of all possible paths through the template filter.
** Determines the controlling pin type for each node type in the
** template filter.
**
**
** Arguments:
**
**
** pFilterFactoryCtx
**
** Returns:
**
** NULL If no valid pin pairing exists with the
** given input and output pins.
**
** Side Effects: none
*/
STDMETHODIMP_(NTSTATUS)
BdaCreateTemplatePaths(
const BDA_FILTER_TEMPLATE * pBdaFilterTemplate,
PULONG pulcPathInfo,
PBDA_PATH_INFO ** pargpPathInfo
);
ULONG __inline
OutputBufferLenFromIrp(
PIRP pIrp
)
{
PIO_STACK_LOCATION pIrpStack;
ASSERT( pIrp);
if (!pIrp)
{
return 0;
}
pIrpStack = IoGetCurrentIrpStackLocation( pIrp);
ASSERT( pIrpStack);
if (pIrpStack)
{
return pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
}
else
{
return 0;
}
}
//---------------------------------------------------------------------------
// BDA Topology Const Data
//
// Minidriver code should not use these fields directly
//
//---------------------------------------------------------------------------
extern const KSAUTOMATION_TABLE BdaDefaultPinAutomation;
extern const KSAUTOMATION_TABLE BdaDefaultFilterAutomation;
#if defined(__cplusplus)
}
#endif // defined(__cplusplus)