reactos/drivers/multimedia/bdasup/bdasup.c

1050 lines
25 KiB
C
Raw Normal View History

#include "precomp.h"
#define TAG_BDASUP 'SadB'
const GUID KSPROPSETID_BdaPinControl = {0xded49d5, 0xa8b7, 0x4d5d, {0x97, 0xa1, 0x12, 0xb0, 0xc1, 0x95, 0x87, 0x4d}};
const GUID KSMETHODSETID_BdaDeviceConfiguration = {0x71985f45, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
const GUID KSPROPSETID_BdaTopology = {0xa14ee835, 0x0a23, 0x11d3, {0x9c, 0xc7, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
BDA_GLOBAL g_Settings =
{
0,
0,
{NULL, NULL}
};
KSPROPERTY_ITEM FilterPropertyItem[] =
{
DEFINE_KSPROPERTY_ITEM_BDA_NODE_TYPES(BdaPropertyNodeTypes, NULL),
DEFINE_KSPROPERTY_ITEM_BDA_PIN_TYPES( BdaPropertyPinTypes, NULL),
DEFINE_KSPROPERTY_ITEM_BDA_TEMPLATE_CONNECTIONS(BdaPropertyTemplateConnections, NULL),
DEFINE_KSPROPERTY_ITEM_BDA_NODE_METHODS(BdaPropertyNodeMethods, NULL),
DEFINE_KSPROPERTY_ITEM_BDA_NODE_PROPERTIES(BdaPropertyNodeProperties, NULL),
DEFINE_KSPROPERTY_ITEM_BDA_NODE_EVENTS(BdaPropertyNodeEvents, NULL),
DEFINE_KSPROPERTY_ITEM_BDA_CONTROLLING_PIN_ID(BdaPropertyGetControllingPinId, NULL),
DEFINE_KSPROPERTY_ITEM_BDA_NODE_DESCRIPTORS(BdaPropertyNodeDescriptors, NULL)
};
KSPROPERTY_SET FilterPropertySet =
{
&KSPROPSETID_BdaTopology,
8,
FilterPropertyItem,
0,
NULL
};
KSMETHOD_ITEM FilterMethodItem[] =
{
//DEFINE_KSMETHOD_ITEM_BDA_CREATE_PIN_FACTORY(BdaMethodCreatePin, NULL),
DEFINE_KSMETHOD_ITEM_BDA_CREATE_TOPOLOGY(BdaMethodCreateTopology, NULL)
};
KSMETHOD_SET FilterMethodSet =
{
&KSMETHODSETID_BdaDeviceConfiguration,
2,
FilterMethodItem,
0,
NULL
};
KSAUTOMATION_TABLE FilterAutomationTable =
{
1,
sizeof(KSPROPERTY_ITEM),
&FilterPropertySet,
1,
sizeof(KSMETHOD_ITEM),
&FilterMethodSet,
0,
sizeof(KSEVENT_ITEM),
NULL
};
KSPROPERTY_ITEM PinPropertyItem[] =
{
DEFINE_KSPROPERTY_ITEM_BDA_PIN_ID(BdaPropertyGetPinControl, NULL),
DEFINE_KSPROPERTY_ITEM_BDA_PIN_TYPE(BdaPropertyGetPinControl, NULL)
};
KSPROPERTY_SET PinPropertySet =
{
&KSPROPSETID_BdaPinControl,
2,
PinPropertyItem,
0,
NULL
};
KSAUTOMATION_TABLE PinAutomationTable =
{
1,
sizeof(KSPROPERTY_ITEM),
&PinPropertySet,
0,
sizeof(KSMETHOD_ITEM),
NULL,
0,
sizeof(KSEVENT_ITEM),
NULL
};
PVOID
AllocateItem(
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes)
{
return ExAllocatePoolZero(PoolType, NumberOfBytes, TAG_BDASUP);
}
VOID
FreeItem(
IN PVOID Item)
{
ExFreePoolWithTag(Item, TAG_BDASUP);
}
PBDA_FILTER_INSTANCE_ENTRY
GetFilterInstanceEntry(
IN PKSFILTERFACTORY FilterFactory)
{
PBDA_FILTER_INSTANCE_ENTRY InstanceEntry = NULL;
PLIST_ENTRY Entry;
KIRQL OldLevel;
/* acquire list lock */
KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
/* point to first entry */
Entry = g_Settings.FilterFactoryInstanceList.Flink;
while(Entry != &g_Settings.FilterFactoryInstanceList)
{
/* get instance entry from list entry offset */
InstanceEntry = (PBDA_FILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BDA_FILTER_INSTANCE_ENTRY, Entry);
/* is the instance entry the requested one */
if (InstanceEntry->FilterFactoryInstance == FilterFactory)
break;
/* move to next entry */
Entry = Entry->Flink;
/* set to null as it has not been found */
InstanceEntry = NULL;
}
/* release spin lock */
KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
/* return result */
return InstanceEntry;
}
/*
@implemented
*/
NTSTATUS
NTAPI
DllInitialize(
PUNICODE_STRING RegistryPath)
{
DPRINT("BDASUP::DllInitialize\n");
KeInitializeSpinLock(&g_Settings.FilterFactoryInstanceListLock);
InitializeListHead(&g_Settings.FilterFactoryInstanceList);
g_Settings.Initialized = TRUE;
return STATUS_SUCCESS;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaCheckChanges(IN PIRP Irp)
{
DPRINT("BdaCheckChanges\n");
if (!Irp)
return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaCommitChanges(IN PIRP Irp)
{
DPRINT("BdaCommitChanges\n");
if (!Irp)
return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaCreateFilterFactory(
IN PKSDEVICE pKSDevice,
IN const KSFILTER_DESCRIPTOR *pFilterDescriptor,
IN const BDA_FILTER_TEMPLATE *pBdaFilterTemplate)
{
return BdaCreateFilterFactoryEx(pKSDevice, pFilterDescriptor, pBdaFilterTemplate, NULL);
}
VOID
NTAPI
FreeFilterInstance(
IN PVOID Context)
{
PBDA_FILTER_INSTANCE_ENTRY InstanceEntry = NULL;
PLIST_ENTRY Entry;
KIRQL OldLevel;
/* acquire list lock */
KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
/* point to first entry */
Entry = g_Settings.FilterFactoryInstanceList.Flink;
while(Entry != &g_Settings.FilterFactoryInstanceList)
{
/* get instance entry from list entry offset */
InstanceEntry = (PBDA_FILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BDA_FILTER_INSTANCE_ENTRY, Entry);
/* is the instance entry the requested one */
if (InstanceEntry == (PBDA_FILTER_INSTANCE_ENTRY)Context)
{
RemoveEntryList(&InstanceEntry->Entry);
FreeItem(InstanceEntry);
break;
}
/* move to next entry */
Entry = Entry->Flink;
}
/* release spin lock */
KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaCreateFilterFactoryEx(
IN PKSDEVICE pKSDevice,
IN const KSFILTER_DESCRIPTOR *pFilterDescriptor,
IN const BDA_FILTER_TEMPLATE *BdaFilterTemplate,
OUT PKSFILTERFACTORY *ppKSFilterFactory)
{
PKSFILTERFACTORY FilterFactory;
PBDA_FILTER_INSTANCE_ENTRY FilterInstance;
KIRQL OldLevel;
NTSTATUS Status;
PKSFILTER_DESCRIPTOR FilterDescriptor;
DPRINT("BdaCreateFilterFactoryEx\n");
FilterDescriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR));
if (!FilterDescriptor)
{
/* no memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* copy filter descriptor template */
RtlMoveMemory(FilterDescriptor, pFilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
/* erase pin / nodes / connections from filter descriptor */
FilterDescriptor->PinDescriptorsCount = 0;
FilterDescriptor->PinDescriptors = NULL;
FilterDescriptor->NodeDescriptorsCount = 0;
FilterDescriptor->NodeDescriptors = NULL;
FilterDescriptor->ConnectionsCount = 0;
FilterDescriptor->Connections = NULL;
/* merge the automation tables */
Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&FilterDescriptor->AutomationTable, (PKSAUTOMATION_TABLE)pFilterDescriptor->AutomationTable, &FilterAutomationTable, NULL);
/* check for success */
if (!NT_SUCCESS(Status))
{
DPRINT1("KsMergeAutomationTables failed with %lx\n", Status);
FreeItem(FilterDescriptor);
return Status;
}
/* allocate filter instance */
FilterInstance = AllocateItem(NonPagedPool, sizeof(BDA_FILTER_INSTANCE_ENTRY));
if (!FilterInstance)
{
/* not enough memory */
FreeItem(FilterDescriptor);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* create the filter factory */
Status = KsCreateFilterFactory(pKSDevice->FunctionalDeviceObject, FilterDescriptor, NULL, NULL, 0, NULL, NULL, &FilterFactory);
/* check for success */
if (NT_SUCCESS(Status))
{
if (FilterDescriptor->AutomationTable != &FilterAutomationTable)
{
/* add the item to filter object bag */
KsAddItemToObjectBag(FilterFactory->Bag, (PVOID)FilterDescriptor->AutomationTable, FreeFilterInstance);
}
else
{
/* make sure the automation table is not-read only */
Status = _KsEdit(FilterFactory->Bag, (PVOID*)&FilterDescriptor->AutomationTable, sizeof(KSAUTOMATION_TABLE), sizeof(KSAUTOMATION_TABLE), 0);
/* sanity check */
ASSERT(Status == STATUS_SUCCESS);
/* add to object bag */
KsAddItemToObjectBag(FilterFactory->Bag, (PVOID)FilterDescriptor->AutomationTable, FreeFilterInstance);
}
/* initialize filter instance entry */
FilterInstance->FilterFactoryInstance = FilterFactory;
FilterInstance->FilterTemplate = (BDA_FILTER_TEMPLATE *)BdaFilterTemplate;
/* acquire list lock */
KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
/* insert factory at the end */
InsertTailList(&g_Settings.FilterFactoryInstanceList, &FilterInstance->Entry);
/* release spin lock */
KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
if (ppKSFilterFactory)
{
/* store result */
*ppKSFilterFactory = FilterFactory;
}
}
else
{
/* failed to create filter factory */
FreeItem(FilterInstance);
FreeItem(FilterDescriptor);
}
/* done */
DPRINT("BdaCreateFilterFactoryEx Status %x\n", Status);
return Status;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaCreatePin(
IN PKSFILTER pKSFilter,
IN ULONG ulPinType,
OUT ULONG *pulPinId)
{
PKSPIN_DESCRIPTOR_EX PinDescriptor;
PKSFILTERFACTORY FilterFactory;
PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
NTSTATUS Status;
ULONG PinId;
PKSPIN_DESCRIPTOR_EX NewPinDescriptor;
DPRINT("BdaCreatePin\n");
if (!pulPinId || !pKSFilter)
return STATUS_INVALID_PARAMETER;
/* get parent filter factory */
FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
/* sanity check */
ASSERT(FilterFactory);
/* find instance entry */
InstanceEntry = GetFilterInstanceEntry(FilterFactory);
if (!InstanceEntry)
{
/* the filter was not initialized with BDA */
return STATUS_NOT_FOUND;
}
/* sanity checks */
ASSERT(InstanceEntry->FilterTemplate);
ASSERT(InstanceEntry->FilterTemplate->pFilterDescriptor);
/* does the filter support any pins */
if (!InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount)
{
/* no pins supported */
DPRINT("BdaCreatePin NoPins supported\n");
return STATUS_UNSUCCESSFUL;
}
/* is pin factory still existing */
if (InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount <= ulPinType)
{
/* pin request is out of bounds */
DPRINT("BdaCreatePin ulPinType %lu >= PinDescriptorCount %lu\n", ulPinType, InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount);
return STATUS_INVALID_PARAMETER;
}
/* FIXME custom pin descriptors */
ASSERT(InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
/* get pin descriptor */
PinDescriptor = (PKSPIN_DESCRIPTOR_EX)&InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptors[ulPinType];
/* allocate pin descriptor */
NewPinDescriptor = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR_EX));
if (!NewPinDescriptor)
{
/* no memory */
DPRINT("BdaCreatePin OutOfMemory\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
/* make a copy of the pin descriptor */
RtlMoveMemory(NewPinDescriptor, PinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
/* merge the automation tables */
Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&NewPinDescriptor->AutomationTable, (PKSAUTOMATION_TABLE)PinDescriptor->AutomationTable, &PinAutomationTable, pKSFilter->Bag);
/* check for success */
if (NT_SUCCESS(Status))
{
/* create the pin factory */
Status = KsFilterCreatePinFactory(pKSFilter, NewPinDescriptor, &PinId);
/* check for success */
if (NT_SUCCESS(Status))
{
/* store result */
*pulPinId = PinId;
}
}
DPRINT("BdaCreatePin Result %x PinId %u\n", Status, PinId);
return Status;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaMethodCreatePin(
IN PIRP Irp,
IN KSMETHOD *pKSMethod,
OUT ULONG *pulPinFactoryID)
{
PKSM_PIN Pin;
PKSFILTER Filter;
DPRINT("BdaMethodCreatePin\n");
if (!Irp)
{
/* invalid parameter */
return STATUS_INVALID_PARAMETER;
}
/* get filter from irp */
Filter = KsGetFilterFromIrp(Irp);
/* sanity check */
ASSERT(Filter);
ASSERT(pKSMethod);
/* get method request */
Pin = (PKSM_PIN)pKSMethod;
/* create the pin */
return BdaCreatePin(Filter, Pin->PinId, pulPinFactoryID);
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaInitFilter(
IN PKSFILTER pKSFilter,
IN const BDA_FILTER_TEMPLATE *pBdaFilterTemplate)
{
PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
PKSFILTERFACTORY FilterFactory;
ULONG Index, PinId;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("BdaInitFilter %p\n", pBdaFilterTemplate);
/* check input parameters */
if (!pKSFilter)
return STATUS_INVALID_PARAMETER;
/* get parent filter factory */
FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
/* sanity check */
ASSERT(FilterFactory);
/* find instance entry */
InstanceEntry = GetFilterInstanceEntry(FilterFactory);
/* sanity check */
ASSERT(InstanceEntry);
if (!pBdaFilterTemplate)
{
/* use template from BdaCreateFilterFactoryEx */
pBdaFilterTemplate = InstanceEntry->FilterTemplate;
}
/* now create the pins */
for(Index = 0; Index < pBdaFilterTemplate->pFilterDescriptor->PinDescriptorsCount; Index++)
{
/* create the pin */
Status = BdaCreatePin(pKSFilter, Index, &PinId);
/* check for success */
if (!NT_SUCCESS(Status))
break;
}
/* done */
return Status;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaCreateTopology(
IN PKSFILTER pKSFilter,
IN ULONG InputPinId,
IN ULONG OutputPinId)
{
PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
PKSFILTERFACTORY FilterFactory;
KSTOPOLOGY_CONNECTION Connection;
DPRINT("BdaCreateTopology\n");
/* check input parameters */
if (!pKSFilter)
return STATUS_INVALID_PARAMETER;
/* get parent filter factory */
FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
/* sanity check */
ASSERT(FilterFactory);
/* find instance entry */
InstanceEntry = GetFilterInstanceEntry(FilterFactory);
if (!InstanceEntry)
{
/* the filter was not initialized with BDA */
return STATUS_NOT_FOUND;
}
if (InputPinId >= InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount ||
OutputPinId >= InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount)
{
/* invalid pin id */
return STATUS_INVALID_PARAMETER;
}
/* initialize topology connection */
Connection.FromNode = KSFILTER_NODE;
Connection.ToNode = KSFILTER_NODE;
Connection.FromNodePin = InputPinId;
Connection.ToNodePin = OutputPinId;
/* add the connection */
return KsFilterAddTopologyConnections(pKSFilter, 1, &Connection);
}
/*
@unimplemented
*/
NTSTATUS
NTAPI
BdaDeletePin(
IN PKSFILTER pKSFilter,
IN ULONG *pulPinId)
{
UNIMPLEMENTED;
DPRINT("BdaDeletePin\n");
return STATUS_NOT_IMPLEMENTED;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaFilterFactoryUpdateCacheData(
IN PKSFILTERFACTORY FilterFactory,
IN const KSFILTER_DESCRIPTOR *FilterDescriptor OPTIONAL)
{
DPRINT("BdaFilterFactoryUpdateCacheData\n");
return KsFilterFactoryUpdateCacheData(FilterFactory, FilterDescriptor);
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaGetChangeState(
IN PIRP Irp,
OUT BDA_CHANGE_STATE *ChangeState)
{
DPRINT("BdaGetChangeState\n");
if (Irp && ChangeState)
{
*ChangeState = BDA_CHANGES_COMPLETE;
return STATUS_SUCCESS;
}
/* invalid parameters supplied */
return STATUS_INVALID_PARAMETER;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaMethodCreateTopology(
IN PIRP Irp,
IN KSMETHOD *pKSMethod,
OPTIONAL PVOID pvIgnored)
{
PKSFILTER Filter;
PKSP_BDA_NODE_PIN Node;
DPRINT("BdaMethodCreateTopology\n");
/* check input parameters */
if (!Irp || !pKSMethod)
return STATUS_INVALID_PARAMETER;
/* get filter */
Filter = KsGetFilterFromIrp(Irp);
/* sanity check */
ASSERT(Filter);
/* get method request */
Node = (PKSP_BDA_NODE_PIN)pKSMethod;
/* create the topology */
return BdaCreateTopology(Filter, Node->ulInputPinId, Node->ulOutputPinId);
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaMethodDeletePin(
IN PIRP Irp,
IN KSMETHOD *pKSMethod,
OPTIONAL PVOID pvIgnored)
{
DPRINT("BdaMethodDeletePin\n");
if (!Irp)
return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
}
/*
@unimplemented
*/
NTSTATUS
NTAPI
BdaPropertyGetControllingPinId(
IN PIRP Irp,
IN KSP_BDA_NODE_PIN *pProperty,
OUT ULONG *pulControllingPinId)
{
UNIMPLEMENTED;
DPRINT("BdaPropertyGetControllingPinId\n");
return STATUS_NOT_IMPLEMENTED;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaPropertyGetPinControl(
IN PIRP Irp,
IN KSPROPERTY *pKSProperty,
OUT ULONG *pulProperty)
{
PKSPIN Pin;
PKSFILTER Filter;
PKSFILTERFACTORY FilterFactory;
PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
DPRINT("BdaPropertyGetPinControl\n");
/* first get the pin */
Pin = KsGetPinFromIrp(Irp);
ASSERT(Pin);
/* now get the parent filter */
Filter = KsPinGetParentFilter(Pin);
ASSERT(Filter);
/* get parent filter factory */
FilterFactory = KsFilterGetParentFilterFactory(Filter);
ASSERT(FilterFactory);
/* find instance entry */
InstanceEntry = GetFilterInstanceEntry(FilterFactory);
ASSERT(InstanceEntry);
/* sanity check */
pKSProperty++;
ASSERT(pKSProperty->Id == KSPROPERTY_BDA_PIN_TYPE);
/* store pin id */
*pulProperty = Pin->Id;
return STATUS_SUCCESS;
}
/*
@unimplemented
*/
NTSTATUS
NTAPI
BdaPropertyNodeDescriptors(
IN PIRP Irp,
IN KSPROPERTY *pKSProperty,
OUT BDANODE_DESCRIPTOR *pNodeDescriptorProperty)
{
UNIMPLEMENTED;
DPRINT("BdaPropertyNodeDescriptors\n");
return STATUS_NOT_IMPLEMENTED;
}
/*
@unimplemented
*/
NTSTATUS
NTAPI
BdaPropertyNodeEvents(
IN PIRP Irp,
IN KSP_NODE *pKSProperty,
OUT GUID *pguidProperty)
{
UNIMPLEMENTED;
DPRINT("BdaPropertyNodeEvents\n");
return STATUS_NOT_IMPLEMENTED;
}
/*
@unimplemented
*/
NTSTATUS
NTAPI
BdaPropertyNodeMethods(
IN PIRP Irp,
IN KSP_NODE *pKSProperty,
OUT GUID *pguidProperty)
{
UNIMPLEMENTED;
DPRINT("BdaPropertyNodeMethods\n");
return STATUS_NOT_IMPLEMENTED;
}
/*
@unimplemented
*/
NTSTATUS
NTAPI
BdaPropertyNodeProperties(
IN PIRP Irp,
IN KSP_NODE *pKSProperty,
OUT GUID *pguidProperty)
{
UNIMPLEMENTED;
DPRINT("BdaPropertyNodeProperties\n");
return STATUS_NOT_IMPLEMENTED;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaPropertyNodeTypes(
IN PIRP Irp,
IN KSPROPERTY *pKSProperty,
OUT ULONG *pulProperty)
{
PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
PKSFILTERFACTORY FilterFactory;
PKSFILTER pKSFilter;
PIO_STACK_LOCATION IoStack;
ULONG Index;
DPRINT("BdaPropertyNodeTypes\n");
/* check input parameter */
if (!Irp || !pKSProperty)
return STATUS_INVALID_PARAMETER;
/* first get the filter */
pKSFilter = KsGetFilterFromIrp(Irp);
/* sanity check */
ASSERT(pKSFilter);
/* get parent filter factory */
FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
/* sanity check */
ASSERT(FilterFactory);
/* find instance entry */
InstanceEntry = GetFilterInstanceEntry(FilterFactory);
ASSERT(InstanceEntry);
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* are there node types provided */
if (!pulProperty)
{
/* no node entry array provided */
Irp->IoStatus.Information = InstanceEntry->FilterTemplate->pFilterDescriptor->NodeDescriptorsCount * sizeof(ULONG);
Irp->IoStatus.Status = STATUS_MORE_ENTRIES;
return STATUS_MORE_ENTRIES;
}
if (InstanceEntry->FilterTemplate->pFilterDescriptor->NodeDescriptorsCount * sizeof(ULONG) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
{
/* buffer too small */
Irp->IoStatus.Information = InstanceEntry->FilterTemplate->pFilterDescriptor->NodeDescriptorsCount * sizeof(ULONG);
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
/* now copy all descriptors */
for(Index = 0; Index < InstanceEntry->FilterTemplate->pFilterDescriptor->NodeDescriptorsCount; Index++)
{
/* use the index as the type */
pulProperty[Index] = Index;
}
return STATUS_SUCCESS;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaPropertyPinTypes(
IN PIRP Irp,
IN KSPROPERTY *pKSProperty,
OUT ULONG *pulProperty)
{
PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
PKSFILTERFACTORY FilterFactory;
PKSFILTER pKSFilter;
PIO_STACK_LOCATION IoStack;
ULONG Index;
DPRINT("BdaPropertyPinTypes\n");
/* check input parameter */
if (!Irp || !pKSProperty)
return STATUS_INVALID_PARAMETER;
/* first get the filter */
pKSFilter = KsGetFilterFromIrp(Irp);
/* sanity check */
ASSERT(pKSFilter);
/* get parent filter factory */
FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
/* sanity check */
ASSERT(FilterFactory);
/* find instance entry */
InstanceEntry = GetFilterInstanceEntry(FilterFactory);
ASSERT(InstanceEntry);
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* are there node types provided */
if (!pKSProperty)
{
/* no node entry array provided */
Irp->IoStatus.Information = InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount * sizeof(ULONG);
Irp->IoStatus.Status = STATUS_MORE_ENTRIES;
return STATUS_MORE_ENTRIES;
}
if (InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount * sizeof(ULONG) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
{
/* buffer too small */
Irp->IoStatus.Information = InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount * sizeof(ULONG);
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
/* now copy all descriptors */
for(Index = 0; Index < InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount; Index++)
{
/* use the index as the type */
pulProperty[Index] = Index;
}
return STATUS_SUCCESS;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaPropertyTemplateConnections(
IN PIRP Irp,
IN KSPROPERTY *pKSProperty,
OUT KSTOPOLOGY_CONNECTION *pConnectionProperty)
{
PBDA_FILTER_INSTANCE_ENTRY FilterInstance;
PKSFILTER Filter;
PIO_STACK_LOCATION IoStack;
ULONG Index;
DPRINT("BdaPropertyTemplateConnections\n");
/* validate parameters */
if (!Irp || !pKSProperty)
return STATUS_INVALID_PARAMETER;
/* first get the filter */
Filter = KsGetFilterFromIrp(Irp);
/* sanity check */
ASSERT(Filter);
/* verify filter has been registered with BDA */
FilterInstance = GetFilterInstanceEntry(KsFilterGetParentFilterFactory(Filter));
if (!FilterInstance)
return STATUS_INVALID_PARAMETER;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (!pConnectionProperty)
{
/* caller needs the size first */
Irp->IoStatus.Information = FilterInstance->FilterTemplate->pFilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION);
Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
return STATUS_BUFFER_OVERFLOW;
}
/* sanity check */
ASSERT(FilterInstance->FilterTemplate->pFilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION) <= IoStack->Parameters.DeviceIoControl.OutputBufferLength);
for(Index = 0; Index < FilterInstance->FilterTemplate->pFilterDescriptor->ConnectionsCount; Index++)
{
/* sanity check */
ASSERT(FilterInstance->FilterTemplate->pFilterDescriptor->Connections);
/* copy connection */
RtlMoveMemory(pConnectionProperty, &FilterInstance->FilterTemplate->pFilterDescriptor->Connections[Index], sizeof(KSTOPOLOGY_CONNECTION));
}
/* store result */
Irp->IoStatus.Information = FilterInstance->FilterTemplate->pFilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION);
Irp->IoStatus.Status = STATUS_SUCCESS;
/* done */
return STATUS_SUCCESS;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaStartChanges(IN PIRP Irp)
{
DPRINT("BdaStartChanges\n");
if (Irp)
return STATUS_SUCCESS;
else
return STATUS_INVALID_PARAMETER;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaUninitFilter(IN PKSFILTER pKSFilter)
{
DPRINT("BdaUninitFilter\n");
return STATUS_SUCCESS;
}
/*
@implemented
*/
NTSTATUS
NTAPI
BdaValidateNodeProperty(
IN PIRP Irp,
IN KSPROPERTY *KSProperty)
{
DPRINT("BdaValidateNodeProperty\n");
/* check for valid parameter */
if (Irp && KSProperty)
return STATUS_SUCCESS;
return STATUS_INVALID_PARAMETER;
}