- Implement KsGetFirstChild, KsGetNextSibling
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 15 Aug 2009 13:45:06 +0000 (13:45 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 15 Aug 2009 13:45:06 +0000 (13:45 +0000)
- Implement IKsFilter_fnAddProcessPin, IKsFilter_fnRemoveProcessPin
- Remove old code for attaching so that it works with KsGetFirstChild
- Implement attach of filter factories to the device header
- Unimplement a few functions which were wrong
- Implement KsDispatchSpecificProperty

svn path=/trunk/; revision=42699

reactos/drivers/ksfilter/ks/api.c
reactos/drivers/ksfilter/ks/filter.c
reactos/drivers/ksfilter/ks/filterfactory.c
reactos/drivers/ksfilter/ks/irp.c
reactos/drivers/ksfilter/ks/ksfunc.h
reactos/drivers/ksfilter/ks/ksiface.h
reactos/drivers/ksfilter/ks/kstypes.h
reactos/drivers/ksfilter/ks/pin.c
reactos/drivers/ksfilter/ks/property.c

index db6e1b8..df0f709 100644 (file)
@@ -1891,7 +1891,7 @@ KsGetBusEnumPnpDeviceObject(
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 PVOID
@@ -1899,12 +1899,19 @@ NTAPI
 KsGetFirstChild(
     IN PVOID Object)
 {
-    UNIMPLEMENTED
-    return NULL;
+    PKSBASIC_HEADER BasicHeader;
+
+    /* get the basic header */
+    BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
+
+    /* type has to be either a device or a filter factory */
+    ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory);
+
+    return (PVOID)BasicHeader->FirstChild.Filter;
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 PVOID
@@ -1912,8 +1919,15 @@ NTAPI
 KsGetNextSibling(
     IN PVOID Object)
 {
-    UNIMPLEMENTED
-    return NULL;
+    PKSBASIC_HEADER BasicHeader;
+
+    /* get the basic header */
+    BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
+
+    ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || 
+           BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
+
+    return (PVOID)BasicHeader->Next.Pin;
 }
 
 /*
index a1d9baf..1ad54d1 100644 (file)
@@ -32,6 +32,9 @@ typedef struct
     PFNKSFILTERPOWER Wake;
 
     ULONG *PinInstanceCount;
+    PKSPIN * FirstPin;
+    KSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+
 }IKsFilterImpl;
 
 const GUID IID_IKsControl = {0x28F54685L, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
@@ -284,8 +287,43 @@ IKsFilter_fnAddProcessPin(
     IKsFilter * iface,
     IN PKSPROCESSPIN ProcessPin)
 {
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    PKSPROCESSPIN *Pins;
+    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));
+
+    /* check if allocation succeeded */
+    if (Pins)
+    {
+        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.Count++;
+    }
+
+    /* release process mutex */
+    KeReleaseMutex(&This->ProcessingMutex, FALSE);
+
+    if (Pins)
+        return STATUS_SUCCESS;
+    else
+        return STATUS_INSUFFICIENT_RESOURCES;
+
 }
 
 NTSTATUS
@@ -294,8 +332,33 @@ IKsFilter_fnRemoveProcessPin(
     IKsFilter * iface,
     IN PKSPROCESSPIN ProcessPin)
 {
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    ULONG Index;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+
+    /* first acquire processing mutex */
+    KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
+
+    /* iterate through process pin index array and search for the process pin to be removed */
+    for(Index = 0; Index < This->ProcessPinIndex.Count; Index++)
+    {
+        if (This->ProcessPinIndex.Pins[Index] == ProcessPin)
+        {
+            /* found process pin */
+            if (Index + 1 < This->ProcessPinIndex.Count)
+            {
+                /* erase entry */
+                RtlMoveMemory(&This->ProcessPinIndex.Pins[Index], &This->ProcessPinIndex.Pins[Index+1], This->ProcessPinIndex.Count - Index - 1);
+            }
+            /* decrement process pin count */
+            This->ProcessPinIndex.Count--;
+        }
+    }
+
+    /* release process mutex */
+    KeReleaseMutex(&This->ProcessingMutex, FALSE);
+
+    /* done */
+    return STATUS_SUCCESS;
 }
 
 BOOL
@@ -437,8 +500,8 @@ IKsFilter_DispatchClose(
         /* complete irp */
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-        /* remove our instance from the filter factory */
-        This->FilterFactory->lpVtbl->RemoveFilterInstance(This->FilterFactory, Filter);
+        /* FIXME remove our instance from the filter factory */
+        ASSERT(0);
 
         /* free object header */
         KsFreeObjectHeader(This->ObjectHeader);
@@ -726,6 +789,15 @@ IKsFilter_CreateDescriptors(
             return STATUS_INSUFFICIENT_RESOURCES;
         }
 
+        /* allocate first pin array */
+        This->FirstPin = AllocateItem(NonPagedPool, sizeof(PKSPIN) * FilterDescriptor->PinDescriptorsCount);
+        if(!This->FirstPin)
+        {
+            FreeItem(This->PinDescriptors);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+
         /* allocate pin descriptor array */
         This->PinDescriptors = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount);
         if(!This->PinDescriptors)
@@ -852,6 +924,50 @@ IKsFilter_CopyFilterDescriptor(
     return STATUS_SUCCESS;
 }
 
+
+NTSTATUS
+IKsFilter_AddPin(
+    IKsFilter * Filter,
+    PKSPIN Pin)
+{
+    PKSPIN NextPin, CurPin;
+    PKSBASIC_HEADER BasicHeader;
+    IKsFilterImpl * This = (IKsFilterImpl*)Filter;
+
+    /* sanity check */
+    ASSERT(Pin->Id < This->PinDescriptorCount);
+
+    if (This->FirstPin[Pin->Id] == NULL)
+    {
+        /* welcome first pin */
+        This->FirstPin[Pin->Id] = Pin;
+        return STATUS_SUCCESS;
+    }
+
+    /* get first pin */
+    CurPin = This->FirstPin[Pin->Id];
+
+    do
+    {
+        /* get next instantiated pin */
+        NextPin = KsPinGetNextSiblingPin(CurPin);
+        if (!NextPin)
+            break;
+
+        NextPin = CurPin;
+
+    }while(NextPin != NULL);
+
+    /* get basic header */
+    BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)CurPin - sizeof(KSBASIC_HEADER));
+
+    /* store pin */
+    BasicHeader->Next.Pin = Pin;
+
+    return STATUS_SUCCESS;
+}
+
+
 NTSTATUS
 NTAPI
 IKsFilter_DispatchCreatePin(
@@ -921,6 +1037,54 @@ IKsFilter_DispatchCreateNode(
 }
 
 
+VOID
+IKsFilter_AttachFilterToFilterFactory(
+    IKsFilterImpl * This,
+    PKSFILTERFACTORY FilterFactory)
+{
+    PKSBASIC_HEADER BasicHeader;
+    PKSFILTER Filter;
+
+
+    /* get filter factory basic header */
+    BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
+
+    /* sanity check */
+    ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
+
+    if (BasicHeader->FirstChild.FilterFactory == NULL)
+    {
+        /* welcome first instantiated filter */
+        BasicHeader->FirstChild.Filter = &This->Filter;
+        return;
+    }
+
+    /* set to first entry */
+    Filter = BasicHeader->FirstChild.Filter;
+
+    do
+    {
+        /* get basic header */
+        BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER));
+        /* sanity check */
+        ASSERT(BasicHeader->Type == KsObjectTypeFilter);
+
+        if (BasicHeader->Next.Filter)
+        {
+            /* iterate to next filter factory */
+            Filter = BasicHeader->Next.Filter;
+        }
+        else
+        {
+            /* found last entry */
+            break;
+        }
+    }while(FilterFactory);
+
+    /* attach filter factory */
+    BasicHeader->Next.Filter = &This->Filter;
+}
+
 NTSTATUS
 NTAPI
 KspCreateFilter(
@@ -1016,10 +1180,6 @@ KspCreateFilter(
     InitializeListHead(&This->Header.EventList);
     KeInitializeSpinLock(&This->Header.EventListLock);
 
-
-
-
-
     /* allocate the stream descriptors */
     Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor);
     if (!NT_SUCCESS(Status))
@@ -1030,17 +1190,6 @@ KspCreateFilter(
         return Status;
     }
 
-    /* now add the filter instance to the filter factory */
-    Status = iface->lpVtbl->AddFilterInstance(iface, (IKsFilter*)&This->lpVtbl);
-
-    if (!NT_SUCCESS(Status))
-    {
-        /* failed to add filter */
-        FreeItem(This);
-        FreeItem(CreateItem);
-        return Status;
-    }
-
     /* does the filter have a filter dispatch */
     if (Factory->FilterDescriptor->Dispatch)
     {
@@ -1055,9 +1204,6 @@ KspCreateFilter(
                 /* driver failed to initialize */
                 DPRINT1("Driver: Status %x\n", Status);
 
-                /* remove filter instance from filter factory */
-                iface->lpVtbl->RemoveFilterInstance(iface, (IKsFilter*)&This->lpVtbl);
-
                 /* free filter instance */
                 FreeItem(This);
                 FreeItem(CreateItem);
@@ -1081,6 +1227,8 @@ KspCreateFilter(
     This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
     This->ObjectHeader->ObjectType = (PVOID)&This->Filter;
 
+    /* attach filter to filter factory */
+    IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory);
 
     /* completed initialization */
     return Status;
@@ -1205,6 +1353,7 @@ KsFilterCreatePinFactory (
     ULONG *PinInstanceCount;
     KSPIN_DESCRIPTOR_EX * PinDescriptorsEx;
     KSPIN_DESCRIPTOR * PinDescriptors;
+    PKSPIN *FirstPin;
     IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
 
     /* calculate existing count */
@@ -1234,6 +1383,17 @@ KsFilterCreatePinFactory (
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
+    /* allocate first pin array */
+    FirstPin = AllocateItem(NonPagedPool, sizeof(PKSPIN) * Count);
+    if (!FirstPin)
+    {
+        /* not enough memory */
+        FreeItem(PinDescriptorsEx);
+        FreeItem(PinInstanceCount);
+        FreeItem(PinDescriptors);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
     /* now copy all fields */
     if (Count > 1)
     {
@@ -1241,11 +1401,13 @@ KsFilterCreatePinFactory (
         RtlMoveMemory(PinDescriptorsEx, This->Filter.Descriptor->PinDescriptors, max(This->Filter.Descriptor->PinDescriptorSize, sizeof(KSPIN_DESCRIPTOR_EX)) * This->PinDescriptorCount);
         RtlMoveMemory(PinInstanceCount, This->PinInstanceCount, This->PinDescriptorCount * sizeof(ULONG));
         RtlMoveMemory(PinDescriptors, This->PinDescriptors, sizeof(KSPIN_DESCRIPTOR) * This->PinDescriptorCount);
+        RtlMoveMemory(FirstPin, This->FirstPin, sizeof(PKSPIN) * This->PinDescriptorCount);
 
         /* now free old descriptors */
         FreeItem(This->PinInstanceCount);
         FreeItem((PVOID)This->Filter.Descriptor->PinDescriptors);
         FreeItem(This->PinDescriptors);
+        FreeItem(This->FirstPin);
     }
 
     /* add new pin factory */
@@ -1258,6 +1420,7 @@ KsFilterCreatePinFactory (
 
     This->PinDescriptors = PinDescriptors;
     This->PinInstanceCount = PinInstanceCount;
+    This->FirstPin = FirstPin;
 
     /* store new pin id */
     *PinID = This->PinDescriptorCount;
@@ -1304,7 +1467,7 @@ KsFilterGetChildPinCount(
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 PKSPIN
@@ -1313,8 +1476,16 @@ KsFilterGetFirstChildPin(
     IN PKSFILTER Filter,
     IN ULONG PinId)
 {
-    UNIMPLEMENTED
-    return NULL;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
+
+    if (PinId >= This->PinDescriptorCount)
+    {
+        /* index is out of bounds */
+        return NULL;
+    }
+
+    /* return first pin index */
+    return This->FirstPin[PinId];
 }
 
 /*
index 39cce79..54e06b7 100644 (file)
@@ -21,17 +21,8 @@ typedef struct
     PFNKSFILTERFACTORYPOWER WakeCallback;
 
     LIST_ENTRY SymbolicLinkList;
-    LIST_ENTRY FilterInstanceList;
 }IKsFilterFactoryImpl;
 
-typedef struct
-{
-    LIST_ENTRY Entry;
-    IKsFilter *FilterInstance;
-}FILTER_INSTANCE_ENTRY, *PFILTER_INSTANCE_ENTRY;
-
-
-
 VOID
 NTAPI
 IKsFilterFactory_ItemFreeCb(
@@ -155,6 +146,47 @@ IKsFilterFactory_fnSetDeviceClassesState(
     return KspSetDeviceInterfacesState(&This->SymbolicLinkList, Enable);
 }
 
+VOID
+IKsFilterFactory_AttachFilterFactoryToDeviceHeader(
+    IKsFilterFactoryImpl * This,
+    PKSIDEVICE_HEADER DeviceHeader)
+{
+    PKSBASIC_HEADER BasicHeader;
+    PKSFILTERFACTORY FilterFactory;
+
+    if (DeviceHeader->BasicHeader.FirstChild.FilterFactory == NULL)
+    {
+        /* first attached filter factory */
+        DeviceHeader->BasicHeader.FirstChild.FilterFactory = &This->FilterFactory;
+        return;
+    }
+
+    /* set to first entry */
+    FilterFactory = DeviceHeader->BasicHeader.FirstChild.FilterFactory;
+
+    do
+    {
+        /* get basic header */
+        BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
+        /* sanity check */
+        ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
+
+        if (BasicHeader->Next.FilterFactory)
+        {
+            /* iterate to next filter factory */
+            FilterFactory = BasicHeader->Next.FilterFactory;
+        }
+        else
+        {
+            /* found last entry */
+            break;
+        }
+    }while(FilterFactory);
+
+    /* attach filter factory */
+    BasicHeader->Next.FilterFactory = &This->FilterFactory;
+}
+
 NTSTATUS
 NTAPI
 IKsFilterFactory_fnInitialize(
@@ -196,7 +228,6 @@ IKsFilterFactory_fnInitialize(
 
 
     InitializeListHead(&This->SymbolicLinkList);
-    InitializeListHead(&This->FilterInstanceList);
 
     /* initialize filter factory control mutex */
     KeInitializeMutex(&This->Header.ControlMutex, 0);
@@ -273,62 +304,13 @@ IKsFilterFactory_fnInitialize(
         }
     }
 
+    /* attach filterfactory to device header */
+    IKsFilterFactory_AttachFilterFactoryToDeviceHeader(This, DeviceExtension->DeviceHeader);
 
     /* return result */
     return Status;
 }
 
-NTSTATUS
-NTAPI
-IKsFilterFactory_fnAddFilterInstance(
-    IKsFilterFactory * iface,
-    IN IKsFilter *FilterInstance)
-{
-    PFILTER_INSTANCE_ENTRY Entry;
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
-
-    /* allocate filter instance entry */
-    Entry = AllocateItem(NonPagedPool, sizeof(FILTER_INSTANCE_ENTRY));
-    if (!Entry)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    /* initialize filter instance entry */
-    Entry->FilterInstance = FilterInstance;
-
-    /* insert entry */
-    InsertTailList(&This->FilterInstanceList, &Entry->Entry);
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-IKsFilterFactory_fnRemoveFilterInstance(
-    IKsFilterFactory * iface,
-    IN IKsFilter *FilterInstance)
-{
-    PFILTER_INSTANCE_ENTRY InstanceEntry;
-    PLIST_ENTRY Entry;
-    IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
-
-    /* point to first entry */
-    Entry = This->FilterInstanceList.Flink;
-
-    while(Entry != &This->FilterInstanceList)
-    {
-        InstanceEntry = (PFILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, FILTER_INSTANCE_ENTRY, Entry);
-        if (InstanceEntry->FilterInstance == FilterInstance)
-        {
-            /* found entry */
-            RemoveEntryList(&InstanceEntry->Entry);
-            FreeItem(InstanceEntry);
-            return STATUS_SUCCESS;
-        }
-    }
-
-    /* entry not in list! */
-    return STATUS_NOT_FOUND;
-}
-
 static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl =
 {
     IKsFilterFactory_fnQueryInterface,
@@ -336,9 +318,7 @@ static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl =
     IKsFilterFactory_fnRelease,
     IKsFilterFactory_fnGetStruct,
     IKsFilterFactory_fnSetDeviceClassesState,
-    IKsFilterFactory_fnInitialize,
-    IKsFilterFactory_fnAddFilterInstance,
-    IKsFilterFactory_fnRemoveFilterInstance
+    IKsFilterFactory_fnInitialize
 };
 
 
index cf33e16..e4b48ce 100644 (file)
@@ -114,20 +114,6 @@ KsDispatchSetSecurity(
     return Status;
 }
 
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsDispatchSpecificProperty(
-    IN  PIRP Irp,
-    IN  PFNKSHANDLER Handler)
-{
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
-}
-
 /*
     @unimplemented
 */
index 86b62b6..4e2e33c 100644 (file)
@@ -117,13 +117,18 @@ KspCopyCreateRequest(
 NTSTATUS
 KspCreatePin(
     IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp, 
+    IN PIRP Irp,
     IN PKSDEVICE KsDevice,
-    IN IKsFilterFactory * FilterFactory, 
+    IN IKsFilterFactory * FilterFactory,
     IN IKsFilter* Filter,
     IN PKSPIN_CONNECT Connect,
     IN KSPIN_DESCRIPTOR_EX* Descriptor);
 
+NTSTATUS
+IKsFilter_AddPin(
+    IKsFilter * Filter,
+    PKSPIN Pin);
+
 NTSTATUS
 KspAddCreateItemToList(
     OUT PLIST_ENTRY ListHead,
index a69848e..8954528 100644 (file)
@@ -237,12 +237,6 @@ DECLARE_INTERFACE_(IKsFilterFactory, IUnknown)
         IN PFNKSFILTERFACTORYPOWER  SleepCallback OPTIONAL,
         IN PFNKSFILTERFACTORYPOWER  WakeCallback OPTIONAL,
         OUT PKSFILTERFACTORY  *FilterFactory OPTIONAL)PURE;
-
-    STDMETHOD_(NTSTATUS, AddFilterInstance)(THIS_
-        IN IKsFilter *Filter)PURE;
-
-    STDMETHOD_(NTSTATUS, RemoveFilterInstance)(THIS_
-        IN IKsFilter *Filter)PURE;
 };
 
 
index 473c64a..22c1a22 100644 (file)
@@ -62,13 +62,26 @@ typedef struct
     KMUTEX ControlMutex;
     LIST_ENTRY EventList;
     KSPIN_LOCK EventListLock;
-
     union
     {
         PKSDEVICE KsDevice;
         PKSFILTERFACTORY KsFilterFactory;
         PKSFILTER KsFilter;
     }Parent;
+
+    union
+    {
+        PKSFILTERFACTORY FilterFactory;
+        PKSFILTER Filter;
+        PKSPIN Pin;
+    }Next;
+
+    union
+    {
+        PKSFILTERFACTORY FilterFactory;
+        PKSFILTER Filter;
+    }FirstChild;
+
 }KSBASIC_HEADER, *PKSBASIC_HEADER;
 
 typedef struct
index 7bb32b3..760c55f 100644 (file)
@@ -25,6 +25,7 @@ typedef struct
     KSBASIC_HEADER BasicHeader;
     KSPIN Pin;
     PKSIOBJECT_HEADER ObjectHeader;
+    KSPROCESSPIN ProcessPin;
     LIST_ENTRY Entry;
 
     IKsPinVtbl *lpVtbl;
@@ -370,17 +371,15 @@ KsPinGetConnectedFilterInterface(
 }
 
 /*
-    @implemented
+    @unimplemented
 */
 PDEVICE_OBJECT
 NTAPI
 KsPinGetConnectedPinDeviceObject(
     IN PKSPIN Pin)
 {
-    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
-
-    /* return related file object */
-    return IoGetRelatedDeviceObject(This->FileObject);
+    UNIMPLEMENTED
+    return NULL;
 }
 
 /*
@@ -391,11 +390,12 @@ NTAPI
 KsPinGetConnectedPinFileObject(
     IN PKSPIN Pin)
 {
+    UNIMPLEMENTED
     return NULL;
 }
 
 /*
-    @implemented
+    @unimplemented
 */
 NTSTATUS
 NTAPI
@@ -404,14 +404,8 @@ KsPinGetConnectedPinInterface(
     IN const GUID*  InterfaceId,
     OUT PVOID*  Interface)
 {
-    IKsPin * KsPin;
-    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
-
-    /* get pin interface */
-    KsPin = (IKsPin*)&This->lpVtbl;
-
-    /* query pin interface for the requested interface */
-    return KsPin->lpVtbl->QueryInterface(KsPin, InterfaceId, Interface);
+    UNIMPLEMENTED
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 /*
@@ -1186,6 +1180,30 @@ KspCreatePin(
     This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;
     This->ObjectHeader->ObjectType = (PVOID)&This->Pin;
 
+    /* setup process pin */
+    This->ProcessPin.Pin = &This->Pin;
+    This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)This->LeadingEdgeStreamPointer;
+
+    if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process)
+    {
+        /* the pin is part of filter-centric processing filter
+         * add process pin to filter
+         */
+
+        Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin);
+        if (!NT_SUCCESS(Status))
+        {
+            /* failed to add process pin */
+            KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
+            KsFreeObjectHeader(&This->ObjectHeader);
+
+            /* return failure code */
+            return Status;
+        }
+    }
+
+    /* FIXME add pin instance to filter instance */
+
     /* does the driver have a pin dispatch */
     if (Descriptor->Dispatch && Descriptor->Dispatch->Create)
     {
@@ -1204,7 +1222,5 @@ KspCreatePin(
         return Status;
     }
 
-    /* FIXME add pin instance to filter instance */
-
     return Status;
 }
index cc56bbb..6b3ee96 100644 (file)
@@ -200,7 +200,7 @@ FindFastPropertyHandler(
 
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 BOOLEAN
@@ -280,3 +280,22 @@ KsFastPropertyHandler(
     }
     return FALSE;
 }
+
+/*
+    @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsDispatchSpecificProperty(
+    IN  PIRP Irp,
+    IN  PFNKSHANDLER Handler)
+{
+    PIO_STACK_LOCATION IoStack;
+
+    /* get current irp stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    return Handler(Irp, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, Irp->UserBuffer);
+}
+