[KS]
[reactos.git] / reactos / drivers / ksfilter / ks / filter.c
index bcac218..5f4a74b 100644 (file)
@@ -14,16 +14,12 @@ typedef struct
     KSBASIC_HEADER Header;
     KSFILTER Filter;
 
-    IKsFilterVtbl *lpVtbl;
     IKsControlVtbl *lpVtblKsControl;
     IKsFilterFactory * FilterFactory;
     LONG ref;
 
     PKSIOBJECT_HEADER ObjectHeader;
     KSTOPOLOGY Topology;
-    KSPIN_DESCRIPTOR_EX * PinDescriptorsEx;
-    KSPIN_DESCRIPTOR * PinDescriptors;
-    ULONG PinDescriptorCount;
     PKSFILTERFACTORY Factory;
     PFILE_OBJECT FileObject;
     KMUTEX ControlMutex;
@@ -49,9 +45,12 @@ IKsFilter_RemoveFilterFromFilterFactory(
     IKsFilterImpl * This,
     PKSFILTERFACTORY FilterFactory);
 
+NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER  Request, IN OUT PVOID  Data);
+NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER  Request, IN OUT PVOID  Data);
 
-DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler);
-DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler);
+
+DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler);
+DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler);
 
 KSPROPERTY_SET FilterPropertySet[] =
 {
@@ -82,7 +81,7 @@ IKsControl_fnQueryInterface(
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->Header.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
@@ -185,12 +184,13 @@ IKsFilter_fnQueryInterface(
     IN  REFIID refiid,
     OUT PVOID* Output)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    NTSTATUS Status;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     if (IsEqualGUIDAligned(refiid, &IID_IUnknown) ||
         IsEqualGUIDAligned(refiid, &IID_IKsFilter))
     {
-        *Output = &This->lpVtbl;
+        *Output = &This->Header.OuterUnknown;
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
@@ -201,7 +201,20 @@ IKsFilter_fnQueryInterface(
         return STATUS_SUCCESS;
     }
 
-    return STATUS_UNSUCCESSFUL;
+    if (This->Header.ClientAggregate)
+    {
+         /* using client aggregate */
+         Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output);
+
+         if (NT_SUCCESS(Status))
+         {
+             /* client aggregate supports interface */
+             return Status;
+         }
+    }
+
+    DPRINT("IKsFilter_fnQueryInterface no interface\n");
+    return STATUS_NOT_SUPPORTED;
 }
 
 ULONG
@@ -209,7 +222,7 @@ NTAPI
 IKsFilter_fnAddRef(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     return InterlockedIncrement(&This->ref);
 }
@@ -219,7 +232,7 @@ NTAPI
 IKsFilter_fnRelease(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     InterlockedDecrement(&This->ref);
 
@@ -238,7 +251,7 @@ NTAPI
 IKsFilter_fnGetStruct(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     return &This->Filter;
 }
@@ -295,18 +308,18 @@ IKsFilter_fnAddProcessPin(
     IN PKSPROCESSPIN ProcessPin)
 {
     NTSTATUS Status;
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     /* first acquire processing mutex */
     KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
 
     /* sanity check */
-    ASSERT(This->PinDescriptorCount > ProcessPin->Pin->Id);
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id);
 
     /* allocate new process pin array */
     Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins,
-                     (This->PinDescriptorCount + 1) * sizeof(PKSPROCESSPIN),
-                     This->PinDescriptorCount * sizeof(PKSPROCESSPIN),
+                     (This->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PKSPROCESSPIN),
+                     This->Filter.Descriptor->PinDescriptorsCount * sizeof(PKSPROCESSPIN),
                      0);
 
     if (NT_SUCCESS(Status))
@@ -332,7 +345,7 @@ IKsFilter_fnRemoveProcessPin(
     ULONG Count;
     PKSPROCESSPIN * Pins;
 
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     /* first acquire processing mutex */
     KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
@@ -416,7 +429,7 @@ NTAPI
 IKsFilter_fnGetProcessDispatch(
     IKsFilter * iface)
 {
-    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown);
 
     return This->ProcessPinIndex;
 }
@@ -495,13 +508,13 @@ IKsFilter_DispatchClose(
         return Status;
 
     /* get our real implementation */
-    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl);
+    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
 
     /* does the driver support notifications */
-    if (This->Factory->FilterDescriptor && This->Factory->FilterDescriptor->Dispatch && This->Factory->FilterDescriptor->Dispatch->Close)
+    if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close)
     {
         /* call driver's filter close function */
-        Status = This->Factory->FilterDescriptor->Dispatch->Close(&This->Filter, Irp);
+        Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp);
     }
 
     if (NT_SUCCESS(Status) && Status != STATUS_PENDING)
@@ -540,7 +553,7 @@ KspHandlePropertyInstances(
     KSPIN_CINSTANCES * Instances;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -548,12 +561,12 @@ KspHandlePropertyInstances(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
     Instances = (KSPIN_CINSTANCES*)Data;
     /* max instance count */
-    Instances->PossibleCount = This->PinDescriptorsEx[Pin->PinId].InstancesPossible;
+    Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible;
     /* current instance count */
     Instances->CurrentCount = This->PinInstanceCount[Pin->PinId];
 
@@ -572,7 +585,7 @@ KspHandleNecessaryPropertyInstances(
     PULONG Result;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -580,11 +593,11 @@ KspHandleNecessaryPropertyInstances(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
     Result = (PULONG)Data;
-    *Result = This->PinDescriptorsEx[Pin->PinId].InstancesNecessary;
+    *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
 
     IoStatus->Information = sizeof(ULONG);
     IoStatus->Status = STATUS_SUCCESS;
@@ -604,8 +617,15 @@ KspHandleDataIntersection(
     PKSDATARANGE DataRange;
     NTSTATUS Status = STATUS_NO_MATCH;
     ULONG Index, Length;
+    PIO_STACK_LOCATION IoStack;
     KSP_PIN * Pin = (KSP_PIN*)Request;
 
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* sanity check */
+    ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+
     /* Access parameters */
     MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
     DataRange = (PKSDATARANGE)(MultipleItem + 1);
@@ -613,7 +633,7 @@ KspHandleDataIntersection(
     /* FIXME make sure its 64 bit aligned */
     ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
 
-    if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
+    if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* no filter / pin descriptor */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -621,12 +641,12 @@ KspHandleDataIntersection(
     }
 
     /* ignore custom structs for now */
-    ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
-    ASSERT(This->PinDescriptorCount > Pin->PinId);
+    ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); 
+    ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
 
-    if (This->PinDescriptorsEx[Pin->PinId].IntersectHandler == NULL ||
-        This->PinDescriptors[Pin->PinId].DataRanges == NULL ||
-        This->PinDescriptors[Pin->PinId].DataRangesCount == 0)
+    if (This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL ||
+        This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL ||
+        This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0)
     {
         /* no driver supported intersect handler / no provided data ranges */
         IoStatus->Status = STATUS_NOT_IMPLEMENTED;
@@ -641,26 +661,25 @@ KspHandleDataIntersection(
         RtlStringFromGUID(&DataRange->SubFormat, &SubFormat);
         RtlStringFromGUID(&DataRange->Specifier, &Specifier);
 
-        DPRINT("Index %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer,
-                       DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength);
+        DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, Pin->PinId, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer,
+               DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength);
 
         /* FIXME implement KsPinDataIntersectionEx */
         /* Call miniport's properitary handler */
-        Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(&This->Filter,
-                                                                     Irp,
-                                                                     Pin,
-                                                                     DataRange,
-                                                                     This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
-                                                                     DataLength,
-                                                                     Data,
-                                                                     &Length);
+        Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter,
+                                                                                      Irp,
+                                                                                      Pin,
+                                                                                      DataRange,
+                                                                                      This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
+                                                                                      DataLength,
+                                                                                      Data,
+                                                                                      &Length);
+        DPRINT("KspHandleDataIntersection Status %lx\n", Status);
 
         if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
         {
             ASSERT(Length);
             IoStatus->Information = Length;
-            if (Status != STATUS_SUCCESS)
-                Status = STATUS_MORE_ENTRIES;
             break;
         }
 
@@ -668,14 +687,13 @@ KspHandleDataIntersection(
         /* FIXME make sure its 64 bit aligned */
         ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
     }
-
     IoStatus->Status = Status;
     return Status;
 }
 
 NTSTATUS
 NTAPI
-KspTopologyPropertyHandler(
+FilterTopologyPropertyHandler(
     IN PIRP Irp,
     IN PKSIDENTIFIER  Request,
     IN OUT PVOID  Data)
@@ -695,7 +713,7 @@ KspTopologyPropertyHandler(
 
 NTSTATUS
 NTAPI
-KspPinPropertyHandler(
+FilterPinPropertyHandler(
     IN PIRP Irp,
     IN PKSIDENTIFIER  Request,
     IN OUT PVOID  Data)
@@ -724,7 +742,7 @@ KspPinPropertyHandler(
         case KSPROPERTY_PIN_CATEGORY:
         case KSPROPERTY_PIN_NAME:
         case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
-            Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors);
+            Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize);
             break;
         case KSPROPERTY_PIN_GLOBALCINSTANCES:
             Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE);
@@ -770,7 +788,7 @@ IKsFilter_DispatchDeviceIoControl(
         return Status;
 
     /* get our real implementation */
-    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl);
+    This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown);
 
     /* current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -781,16 +799,14 @@ IKsFilter_DispatchDeviceIoControl(
     /* get filter instance */
     FilterInstance = Filter->lpVtbl->GetStruct(Filter);
 
-
     /* sanity check */
     ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
     ASSERT(FilterInstance);
     ASSERT(FilterInstance->Descriptor);
     ASSERT(FilterInstance->Descriptor->AutomationTable);
 
-    RtlStringFromGUID(&Property->Set, &GuidString);
-    DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
-    RtlFreeUnicodeString(&GuidString);
+    /* acquire control mutex */
+    KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
 
     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD)
     {
@@ -859,6 +875,9 @@ IKsFilter_DispatchDeviceIoControl(
     /* release filter */
     Filter->lpVtbl->Release(Filter);
 
+    /* release control mutex */
+    KeReleaseMutex(This->Header.ControlMutex, FALSE);
+
     if (Status != STATUS_PENDING)
     {
         Irp->IoStatus.Status = Status;
@@ -895,10 +914,7 @@ IKsFilter_CreateDescriptors(
     /* initialize pin descriptors */
     This->FirstPin = NULL;
     This->PinInstanceCount = NULL;
-    This->PinDescriptors = NULL;
-    This->PinDescriptorsEx = NULL;
     This->ProcessPinIndex = NULL;
-    This->PinDescriptorCount = 0;
 
     /* initialize topology descriptor */
     This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount;
@@ -917,18 +933,8 @@ IKsFilter_CreateDescriptors(
         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);
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount,
+                         FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0);
 
         if (!NT_SUCCESS(Status))
         {
@@ -936,7 +942,7 @@ IKsFilter_CreateDescriptors(
             return Status;
         }
 
-        /* store pin instance count ex */
+        /* store pin instance count */
         Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount,
                          sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0);
 
@@ -957,12 +963,7 @@ IKsFilter_CreateDescriptors(
         }
 
         /* 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));
-        }
+        RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount);
 
         /* allocate process pin index */
         Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount,
@@ -974,9 +975,20 @@ IKsFilter_CreateDescriptors(
             return Status;
         }
 
-        /* store new pin descriptor count */
-        This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
+    }
+
 
+    if (FilterDescriptor->ConnectionsCount)
+    {
+        /* modify connections array */
+        Status = _KsEdit(This->Filter.Bag,
+                        (PVOID*)&This->Filter.Descriptor->Connections,
+                         FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                         FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                         0);
+
+       This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
+       This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount;
     }
 
     if (FilterDescriptor->NodeDescriptorsCount)
@@ -1070,7 +1082,7 @@ IKsFilter_AddPin(
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
     /* sanity check */
-    ASSERT(Pin->Id < This->PinDescriptorCount);
+    ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
 
     if (This->FirstPin[Pin->Id] == NULL)
     {
@@ -1111,7 +1123,7 @@ IKsFilter_RemovePin(
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
     /* sanity check */
-    ASSERT(Pin->Id < This->PinDescriptorCount);
+    ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
 
     /* get first pin */
     CurPin = This->FirstPin[Pin->Id];
@@ -1180,23 +1192,23 @@ IKsFilter_DispatchCreatePin(
     KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
 
     /* now validate the connect request */
-    Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect);
+    Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect);
 
     DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status);
 
     if (NT_SUCCESS(Status))
     {
         /* sanity check */
-        ASSERT(Connect->PinId < This->PinDescriptorCount);
+        ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount);
 
         DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId, 
                This->PinInstanceCount[Connect->PinId],
-               This->PinDescriptorsEx[Connect->PinId].InstancesPossible);
+               This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible);
 
-        if (This->PinInstanceCount[Connect->PinId] < This->PinDescriptorsEx[Connect->PinId].InstancesPossible)
+        if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible)
         {
             /* create the pin */
-            Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, &This->PinDescriptorsEx[Connect->PinId]);
+            Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]);
 
             DPRINT("IKsFilter_DispatchCreatePin  KspCreatePin %lx\n", Status);
         }
@@ -1204,7 +1216,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]);
+            DPRINT("IKsFilter_DispatchCreatePin  MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
         }
     }
 
@@ -1388,7 +1400,7 @@ KspCreateFilter(
         DPRINT("KspCreateFilter OutOfMemory\n");
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice;
+    KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
     KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL);
 
     /* copy filter descriptor */
@@ -1432,7 +1444,7 @@ KspCreateFilter(
 
     /* initialize filter instance */
     This->ref = 1;
-    This->lpVtbl = &vt_IKsFilter;
+    This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter;
     This->lpVtblKsControl = &vt_IKsControl;
 
     This->Factory = Factory;
@@ -1496,14 +1508,14 @@ KspCreateFilter(
 
     /* initialize object header extra fields */
     This->ObjectHeader->Type = KsObjectTypeFilter;
-    This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
+    This->ObjectHeader->Unknown = (PUNKNOWN)&This->Header.OuterUnknown;
     This->ObjectHeader->ObjectType = (PVOID)&This->Filter;
 
     /* attach filter to filter factory */
     IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory);
 
     /* completed initialization */
-    DPRINT("KspCreateFilter done %lx\n", Status);
+    DPRINT("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice);
     return Status;
 }
 
@@ -1548,40 +1560,42 @@ KsFilterAddTopologyConnections (
     IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections)
 {
     ULONG Count;
-    KSTOPOLOGY_CONNECTION * Connections;
+    NTSTATUS Status;
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
+    DPRINT("KsFilterAddTopologyConnections\n");
+
+    ASSERT(This->Filter.Descriptor);
     Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount;
 
-    /* allocate array */
-    Connections = AllocateItem(NonPagedPool, Count * sizeof(KSTOPOLOGY_CONNECTION));
-    if (!Connections)
-        return STATUS_INSUFFICIENT_RESOURCES;
 
-    /* FIXME verify connections */
+    /* modify connections array */
+    Status = _KsEdit(This->Filter.Bag,
+                    (PVOID*)&This->Filter.Descriptor->Connections,
+                     Count * sizeof(KSTOPOLOGY_CONNECTION),
+                     This->Filter.Descriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION),
+                     0);
 
-    if (This->Filter.Descriptor->ConnectionsCount)
+    if (!NT_SUCCESS(Status))
     {
-        /* copy old connections */
-        RtlMoveMemory(Connections, This->Filter.Descriptor->Connections, sizeof(KSTOPOLOGY_CONNECTION) * This->Filter.Descriptor->ConnectionsCount);
+        /* failed */
+        DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status);
+        return Status;
     }
 
-    /* add new connections */
-    RtlMoveMemory((PVOID)(Connections + This->Filter.Descriptor->ConnectionsCount), NewTopologyConnections, NewConnectionsCount);
-
-    /* add the new connections */
-    RtlMoveMemory((PVOID)&This->Filter.Descriptor->ConnectionsCount, &Count, sizeof(ULONG)); /* brain-dead gcc hack */
+    /* FIXME verify connections */
 
-    /* free old connections array */
-    if (This->Filter.Descriptor->ConnectionsCount)
-    {
-        FreeItem((PVOID)This->Filter.Descriptor->Connections);
-    }
+    /* copy new connections */
+    RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount],
+                  NewTopologyConnections,
+                  NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
 
-    /* brain-dead gcc hack */
-    RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections, Connections, sizeof(KSTOPOLOGY_CONNECTION*));
+    /* update topology */
+    This->Topology.TopologyConnectionsCount += NewConnectionsCount;
+    ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount;
+    This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 /*
@@ -1630,22 +1644,13 @@ KsFilterCreatePinFactory (
     DPRINT("KsFilterCreatePinFactory\n");
 
     /* calculate new count */
-    Count = This->PinDescriptorCount + 1;
+    Count = This->Filter.Descriptor->PinDescriptorsCount + 1;
 
     /* sanity check */
     ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
 
-    /* allocate pin descriptors ex array */
-    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, Count * sizeof(KSPIN_DESCRIPTOR_EX), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR_EX), 0);
-    if (!NT_SUCCESS(Status))
-    {
-        /* failed */
-        DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
-        return Status;
-    }
-
-    /* allocate pin descriptors array */
-    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, Count * sizeof(KSPIN_DESCRIPTOR), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR), 0);
+    /* modify pin descriptors ex array */
+    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, Count * This->Filter.Descriptor->PinDescriptorSize, This->Filter.Descriptor->PinDescriptorsCount * This->Filter.Descriptor->PinDescriptorSize, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1653,9 +1658,8 @@ KsFilterCreatePinFactory (
         return Status;
     }
 
-
-    /* allocate pin instance count array */
-    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->PinDescriptorCount, 0);
+    /* modify pin instance count array */
+    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->Filter.Descriptor->PinDescriptorsCount, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1663,8 +1667,8 @@ KsFilterCreatePinFactory (
         return Status;
     }
 
-    /* allocate first pin array */
-    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->PinDescriptorCount, 0);
+    /* modify first pin array */
+    Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->Filter.Descriptor->PinDescriptorsCount, 0);
     if (!NT_SUCCESS(Status))
     {
         /* failed */
@@ -1673,13 +1677,11 @@ KsFilterCreatePinFactory (
     }
 
     /* add new pin factory */
-    RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
-    RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount], &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
-
+    RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
 
     /* allocate process pin index */
     Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count,
-                     sizeof(KSPROCESSPIN_INDEXENTRY) * This->PinDescriptorCount, 0);
+                     sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0);
 
     if (!NT_SUCCESS(Status))
     {
@@ -1688,10 +1690,10 @@ KsFilterCreatePinFactory (
     }
 
     /* store new pin id */
-    *PinID = This->PinDescriptorCount;
+    *PinID = This->Filter.Descriptor->PinDescriptorsCount;
 
     /* increment pin descriptor count */
-    This->PinDescriptorCount++;
+    ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++;
 
 
     DPRINT("KsFilterCreatePinFactory done\n");
@@ -1724,7 +1726,7 @@ KsFilterGetChildPinCount(
 {
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
-    if (PinId >= This->PinDescriptorCount)
+    if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* index is out of bounds */
         return 0;
@@ -1745,7 +1747,7 @@ KsFilterGetFirstChildPin(
 {
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
-    if (PinId >= This->PinDescriptorCount)
+    if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
     {
         /* index is out of bounds */
         return NULL;