Author: janderwald
Date: Sat Apr 10 20:00:17 2010
New Revision: 46824

URL: http://svn.reactos.org/svn/reactos?rev=46824&view=rev
Log:
[KS]
- Implement dispatching of enable/disable event properties for filters/pins
- Add new pins to list of instantiated pins when a new pin is created
- Remove pin on close and decrement instance count. Fixes instantiating pin for 
2nd time
- Rewrite handling of pin property/method/events
- ks is now able to deliver signal statistics in XP SP3

Modified:
    trunk/reactos/drivers/ksfilter/ks/filter.c
    trunk/reactos/drivers/ksfilter/ks/ksfunc.h
    trunk/reactos/drivers/ksfilter/ks/methods.c
    trunk/reactos/drivers/ksfilter/ks/pin.c

Modified: trunk/reactos/drivers/ksfilter/ks/filter.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filter.c?rev=46824&r1=46823&r2=46824&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] Sat Apr 10 20:00:17 
2010
@@ -778,11 +778,15 @@
     /* get property from input buffer */
     Property = 
(PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
 
+    /* get filter instance */
+    FilterInstance = Filter->lpVtbl->GetStruct(Filter);
+
+
     /* sanity check */
     ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= 
sizeof(KSIDENTIFIER));
-
-    /* get filter instance */
-    FilterInstance = Filter->lpVtbl->GetStruct(Filter);
+    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);
@@ -794,7 +798,7 @@
         ULONG MethodItemSize = 0;
 
         /* check if the driver supports method sets */
-        if (FilterInstance->Descriptor->AutomationTable && 
FilterInstance->Descriptor->AutomationTable->MethodSetsCount)
+        if (FilterInstance->Descriptor->AutomationTable->MethodSetsCount)
         {
             SetCount = 
FilterInstance->Descriptor->AutomationTable->MethodSetsCount;
             MethodSet = 
FilterInstance->Descriptor->AutomationTable->MethodSets;
@@ -810,7 +814,7 @@
         ULONG PropertyItemSize = 0;
 
         /* check if the driver supports method sets */
-        if (FilterInstance->Descriptor->AutomationTable && 
FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
+        if (FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
         {
             SetCount = 
FilterInstance->Descriptor->AutomationTable->PropertySetsCount;
             PropertySet = 
FilterInstance->Descriptor->AutomationTable->PropertySets;
@@ -829,8 +833,23 @@
         ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_ENABLE_EVENT ||
                IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_DISABLE_EVENT);
 
-        Status = STATUS_NOT_FOUND;
-        UNIMPLEMENTED;
+        if (IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_ENABLE_EVENT)
+        {
+            /* call enable event handlers */
+            Status = KspEnableEvent(Irp,
+                                    
FilterInstance->Descriptor->AutomationTable->EventSetsCount,
+                                    
(PKSEVENT_SET)FilterInstance->Descriptor->AutomationTable->EventSets,
+                                    &This->Header.EventList,
+                                    KSEVENTS_SPINLOCK,
+                                    (PVOID)&This->Header.EventListLock,
+                                    NULL,
+                                    
FilterInstance->Descriptor->AutomationTable->EventItemSize);
+        }
+        else
+        {
+            /* disable event handler */
+            Status = KsDisableEvent(Irp, &This->Header.EventList, 
KSEVENTS_SPINLOCK, &This->Header.EventListLock);
+        }
     }
 
     RtlStringFromGUID(&Property->Set, &GuidString);
@@ -1041,14 +1060,14 @@
 }
 
 
-NTSTATUS
+VOID
 IKsFilter_AddPin(
-    IKsFilter * Filter,
+    PKSFILTER Filter,
     PKSPIN Pin)
 {
     PKSPIN NextPin, CurPin;
     PKSBASIC_HEADER BasicHeader;
-    IKsFilterImpl * This = (IKsFilterImpl*)Filter;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, 
IKsFilterImpl, Filter);
 
     /* sanity check */
     ASSERT(Pin->Id < This->PinDescriptorCount);
@@ -1057,7 +1076,8 @@
     {
         /* welcome first pin */
         This->FirstPin[Pin->Id] = Pin;
-        return STATUS_SUCCESS;
+        This->PinInstanceCount[Pin->Id]++;
+        return;
     }
 
     /* get first pin */
@@ -1079,8 +1099,58 @@
 
     /* store pin */
     BasicHeader->Next.Pin = Pin;
-
-    return STATUS_SUCCESS;
+}
+
+VOID
+IKsFilter_RemovePin(
+    PKSFILTER Filter,
+    PKSPIN Pin)
+{
+    PKSPIN NextPin, CurPin, LastPin;
+    PKSBASIC_HEADER BasicHeader;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, 
IKsFilterImpl, Filter);
+
+    /* sanity check */
+    ASSERT(Pin->Id < This->PinDescriptorCount);
+
+    /* get first pin */
+    CurPin = This->FirstPin[Pin->Id];
+
+    LastPin = NULL;
+    do
+    {
+        /* get next instantiated pin */
+        NextPin = KsPinGetNextSiblingPin(CurPin);
+
+        if (CurPin == Pin)
+        {
+            if (LastPin)
+            {
+                /* get basic header of last pin */
+                BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastPin - 
sizeof(KSBASIC_HEADER));
+
+                BasicHeader->Next.Pin = NextPin;
+            }
+            else
+            {
+                /* erase last pin */
+                This->FirstPin[Pin->Id] = NextPin;
+            }
+            /* decrement pin instance count */
+            This->PinInstanceCount[Pin->Id]--;
+            return;
+        }
+
+        if (!NextPin)
+            break;
+
+        LastPin = CurPin;
+        NextPin = CurPin;
+
+    }while(NextPin != NULL);
+
+    /* pin not found */
+    ASSERT(0);
 }
 
 
@@ -1129,12 +1199,6 @@
             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))
-            {
-                /* successfully created pin, increment pin instance count */
-                This->PinInstanceCount[Connect->PinId]++;
-            }
         }
         else
         {
@@ -1471,6 +1535,7 @@
     KeReleaseMutex(&This->ProcessingMutex, FALSE);
 }
 
+
 /*
     @implemented
 */

Modified: trunk/reactos/drivers/ksfilter/ks/ksfunc.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/ksfunc.h?rev=46824&r1=46823&r2=46824&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/ksfunc.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/ksfunc.h [iso-8859-1] Sat Apr 10 20:00:17 
2010
@@ -123,11 +123,6 @@
     IN KSPIN_DESCRIPTOR_EX* Descriptor);
 
 NTSTATUS
-IKsFilter_AddPin(
-    IKsFilter * Filter,
-    PKSPIN Pin);
-
-NTSTATUS
 KspAddCreateItemToList(
     OUT PLIST_ENTRY ListHead,
     IN ULONG ItemsCount,
@@ -165,3 +160,24 @@
     IN  PFNKSALLOCATOR Allocator OPTIONAL,
     IN  ULONG MethodItemSize OPTIONAL);
 
+VOID
+IKsFilter_AddPin(
+    PKSFILTER Filter,
+    PKSPIN Pin);
+
+VOID
+IKsFilter_RemovePin(
+    PKSFILTER Filter,
+    PKSPIN Pin);
+
+NTSTATUS
+KspEnableEvent(
+    IN  PIRP Irp,
+    IN  ULONG EventSetsCount,
+    IN  PKSEVENT_SET EventSet,
+    IN  OUT PLIST_ENTRY EventsList OPTIONAL,
+    IN  KSEVENTS_LOCKTYPE EventsFlags OPTIONAL,
+    IN  PVOID EventsLock OPTIONAL,
+    IN  PFNKSALLOCATOR Allocator OPTIONAL,
+    IN  ULONG EventItemSize OPTIONAL);
+

Modified: trunk/reactos/drivers/ksfilter/ks/methods.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/methods.c?rev=46824&r1=46823&r2=46824&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/methods.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/methods.c [iso-8859-1] Sat Apr 10 
20:00:17 2010
@@ -21,9 +21,6 @@
     OUT PKSMETHOD_SET * Set)
 {
     ULONG Index, ItemIndex;
-
-    /* TODO */
-    ASSERT((Method->Flags & KSMETHOD_TYPE_SETSUPPORT) == 0);
 
     for(Index = 0; Index < MethodSetCount; Index++)
     {

Modified: trunk/reactos/drivers/ksfilter/ks/pin.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/pin.c?rev=46824&r1=46823&r2=46824&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] Sat Apr 10 20:00:17 
2010
@@ -151,11 +151,14 @@
     /* get the object header */
     ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
 
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
     /* locate ks pin implemention from KSPIN offset */
     This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, 
IKsPinImpl, Pin);
 
-    /* acquire control mutex */
-    KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, 
KernelMode, FALSE, NULL);
+    /* sanity check */
+    ASSERT(This);
 
     Handle = (PHANDLE)Data;
 
@@ -226,10 +229,7 @@
         }
     }
 
-    /* release processing mutex */
-    KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
-
-    DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status);
+    DPRINT("IKsPin_PinMasterClock Status %lx\n", Status);
     return Status;
 }
 
@@ -1907,86 +1907,6 @@
     return Status;
 }
 
-
-NTSTATUS
-IKsPin_DispatchKsProperty(
-    PDEVICE_OBJECT DeviceObject,
-    PIRP Irp,
-    IKsPinImpl * This)
-{
-    NTSTATUS Status;
-    PKSPROPERTY Property;
-    PIO_STACK_LOCATION IoStack;
-    UNICODE_STRING GuidString;
-    ULONG PropertySetsCount = 0, PropertyItemSize = 0;
-    const KSPROPERTY_SET* PropertySets = NULL;
-
-    /* sanity check */
-    ASSERT(This->Pin.Descriptor);
-
-    /* get current irp stack */
-    IoStack = IoGetCurrentIrpStackLocation(Irp);
-
-
-    if (This->Pin.Descriptor->AutomationTable)
-    {
-        /* use available driver property sets */
-        PropertySetsCount = 
This->Pin.Descriptor->AutomationTable->PropertySetsCount;
-        PropertySets = This->Pin.Descriptor->AutomationTable->PropertySets;
-        PropertyItemSize = 
This->Pin.Descriptor->AutomationTable->PropertyItemSize;
-    }
-
-
-    /* try driver provided property sets */
-    Status = KspPropertyHandler(Irp,
-                                PropertySetsCount,
-                                PropertySets,
-                                NULL,
-                                PropertyItemSize);
-
-    if (Status != STATUS_NOT_FOUND)
-    {
-        /* property was handled by driver */
-        if (Status != STATUS_PENDING)
-        {
-            Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        }
-        return Status;
-    }
-
-    /* try our properties */
-    Status = KspPropertyHandler(Irp,
-                                sizeof(PinPropertySet) / 
sizeof(KSPROPERTY_SET),
-                                PinPropertySet,
-                                NULL,
-                                0);
-
-    if (Status != STATUS_NOT_FOUND)
-    {
-        /* property was handled by driver */
-        if (Status != STATUS_PENDING)
-        {
-            Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        }
-        return Status;
-    }
-
-    /* property was not handled */
-    Property = 
(PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
-
-    RtlStringFromGUID(&Property->Set, &GuidString);
-    DPRINT("IKsPin_DispatchKsProperty Unhandled property Set |%S| Id %u Flags 
%x\n", GuidString.Buffer, Property->Id, Property->Flags);
-    RtlFreeUnicodeString(&GuidString);
-
-    Irp->IoStatus.Status = STATUS_NOT_FOUND;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return STATUS_NOT_FOUND;
-
-}
-
 NTSTATUS
 NTAPI
 IKsPin_DispatchDeviceIoControl(
@@ -1996,6 +1916,10 @@
     PIO_STACK_LOCATION IoStack;
     PKSIOBJECT_HEADER ObjectHeader;
     IKsPinImpl * This;
+    NTSTATUS Status;
+    UNICODE_STRING GuidString;
+    PKSPROPERTY Property;
+    ULONG SetCount = 0;
 
     /* get current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -2010,23 +1934,93 @@
     /* locate ks pin implemention from KSPIN offset */
     This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, 
IKsPinImpl, Pin);
 
-    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
-    {
-        /* handle ks properties */
-        return IKsPin_DispatchKsProperty(DeviceObject, Irp, This);
-    }
-
-    if (IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_WRITE_STREAM ||
-        IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_READ_STREAM)
-    {
-        /* handle ks properties */
-        return IKsPin_DispatchKsStream(DeviceObject, Irp, This);
-    }
-
-    UNIMPLEMENTED;
-    Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return STATUS_NOT_IMPLEMENTED;
+    /* current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* get property from input buffer */
+    Property = 
(PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    /* sanity check */
+    ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= 
sizeof(KSIDENTIFIER));
+    ASSERT(This->Pin.Descriptor->AutomationTable);
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags 
%x\n", GuidString.Buffer, Property->Id, Property->Flags);
+    RtlFreeUnicodeString(&GuidString);
+
+
+    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD)
+    {
+        const KSMETHOD_SET *MethodSet = NULL;
+        ULONG MethodItemSize = 0;
+
+        /* check if the driver supports method sets */
+        if (This->Pin.Descriptor->AutomationTable->MethodSetsCount)
+        {
+            SetCount = This->Pin.Descriptor->AutomationTable->MethodSetsCount;
+            MethodSet = This->Pin.Descriptor->AutomationTable->MethodSets;
+            MethodItemSize = 
This->Pin.Descriptor->AutomationTable->MethodItemSize;
+        }
+
+        /* call method set handler */
+        Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, 
MethodItemSize);
+    }
+    else if (IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_PROPERTY)
+    {
+        const KSPROPERTY_SET *PropertySet = NULL;
+        ULONG PropertyItemSize = 0;
+
+        /* check if the driver supports method sets */
+        if (This->Pin.Descriptor->AutomationTable->PropertySetsCount)
+        {
+            SetCount = 
This->Pin.Descriptor->AutomationTable->PropertySetsCount;
+            PropertySet = This->Pin.Descriptor->AutomationTable->PropertySets;
+            PropertyItemSize = 
This->Pin.Descriptor->AutomationTable->PropertyItemSize;
+        }
+
+        /* needed for our property handlers */
+        KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This;
+
+        /* call property handler */
+        Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, 
PropertyItemSize);
+    }
+    else
+    {
+        /* sanity check */
+        ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_ENABLE_EVENT ||
+               IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_DISABLE_EVENT);
+
+        if (IoStack->Parameters.DeviceIoControl.IoControlCode == 
IOCTL_KS_ENABLE_EVENT)
+        {
+            /* call enable event handlers */
+            Status = KspEnableEvent(Irp,
+                                    
This->Pin.Descriptor->AutomationTable->EventSetsCount,
+                                    
(PKSEVENT_SET)This->Pin.Descriptor->AutomationTable->EventSets,
+                                    &This->BasicHeader.EventList,
+                                    KSEVENTS_SPINLOCK,
+                                    (PVOID)&This->BasicHeader.EventListLock,
+                                    NULL,
+                                    
This->Pin.Descriptor->AutomationTable->EventItemSize);
+        }
+        else
+        {
+            /* disable event handler */
+            Status = KsDisableEvent(Irp, &This->BasicHeader.EventList, 
KSEVENTS_SPINLOCK, &This->BasicHeader.EventListLock);
+        }
+    }
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x 
Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, 
Property->Flags, Status, Irp->IoStatus.Information);
+    RtlFreeUnicodeString(&GuidString);
+
+    if (Status != STATUS_PENDING)
+    {
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+
+    /* done */
+    return Status;
 }
 
 NTSTATUS
@@ -2053,9 +2047,6 @@
     /* locate ks pin implemention fro KSPIN offset */
     This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, 
IKsPinImpl, Pin);
 
-    /* acquire filter control mutex */
-    KsFilterAcquireControl(&This->Pin);
-
     if (This->Pin.Descriptor->Dispatch->Close)
     {
         /* call pin close routine */
@@ -2069,7 +2060,8 @@
             return Status;
         }
 
-        /* FIXME remove pin from filter pin list and decrement reference count 
*/
+        /* remove pin from filter pin list and decrement reference count */
+        IKsFilter_RemovePin(This->Filter->lpVtbl->GetStruct(This->Filter), 
&This->Pin);
 
         if (Status != STATUS_PENDING)
         {
@@ -2078,9 +2070,6 @@
             return Status;
         }
     }
-
-    /* release filter control mutex */
-    KsFilterReleaseControl(&This->Pin);
 
     return Status;
 }
@@ -2228,6 +2217,7 @@
     ULONG Index;
     ULONG FrameSize = 0;
     ULONG NumFrames = 0;
+    KSAUTOMATION_TABLE AutomationTable;
 
     /* sanity checks */
     ASSERT(Descriptor->Dispatch);
@@ -2314,6 +2304,8 @@
     This->BasicHeader.KsDevice = KsDevice;
     This->BasicHeader.Type = KsObjectTypePin;
     This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
+    InitializeListHead(&This->BasicHeader.EventList);
+    KeInitializeSpinLock(&This->BasicHeader.EventListLock);
 
     ASSERT(This->BasicHeader.Parent.KsFilter);
 
@@ -2350,11 +2342,43 @@
     /* initialize object bag */
     Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, NULL);
 
+    /* allocate pin descriptor */
+    This->Pin.Descriptor = AllocateItem(NonPagedPool, 
sizeof(KSPIN_DESCRIPTOR_EX));
+    if (!This->Pin.Descriptor)
+    {
+        /* not enough memory */
+        KsFreeObjectBag(This->Pin.Bag);
+        FreeItem(This);
+        FreeItem(CreateItem);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* copy pin descriptor */
+    RtlMoveMemory((PVOID)This->Pin.Descriptor, Descriptor, 
sizeof(KSPIN_DESCRIPTOR_EX));
+
+    /* initialize automation table */
+    RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE));
+
+    AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM);
+    AutomationTable.PropertySets = PinPropertySet;
+    AutomationTable.PropertySetsCount = sizeof(PinPropertySet) / 
sizeof(KSPROPERTY_SET);
+
+    /* merge in pin property sets */
+    Status = 
KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Pin.Descriptor->AutomationTable,
 (PKSAUTOMATION_TABLE)Descriptor->AutomationTable, &AutomationTable, 
This->Pin.Bag);
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* not enough memory */
+        KsFreeObjectBag(This->Pin.Bag);
+        FreeItem(This);
+        FreeItem(CreateItem);
+        return Status;
+    }
+
     /* get format */
     DataFormat = (PKSDATAFORMAT)(Connect + 1);
 
     /* initialize pin descriptor */
-    This->Pin.Descriptor = Descriptor;
     This->Pin.Context = NULL;
     This->Pin.Id = Connect->PinId;
     This->Pin.Communication = Descriptor->PinDescriptor.Communication;
@@ -2482,7 +2506,7 @@
     }
 
     /* FIXME add pin instance to filter instance */
-
+    IKsFilter_AddPin(Filter->lpVtbl->GetStruct(Filter), &This->Pin);
 
     if (Descriptor->Dispatch && Descriptor->Dispatch->SetDataFormat)
     {
@@ -2505,6 +2529,7 @@
     if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
     {
         /* failed to create pin, release resources */
+        IKsFilter_RemovePin(Filter->lpVtbl->GetStruct(Filter), &This->Pin);
         KsFreeObjectHeader((KSOBJECT_HEADER)This->ObjectHeader);
         KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
         FreeItem(This);


Reply via email to