[KS]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 1 Apr 2010 14:53:16 +0000 (14:53 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 1 Apr 2010 14:53:16 +0000 (14:53 +0000)
- Refactor & bugfix handling of KSPROPERTY_PIN_INTERFACES
- Refactor & bugfix IKsFilter_fnAddProcessPin for filter centric pins
- Fix handling of filter pin property sets
- Copy filter pin templates when filter is initialized.
- Pins are now able to instantiated but processing is pin requests is not yet implemented

svn path=/trunk/; revision=46640

reactos/drivers/ksfilter/ks/connectivity.c
reactos/drivers/ksfilter/ks/filter.c
reactos/drivers/ksfilter/ks/pin.c

index ae9200b..7c9b822 100644 (file)
@@ -392,34 +392,18 @@ KsPinPropertyHandler(
                 break;
             }
 
-            /* calculate size */
-            Size = sizeof(KSMULTIPLE_ITEM);
-            Size += max(1, Descriptor[Pin->PinId].InterfacesCount) * sizeof(KSPIN_INTERFACE);
-
-            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
+            if (Descriptor[Pin->PinId].Interfaces)
             {
-                Irp->IoStatus.Information = Size;
-                Status = STATUS_MORE_ENTRIES;
-                break;
-            }
-
-            Item = (KSMULTIPLE_ITEM*)Buffer;
-            Item->Size = Size;
-
-            if (Descriptor[Pin->PinId].InterfacesCount)
-            {
-                Item->Count = Descriptor[Pin->PinId].InterfacesCount;
-                RtlMoveMemory((PVOID)(Item + 1), Descriptor[Pin->PinId].Interfaces, Descriptor[Pin->PinId].InterfacesCount * sizeof(KSPIN_INTERFACE));
+                /* use mediums provided by driver */
+                return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Interfaces);
             }
             else
             {
-                Item->Count = 1;
-                RtlMoveMemory((PVOID)(Item + 1), &StandardPinInterface, sizeof(KSPIN_INTERFACE));
+                /* use standard medium */
+                return KsHandleSizedListQuery(Irp, 1, sizeof(KSPIN_INTERFACE), &StandardPinInterface);
             }
-
-            Status = STATUS_SUCCESS;
-            Irp->IoStatus.Information = Size;
             break;
+
         case KSPROPERTY_PIN_MEDIUMS:
             Pin = (KSP_PIN*)Property;
             if (Pin->PinId >= DescriptorsCount)
index 1341f53..773302b 100644 (file)
@@ -288,43 +288,30 @@ IKsFilter_fnAddProcessPin(
     IKsFilter * iface,
     IN PKSPROCESSPIN ProcessPin)
 {
-    PKSPROCESSPIN *Pins;
+    NTSTATUS Status;
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
 
     /* first acquire processing mutex */
     KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
 
-    /* allocate new pins array */
-    Pins = AllocateItem(NonPagedPool, sizeof(PKSPROCESSPIN) * (This->ProcessPinIndex.Count + 1));
+    /* edit process pin descriptor */
+    Status = _KsEdit(This->Filter.Bag,
+                     (PVOID*)&This->ProcessPinIndex.Pins, 
+                     (This->ProcessPinIndex.Count + 1) * sizeof(PKSPROCESSPIN),
+                     (This->ProcessPinIndex.Count) * sizeof(PKSPROCESSPIN),
+                     0);
 
-    /* check if allocation succeeded */
-    if (Pins)
+    if (NT_SUCCESS(Status))
     {
-        if (This->ProcessPinIndex.Count)
-        {
-            /* copy old pin index */
-            RtlMoveMemory(Pins, This->ProcessPinIndex.Pins, sizeof(PKSPROCESSPIN) * This->ProcessPinIndex.Count);
-        }
-
         /* add new process pin */
-        Pins[This->ProcessPinIndex.Count] = ProcessPin;
-
-        /* free old process pin */
-        FreeItem(This->ProcessPinIndex.Pins);
-
-        /* store new process pin index */
-        This->ProcessPinIndex.Pins = Pins;
+        This->ProcessPinIndex.Pins[This->ProcessPinIndex.Count] = ProcessPin;
         This->ProcessPinIndex.Count++;
     }
 
     /* release process mutex */
     KeReleaseMutex(&This->ProcessingMutex, FALSE);
 
-    if (Pins)
-        return STATUS_SUCCESS;
-    else
-        return STATUS_INSUFFICIENT_RESOURCES;
-
+    return Status;
 }
 
 NTSTATUS
@@ -530,7 +517,7 @@ KspHandlePropertyInstances(
     KSPIN_CINSTANCES * Instances;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
-    if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount)
+    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -539,11 +526,11 @@ KspHandlePropertyInstances(
 
     /* ignore custom structs for now */
     ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > Pin->PinId);
+    ASSERT(This->PinDescriptorCount > Pin->PinId);
 
     Instances = (KSPIN_CINSTANCES*)Data;
     /* max instance count */
-    Instances->PossibleCount = This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].InstancesPossible;
+    Instances->PossibleCount = This->PinDescriptorsEx[Pin->PinId].InstancesPossible;
     /* current instance count */
     Instances->CurrentCount = This->PinInstanceCount[Pin->PinId];
 
@@ -562,7 +549,7 @@ KspHandleNecessaryPropertyInstances(
     PULONG Result;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
-    if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount)
+    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -571,10 +558,10 @@ KspHandleNecessaryPropertyInstances(
 
     /* ignore custom structs for now */
     ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > Pin->PinId);
+    ASSERT(This->PinDescriptorCount > Pin->PinId);
 
     Result = (PULONG)Data;
-    *Result = This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
+    *Result = This->PinDescriptorsEx[Pin->PinId].InstancesNecessary;
 
     IoStatus->Information = sizeof(ULONG);
     IoStatus->Status = STATUS_SUCCESS;
@@ -600,7 +587,7 @@ KspHandleDataIntersection(
     MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
     DataRange = (PKSDATARANGE)(MultipleItem + 1);
 
-    if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount)
+    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -609,11 +596,11 @@ KspHandleDataIntersection(
 
     /* ignore custom structs for now */
     ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > Pin->PinId);
+    ASSERT(This->PinDescriptorCount > Pin->PinId);
 
-    if (This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL ||
-        This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL ||
-        This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0)
+    if (This->PinDescriptorsEx[Pin->PinId].IntersectHandler == NULL ||
+        This->PinDescriptors[Pin->PinId].DataRanges == NULL ||
+        This->PinDescriptors[Pin->PinId].DataRangesCount == 0)
     {
         /* no driver supported intersect handler / no provided data ranges */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -623,14 +610,14 @@ KspHandleDataIntersection(
     for(Index = 0; Index < MultipleItem->Count; Index++)
     {
         /* Call miniport's properitary handler */
-        Status = This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].IntersectHandler(NULL, /* context */
-                                                                                              Irp,
-                                                                                              Pin,
-                                                                                              DataRange,
-                                                                                              (PKSDATAFORMAT)This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges,
-                                                                                              DataLength,
-                                                                                              Data,
-                                                                                              &Length);
+        Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(NULL, /* context */
+                                                                     Irp,
+                                                                     Pin,
+                                                                     DataRange,
+                                                                    (PKSDATAFORMAT)This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges,
+                                                                     DataLength,
+                                                                     Data,
+                                                                     &Length);
 
         if (Status == STATUS_SUCCESS)
         {
@@ -696,6 +683,9 @@ KspPinPropertyHandler(
             UNIMPLEMENTED
             Status = STATUS_UNSUCCESSFUL;
     }
+    DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status);
+
+
     return Status;
 }
 
@@ -784,9 +774,9 @@ IKsFilter_CreateDescriptors(
     KSFILTER_DESCRIPTOR* FilterDescriptor)
 {
     ULONG Index = 0;
+    NTSTATUS Status;
 
     /* initialize pin descriptors */
-    This->PinInstanceCount = NULL;
     This->FirstPin = NULL;
     This->PinInstanceCount = NULL;
     This->PinDescriptors = NULL;
@@ -800,6 +790,69 @@ IKsFilter_CreateDescriptors(
     This->Topology.TopologyConnectionsCount = FilterDescriptor->ConnectionsCount;
     This->Topology.TopologyConnections = FilterDescriptor->Connections;
 
+    /* are there any templates */
+    if (FilterDescriptor->PinDescriptorsCount)
+    {
+        /* sanity check */
+        ASSERT(FilterDescriptor->PinDescriptors);
+
+        /* FIXME handle variable sized pin descriptors */
+        ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
+
+        /* store pin descriptors ex */
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount,
+                         sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount, 0);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+            return Status;
+        }
+
+        /* store pin descriptors */
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount,
+                         sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount, 0);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+            return Status;
+        }
+
+        /* store pin instance count ex */
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount,
+                         sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+            return Status;
+        }
+
+        /* store instantiated pin arrays */
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->FirstPin, sizeof(PKSPIN) * FilterDescriptor->PinDescriptorsCount,
+                         sizeof(PKSPIN) * FilterDescriptor->PinDescriptorsCount, 0);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+            return Status;
+        }
+
+
+
+        /* add new pin factory */
+        RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount);
+
+        for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++)
+        {
+            RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
+        }
+
+        /* store new pin descriptor count */
+        This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
+    }
+
     if (FilterDescriptor->NodeDescriptorsCount)
     {
         /* sanity check */
@@ -923,24 +976,40 @@ IKsFilter_DispatchCreatePin(
     PKSPIN_CONNECT Connect;
     NTSTATUS Status;
 
+    DPRINT("IKsFilter_DispatchCreatePin\n");
+
     /* get the create item */
     CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
 
     /* get the filter object */
     This = (IKsFilterImpl*)CreateItem->Context;
 
+    /* sanity check */
+    ASSERT(This->Header.Type == KsObjectTypeFilter);
+
     /* acquire control mutex */
     KeWaitForSingleObject(&This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
 
     /* now validate the connect request */
     Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect);
 
+    DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status);
+
     if (NT_SUCCESS(Status))
     {
-        if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible)
+        /* sanity check */
+        ASSERT(Connect->PinId < This->PinDescriptorCount);
+
+        DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId, 
+               This->PinInstanceCount[Connect->PinId],
+               This->PinDescriptorsEx[Connect->PinId].InstancesPossible);
+
+        if (This->PinInstanceCount[Connect->PinId] < This->PinDescriptorsEx[Connect->PinId].InstancesPossible)
         {
             /* create the pin */
-            Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]);
+            Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, &This->PinDescriptorsEx[Connect->PinId]);
+
+            DPRINT("IKsFilter_DispatchCreatePin  KspCreatePin %lx\n", Status);
 
             if (NT_SUCCESS(Status))
             {
@@ -952,6 +1021,7 @@ IKsFilter_DispatchCreatePin(
         {
             /* maximum instance count reached, bye-bye */
             Status = STATUS_UNSUCCESSFUL;
+            DPRINT("IKsFilter_DispatchCreatePin  MaxInstance %lu CurInstance %lu %lx\n", This->PinDescriptorsEx[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
         }
     }
 
@@ -964,7 +1034,9 @@ IKsFilter_DispatchCreatePin(
         Irp->IoStatus.Status = Status;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
     }
+
     /* done */
+    DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status);
     return Status;
 }
 
index 3b4e0b8..a133882 100644 (file)
@@ -1089,6 +1089,8 @@ KspCreatePin(
     ASSERT(Descriptor->Dispatch);
     ASSERT(Descriptor->Dispatch->Create);
 
+    DPRINT("KspCreatePin\n");
+
     /* get current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
@@ -1112,6 +1114,7 @@ KspCreatePin(
     {
         /* not enough memory */
         FreeItem(This);
+        DPRINT("KspCreatePin OutOfMemory\n");
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -1184,6 +1187,7 @@ KspCreatePin(
     if (!NT_SUCCESS(Status))
     {
         /* failed to create object header */
+        DPRINT("KspCreatePin KsAllocateObjectHeader failed %lx\n", Status);
         KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
         FreeItem(This);
         FreeItem(CreateItem);
@@ -1208,6 +1212,8 @@ KspCreatePin(
          */
 
         Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin);
+        DPRINT("KspCreatePin AddProcessPin %lx\n", Status);
+
         if (!NT_SUCCESS(Status))
         {
             /* failed to add process pin */
@@ -1226,8 +1232,11 @@ KspCreatePin(
     {
         /*  now inform the driver to create a new pin */
         Status = Descriptor->Dispatch->Create(&This->Pin, Irp);
+        DPRINT("KspCreatePin DispatchCreate %lx\n", Status);
     }
 
+    DPRINT("KspCreatePin Status %lx\n", Status);
+
     if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
     {
         /* failed to create pin, release resources */