414 lines
9.6 KiB
C
414 lines
9.6 KiB
C
|
|
|
|
//---------------------------------------------------------------------------
|
|
// 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)
|
|
|