[BDASUP]
[reactos.git] / reactos / drivers / multimedia / bdasup / bdasup.c
index 63f3c36..221ae83 100644 (file)
@@ -1,6 +1,10 @@
 
 #include "precomp.h"
 
+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,
@@ -8,6 +12,84 @@ BDA_GLOBAL g_Settings =
     {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(
@@ -67,6 +149,23 @@ GetFilterInstanceEntry(
     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
 */
@@ -74,6 +173,8 @@ NTSTATUS
 NTAPI
 BdaCheckChanges(IN PIRP  Irp)
 {
+    DPRINT("BdaCheckChanges\n");
+
     if (!Irp)
         return STATUS_INVALID_PARAMETER;
 
@@ -87,6 +188,8 @@ NTSTATUS
 NTAPI
 BdaCommitChanges(IN PIRP  Irp)
 {
+    DPRINT("BdaCommitChanges\n");
+
     if (!Irp)
         return STATUS_INVALID_PARAMETER;
 
@@ -158,21 +261,42 @@ BdaCreateFilterFactoryEx(
     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;
+    }
 
-    /* FIXME provide a default automation table
-     * to handle requests which the driver doesnt implement
-     */
+    /* copy filter descriptor template */
+    RtlMoveMemory(FilterDescriptor, pFilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
+
+    /* 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, pFilterDescriptor, NULL, NULL, 0, NULL, NULL, &FilterFactory);
+    Status = KsCreateFilterFactory(pKSDevice->FunctionalDeviceObject, FilterDescriptor, NULL, NULL, 0, NULL, NULL, &FilterFactory);
 
     /* check for success */
     if (NT_SUCCESS(Status))
@@ -183,6 +307,8 @@ BdaCreateFilterFactoryEx(
         if (!NT_SUCCESS(Status))
         {
             /* destroy filter instance */
+            DPRINT1("KsAddItemToObjectBag failed with %lx\n", Status);
+            FreeItem(FilterDescriptor);
             FreeItem(FilterInstance);
             KsDeleteFilterFactory(FilterFactory);
             return Status;
@@ -212,9 +338,11 @@ BdaCreateFilterFactoryEx(
     {
         /* failed to create filter factory */
         FreeItem(FilterInstance);
+        DPRINT1("KsCreateFilterFactory failed with %lx\n", Status);
     }
 
     /* done */
+    DPRINT("BdaCreateFilterFactoryEx Status %x\n", Status);
     return Status;
 }
 
@@ -233,15 +361,13 @@ BdaCreatePin(
     PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
     NTSTATUS Status;
     ULONG PinId;
+    PKSPIN_DESCRIPTOR_EX NewPinDescriptor;
+
+    DPRINT("BdaCreatePin\n");
 
     if (!pulPinId || !pKSFilter)
         return STATUS_INVALID_PARAMETER;
 
-
-    /* FIXME provide a default automation table
-     * to handle requests which the driver doesnt implement
-     */
-
     /* get parent filter factory */
     FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
 
@@ -265,6 +391,7 @@ BdaCreatePin(
     if (!InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount)
     {
         /* no pins supported */
+        DPRINT("BdaCreatePin NoPins supported\n");
         return STATUS_UNSUCCESSFUL;
     }
 
@@ -272,6 +399,7 @@ BdaCreatePin(
     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;
     }
 
@@ -281,17 +409,37 @@ BdaCreatePin(
     /* get pin descriptor */
     PinDescriptor = (PKSPIN_DESCRIPTOR_EX)&InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptors[ulPinType];
 
-    /* create the pin factory */
-    Status = KsFilterCreatePinFactory(pKSFilter, PinDescriptor, &PinId);
+    /* 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))
     {
-        /* store result */
-        *pulPinId = PinId;
+        /* create the pin factory */
+        Status = KsFilterCreatePinFactory(pKSFilter, NewPinDescriptor, &PinId);
+
+        /* check for success */
+        if (NT_SUCCESS(Status))
+        {
+            /* store result */
+            *pulPinId = PinId;
+        }
     }
 
-    DPRINT("BdaCreatePin Result %x\n", Status);
+
+    DPRINT("BdaCreatePin Result %x PinId %u\n", Status, PinId);
     return Status;
 }
 
@@ -308,6 +456,8 @@ BdaMethodCreatePin(
     PKSM_PIN Pin;
     PKSFILTER Filter;
 
+    DPRINT("BdaMethodCreatePin\n");
+
     if (!Irp)
     {
         /* invalid parameter */
@@ -342,6 +492,8 @@ BdaInitFilter(
     ULONG Index, PinId;
     NTSTATUS Status = STATUS_SUCCESS;
 
+    DPRINT("BdaInitFilter %p\n", pBdaFilterTemplate);
+
     /* check input parameters */
     if (!pKSFilter)
         return STATUS_INVALID_PARAMETER;
@@ -357,7 +509,12 @@ BdaInitFilter(
 
     /* sanity check */
     ASSERT(InstanceEntry);
-    ASSERT(InstanceEntry->FilterTemplate == pBdaFilterTemplate);
+
+    if (!pBdaFilterTemplate)
+    {
+        /* use template from BdaCreateFilterFactoryEx */
+        pBdaFilterTemplate = InstanceEntry->FilterTemplate;
+    }
 
     /* now create the pins */
     for(Index = 0; Index < pBdaFilterTemplate->pFilterDescriptor->PinDescriptorsCount; Index++)
@@ -390,6 +547,8 @@ BdaCreateTopology(
     PKSFILTERFACTORY FilterFactory;
     KSTOPOLOGY_CONNECTION Connection;
 
+    DPRINT("BdaCreateTopology\n");
+
     /* check input parameters */
     if (!pKSFilter)
         return STATUS_INVALID_PARAMETER;
@@ -436,6 +595,7 @@ BdaDeletePin(
     IN ULONG *pulPinId)
 {
     UNIMPLEMENTED
+    DPRINT("BdaDeletePin\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -448,6 +608,7 @@ BdaFilterFactoryUpdateCacheData(
     IN PKSFILTERFACTORY FilterFactory,
     IN const KSFILTER_DESCRIPTOR *FilterDescriptor OPTIONAL)
 {
+    DPRINT("BdaFilterFactoryUpdateCacheData\n");
     return KsFilterFactoryUpdateCacheData(FilterFactory, FilterDescriptor);
 }
 
@@ -460,6 +621,8 @@ BdaGetChangeState(
     IN PIRP Irp,
     OUT BDA_CHANGE_STATE *ChangeState)
 {
+    DPRINT("BdaGetChangeState\n");
+
     if (Irp && ChangeState)
     {
         *ChangeState = BDA_CHANGES_COMPLETE;
@@ -484,6 +647,8 @@ BdaMethodCreateTopology(
     PKSFILTER Filter;
     PKSP_BDA_NODE_PIN Node;
 
+    DPRINT("BdaMethodCreateTopology\n");
+
     /* check input parameters */
     if (!Irp || !pKSMethod)
         return STATUS_INVALID_PARAMETER;
@@ -511,6 +676,8 @@ BdaMethodDeletePin(
     IN KSMETHOD *pKSMethod,
     OPTIONAL PVOID pvIgnored)
 {
+    DPRINT("BdaMethodDeletePin\n");
+
     if (!Irp)
         return STATUS_INVALID_PARAMETER;
 
@@ -528,6 +695,7 @@ BdaPropertyGetControllingPinId(
     OUT ULONG *pulControllingPinId)
 {
     UNIMPLEMENTED
+    DPRINT("BdaPropertyGetControllingPinId\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -546,6 +714,8 @@ BdaPropertyGetPinControl(
     PKSFILTERFACTORY FilterFactory;
     PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
 
+    DPRINT("BdaPropertyGetPinControl\n");
+
     /* first get the pin */
     Pin = KsGetPinFromIrp(Irp);
     ASSERT(Pin);
@@ -580,9 +750,10 @@ NTAPI
 BdaPropertyNodeDescriptors(
     IN PIRP Irp,
     IN KSPROPERTY *pKSProperty,
-    OUT GUID *pguidProperty)
+    OUT BDANODE_DESCRIPTOR *pNodeDescriptorProperty)
 {
     UNIMPLEMENTED
+    DPRINT("BdaPropertyNodeDescriptors\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -593,10 +764,11 @@ NTSTATUS
 NTAPI
 BdaPropertyNodeEvents(
     IN PIRP Irp,
-    IN KSPROPERTY *pKSProperty,
+    IN KSP_NODE *pKSProperty,
     OUT GUID *pguidProperty)
 {
     UNIMPLEMENTED
+    DPRINT("BdaPropertyNodeEvents\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -607,10 +779,11 @@ NTSTATUS
 NTAPI
 BdaPropertyNodeMethods(
     IN PIRP Irp,
-    IN KSPROPERTY *pKSProperty,
+    IN KSP_NODE *pKSProperty,
     OUT GUID *pguidProperty)
 {
     UNIMPLEMENTED
+    DPRINT("BdaPropertyNodeMethods\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -621,10 +794,11 @@ NTSTATUS
 NTAPI
 BdaPropertyNodeProperties(
     IN PIRP Irp,
-    IN KSPROPERTY *pKSProperty,
+    IN KSP_NODE *pKSProperty,
     OUT GUID *pguidProperty)
 {
     UNIMPLEMENTED
+    DPRINT("BdaPropertyNodeProperties\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -644,6 +818,8 @@ BdaPropertyNodeTypes(
     PIO_STACK_LOCATION IoStack;
     ULONG Index;
 
+    DPRINT("BdaPropertyNodeTypes\n");
+
     /* check input parameter */
     if (!Irp || !pKSProperty)
         return STATUS_INVALID_PARAMETER;
@@ -710,6 +886,8 @@ BdaPropertyPinTypes(
     PIO_STACK_LOCATION IoStack;
     ULONG Index;
 
+    DPRINT("BdaPropertyPinTypes\n");
+
     /* check input parameter */
     if (!Irp || !pKSProperty)
         return STATUS_INVALID_PARAMETER;
@@ -775,6 +953,8 @@ BdaPropertyTemplateConnections(
     PIO_STACK_LOCATION IoStack;
     ULONG Index;
 
+    DPRINT("BdaPropertyTemplateConnections\n");
+
     /* validate parameters */
     if (!Irp || !pKSProperty)
         return STATUS_INVALID_PARAMETER;
@@ -830,6 +1010,8 @@ NTSTATUS
 NTAPI
 BdaStartChanges(IN PIRP Irp)
 {
+    DPRINT("BdaStartChanges\n");
+
     if (Irp)
         return STATUS_SUCCESS;
     else
@@ -844,6 +1026,7 @@ NTSTATUS
 NTAPI
 BdaUninitFilter(IN PKSFILTER pKSFilter)
 {
+    DPRINT("BdaUninitFilter\n");
     return STATUS_SUCCESS;
 }
 
@@ -856,6 +1039,8 @@ BdaValidateNodeProperty(
     IN PIRP Irp,
     IN KSPROPERTY *KSProperty)
 {
+    DPRINT("BdaValidateNodeProperty\n");
+
     /* check for valid parameter */
     if (Irp && KSProperty)
         return STATUS_SUCCESS;