[ros-diffs] [janderwald] 46685: [KS] - Instantiated pins use as the control mutex the mutex from the filter - Fix KsAcquireControl & KsReleaseControl - Fix handling of IRP_MN_QUERY_INTERFACE - Filter centric ks filters expect an array of KSPROCESSPIN_INDEXENTRY. Allocate array when intializing filter / new pin factory is added - Store result of pin intersection handler when result is STATUS_BUFFER_OVERFLOW - Implement setting / retrieving of master clock - Implement setting / retrieving pin state - Partly implement setting pin data format - Implement IKsReferenceClock interface - Implement KsPinGetReferenceClockInterface - Add sanity checks to KsGetPinFromIrp - Partly implement handling IOCTL_KS_READ_STREAM / IOCTL_KS_WRITE_STREAM - Supply filter property sets when an IOCTL_KS_PROPERTY request arrives - Release again filter mutex when closing the pin - Implement allocating a clock - Tuner pin fails with STATUS_IO_DEVICE_ERROR when set to KSSTATE_RUN, needs more investigation

janderwald at svn.reactos.org janderwald at svn.reactos.org
Fri Apr 2 18:38:48 CEST 2010


Author: janderwald
Date: Fri Apr  2 18:38:48 2010
New Revision: 46685

URL: http://svn.reactos.org/svn/reactos?rev=46685&view=rev
Log:
[KS]
- Instantiated pins use as the control mutex the mutex from the filter
- Fix KsAcquireControl & KsReleaseControl
- Fix handling of IRP_MN_QUERY_INTERFACE
- Filter centric ks filters expect an array of KSPROCESSPIN_INDEXENTRY. Allocate array when intializing filter / new pin factory is added
- Store result of pin intersection handler when result is STATUS_BUFFER_OVERFLOW
- Implement setting / retrieving of master clock
- Implement setting / retrieving pin state
- Partly implement setting pin data format
- Implement IKsReferenceClock interface
- Implement KsPinGetReferenceClockInterface
- Add sanity checks to KsGetPinFromIrp
- Partly implement handling IOCTL_KS_READ_STREAM / IOCTL_KS_WRITE_STREAM
- Supply filter property sets when an IOCTL_KS_PROPERTY request arrives
- Release again filter mutex when closing the pin
- Implement allocating a clock
- Tuner pin fails with STATUS_IO_DEVICE_ERROR when set to KSSTATE_RUN, needs more investigation

Modified:
    trunk/reactos/drivers/ksfilter/ks/api.c
    trunk/reactos/drivers/ksfilter/ks/device.c
    trunk/reactos/drivers/ksfilter/ks/driver.c
    trunk/reactos/drivers/ksfilter/ks/filter.c
    trunk/reactos/drivers/ksfilter/ks/filterfactory.c
    trunk/reactos/drivers/ksfilter/ks/kstypes.h
    trunk/reactos/drivers/ksfilter/ks/pin.c
    trunk/reactos/drivers/ksfilter/ks/priv.h
    trunk/reactos/drivers/ksfilter/ks/property.c

Modified: trunk/reactos/drivers/ksfilter/ks/api.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/api.c?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -1589,7 +1589,7 @@
     /* sanity check */
     ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
 
-    KeWaitForSingleObject(&BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL);
+    KeWaitForSingleObject(BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL);
 
 }
 
@@ -1606,7 +1606,7 @@
     /* sanity check */
     ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
 
-    KeReleaseMutex(&BasicHeader->ControlMutex, FALSE);
+    KeReleaseMutex(BasicHeader->ControlMutex, FALSE);
 }
 
 

Modified: trunk/reactos/drivers/ksfilter/ks/device.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/device.c?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -492,7 +492,7 @@
         }
         case IRP_MN_QUERY_INTERFACE:
         {
-            Status = STATUS_SUCCESS;
+            Status = STATUS_UNSUCCESSFUL;
             /* check for pnp notification support */
             if (Dispatch)
             {
@@ -508,6 +508,7 @@
             if (NT_SUCCESS(Status))
             {
                 /* driver supports a private interface */
+                DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
                 Irp->IoStatus.Status = Status;
                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
                 return Status;

Modified: trunk/reactos/drivers/ksfilter/ks/driver.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/driver.c?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/driver.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/driver.c [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -39,10 +39,10 @@
 {
     PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
 
-    DPRINT("KsGetDevice %p BasicHeader %p Type %x\n", Object, BasicHeader, BasicHeader->Type);
-
-    ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == BasicHeader->Type);
+    ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
     ASSERT(BasicHeader->KsDevice);
+    ASSERT(BasicHeader->KsDevice->Started);
+    ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject);
 
     return BasicHeader->KsDevice;
 }

Modified: trunk/reactos/drivers/ksfilter/ks/filter.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filter.c?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -26,6 +26,7 @@
     ULONG PinDescriptorCount;
     PKSFILTERFACTORY Factory;
     PFILE_OBJECT FileObject;
+    KMUTEX ControlMutex;
     KMUTEX ProcessingMutex;
 
 
@@ -34,7 +35,7 @@
 
     ULONG *PinInstanceCount;
     PKSPIN * FirstPin;
-    KSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+    PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
 
 }IKsFilterImpl;
 
@@ -294,18 +295,20 @@
     /* first acquire processing mutex */
     KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
 
-    /* edit process pin descriptor */
-    Status = _KsEdit(This->Filter.Bag,
-                     (PVOID*)&This->ProcessPinIndex.Pins, 
-                     (This->ProcessPinIndex.Count + 1) * sizeof(PKSPROCESSPIN),
-                     (This->ProcessPinIndex.Count) * sizeof(PKSPROCESSPIN),
+    /* sanity check */
+    ASSERT(This->PinDescriptorCount > 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),
                      0);
 
     if (NT_SUCCESS(Status))
     {
-        /* add new process pin */
-        This->ProcessPinIndex.Pins[This->ProcessPinIndex.Count] = ProcessPin;
-        This->ProcessPinIndex.Count++;
+        /* store process pin */
+        This->ProcessPinIndex[ProcessPin->Pin->Id].Pins[This->ProcessPinIndex[ProcessPin->Pin->Id].Count] = ProcessPin;
+        This->ProcessPinIndex[ProcessPin->Pin->Id].Count++;
     }
 
     /* release process mutex */
@@ -321,25 +324,39 @@
     IN PKSPROCESSPIN ProcessPin)
 {
     ULONG Index;
+    ULONG Count;
+    PKSPROCESSPIN * Pins;
+
     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--;
-        }
+    /* sanity check */
+    ASSERT(ProcessPin->Pin);
+    ASSERT(ProcessPin->Pin->Id);
+
+    Count = This->ProcessPinIndex[ProcessPin->Pin->Id].Count;
+    Pins =  This->ProcessPinIndex[ProcessPin->Pin->Id].Pins;
+
+    /* search for current process pin */
+    for(Index = 0; Index < Count; Index++)
+    {
+        if (Pins[Index] == ProcessPin)
+        {
+            RtlMoveMemory(&Pins[Index], &Pins[Index + 1], (Count - (Index + 1)) * sizeof(PKSPROCESSPIN));
+            break;
+        }
+
+    }
+
+    /* decrement pin count */
+    This->ProcessPinIndex[ProcessPin->Pin->Id].Count--;
+
+    if (!This->ProcessPinIndex[ProcessPin->Pin->Id].Count)
+    {
+        /* clear entry object bag will delete it */
+       This->ProcessPinIndex[ProcessPin->Pin->Id].Pins = NULL;
     }
 
     /* release process mutex */
@@ -394,8 +411,9 @@
 IKsFilter_fnGetProcessDispatch(
     IKsFilter * iface)
 {
-    UNIMPLEMENTED
-    return NULL;
+    IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
+
+    return This->ProcessPinIndex;
 }
 
 static IKsFilterVtbl vt_IKsFilter =
@@ -619,7 +637,7 @@
                                                                      Data,
                                                                      &Length);
 
-        if (Status == STATUS_SUCCESS)
+        if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW)
         {
             IoStatus->Information = Length;
             break;
@@ -784,6 +802,7 @@
     This->PinInstanceCount = NULL;
     This->PinDescriptors = NULL;
     This->PinDescriptorsEx = NULL;
+    This->ProcessPinIndex = NULL;
     This->PinDescriptorCount = 0;
 
     /* initialize topology descriptor */
@@ -842,8 +861,6 @@
             return Status;
         }
 
-
-
         /* add new pin factory */
         RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount);
 
@@ -852,8 +869,19 @@
             RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
         }
 
+        /* allocate process pin index */
+        Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount,
+                         sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, 0);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
+            return Status;
+        }
+
         /* store new pin descriptor count */
         This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
+
     }
 
     if (FilterDescriptor->NodeDescriptorsCount)
@@ -991,7 +1019,7 @@
     ASSERT(This->Header.Type == KsObjectTypeFilter);
 
     /* acquire control mutex */
-    KeWaitForSingleObject(&This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
+    KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
 
     /* now validate the connect request */
     Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect);
@@ -1029,7 +1057,7 @@
     }
 
     /* release control mutex */
-    KeReleaseMutex(&This->Header.ControlMutex, FALSE);
+    KeReleaseMutex(This->Header.ControlMutex, FALSE);
 
     if (Status != STATUS_PENDING)
     {
@@ -1175,6 +1203,8 @@
         DPRINT("KspCreateFilter OutOfMemory\n");
         return STATUS_INSUFFICIENT_RESOURCES;
     }
+
+    DPRINT("KspCreateFilter Flags %lx\n", Factory->FilterDescriptor->Flags);
 
     /* initialize pin create item */
     CreateItem[0].Create = IKsFilter_DispatchCreatePin;
@@ -1202,7 +1232,8 @@
     This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
     This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface);
     This->Header.Type = KsObjectTypeFilter;
-    KeInitializeMutex(&This->Header.ControlMutex, 0);
+    This->Header.ControlMutex = &This->ControlMutex;
+    KeInitializeMutex(This->Header.ControlMutex, 0);
     InitializeListHead(&This->Header.EventList);
     KeInitializeSpinLock(&This->Header.EventListLock);
 
@@ -1224,8 +1255,9 @@
         if (Factory->FilterDescriptor->Dispatch->Create)
         {
             /* now let driver initialize the filter instance */
-            DPRINT("Before instantiating filter Filter %p This %p KSBASIC_HEADER %u\n", &This->Filter, This, sizeof(KSBASIC_HEADER));
+
             ASSERT(This->Header.KsDevice);
+            ASSERT(This->Header.KsDevice->Started);
             Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp);
 
             if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
@@ -1432,6 +1464,17 @@
     RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
     RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount], &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR));
 
+
+    /* allocate process pin index */
+    Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count,
+                     sizeof(KSPROCESSPIN_INDEXENTRY) * This->PinDescriptorCount, 0);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status);
+        return Status;
+    }
+
     /* store new pin id */
     *PinID = This->PinDescriptorCount;
 

Modified: trunk/reactos/drivers/ksfilter/ks/filterfactory.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filterfactory.c?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/filterfactory.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/filterfactory.c [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -21,6 +21,8 @@
     PFNKSFILTERFACTORYPOWER WakeCallback;
 
     LIST_ENTRY SymbolicLinkList;
+    KMUTEX ControlMutex;
+
 }IKsFilterFactoryImpl;
 
 VOID
@@ -225,16 +227,15 @@
     This->Header.Parent.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
     This->DeviceHeader = DeviceExtension->DeviceHeader;
 
+    /* initialize filter factory control mutex */
+    This->Header.ControlMutex = &This->ControlMutex;
+    KeInitializeMutex(This->Header.ControlMutex, 0);
+
     /* unused fields */
-    KeInitializeMutex(&This->Header.ControlMutex, 0);
     InitializeListHead(&This->Header.EventList);
     KeInitializeSpinLock(&This->Header.EventListLock);
 
-
     InitializeListHead(&This->SymbolicLinkList);
-
-    /* initialize filter factory control mutex */
-    KeInitializeMutex(&This->Header.ControlMutex, 0);
 
     /* does the device use a reference string */
     if (RefString || !Descriptor->ReferenceGuid)

Modified: trunk/reactos/drivers/ksfilter/ks/kstypes.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/kstypes.h?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/kstypes.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/kstypes.h [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -58,7 +58,7 @@
 {
     KSOBJECTTYPE Type;
     PKSDEVICE KsDevice;
-    KMUTEX ControlMutex;
+    PRKMUTEX ControlMutex;
     LIST_ENTRY EventList;
     KSPIN_LOCK EventListLock;
     union

Modified: trunk/reactos/drivers/ksfilter/ks/pin.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/pin.c?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -29,8 +29,9 @@
     LIST_ENTRY Entry;
 
     IKsPinVtbl *lpVtbl;
-
     LONG ref;
+
+    IKsFilter * Filter;
     KMUTEX ProcessingMutex;
     PFILE_OBJECT FileObject;
 
@@ -50,7 +51,354 @@
     PFNKSPINFRAMERETURN  FrameReturn;
     PFNKSPINIRPCOMPLETION  IrpCompletion;
 
+    KSCLOCK_FUNCTIONTABLE ClockTable;
+    PFILE_OBJECT ClockFileObject;
+    IKsReferenceClockVtbl * lpVtblReferenceClock;
+    PKSDEFAULTCLOCK DefaultClock;
+
 }IKsPinImpl;
+
+NTSTATUS NTAPI IKsPin_PinStatePropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinStreamAllocator(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinMasterClock(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI IKsPin_PinPipeId(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+
+
+
+DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet, IKsPin_PinStatePropertyHandler, IKsPin_PinDataFormatPropertyHandler, IKsPin_PinAllocatorFramingPropertyHandler);
+DEFINE_KSPROPERTY_STREAMSET(PinStreamSet, IKsPin_PinStreamAllocator, IKsPin_PinMasterClock, IKsPin_PinPipeId);
+
+//TODO
+// KSPROPSETID_Connection
+//    KSPROPERTY_CONNECTION_ACQUIREORDERING
+// KSPROPSETID_StreamInterface
+//     KSPROPERTY_STREAMINTERFACE_HEADERSIZE
+
+KSPROPERTY_SET PinPropertySet[] =
+{
+    {
+        &KSPROPSETID_Connection,
+        sizeof(PinConnectionSet) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&PinConnectionSet,
+        0,
+        NULL
+    },
+    {
+        &KSPROPSETID_Stream,
+        sizeof(PinStreamSet) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&PinStreamSet,
+        0,
+        NULL
+    }
+};
+
+const GUID KSPROPSETID_Connection              = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+const GUID KSPROPSETID_Stream                  = {0x65aaba60L, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
+const GUID KSPROPSETID_Clock                   = {0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+
+NTSTATUS
+NTAPI
+IKsPin_PinStreamAllocator(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    UNIMPLEMENTED
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinMasterClock(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PHANDLE Handle;
+    PFILE_OBJECT FileObject;
+    KPROCESSOR_MODE Mode;
+    KSPROPERTY Property;
+    ULONG BytesReturned;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("IKsPin_PinMasterClock\n");
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* 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);
+
+    Handle = (PHANDLE)Data;
+
+    if (Request->Flags & KSPROPERTY_TYPE_GET)
+    {
+        if (This->Pin.Descriptor->PinDescriptor.Communication != KSPIN_COMMUNICATION_NONE &&
+            This->Pin.Descriptor->Dispatch &&
+            (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK))
+        {
+            *Handle = NULL;
+            Status = STATUS_SUCCESS;
+        }
+        else
+        {
+            /* no clock available */
+            Status = STATUS_UNSUCCESSFUL;
+        }
+    }
+    else if (Request->Flags & KSPROPERTY_TYPE_SET)
+    {
+        if (This->Pin.ClientState != KSSTATE_STOP)
+        {
+            /* can only set in stopped state */
+            Status = STATUS_INVALID_DEVICE_STATE;
+        }
+        else
+        {
+            if (*Handle)
+            {
+                Mode = ExGetPreviousMode();
+
+                Status = ObReferenceObjectByHandle(*Handle, SYNCHRONIZE | DIRECTORY_QUERY, IoFileObjectType, Mode, (PVOID*)&FileObject, NULL);
+
+                DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status);
+                if (NT_SUCCESS(Status))
+                {
+                    Property.Set = KSPROPSETID_Clock;
+                    Property.Id = KSPROPERTY_CLOCK_FUNCTIONTABLE;
+                    Property.Flags = KSPROPERTY_TYPE_GET;
+
+                    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE), &BytesReturned);
+
+                    DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status);
+
+                    if (NT_SUCCESS(Status))
+                    {
+                        This->ClockFileObject = FileObject;
+                    }
+                    else
+                    {
+                        ObDereferenceObject(FileObject);
+                    }
+                }
+            }
+            else
+            {
+                /* zeroing clock handle */
+                RtlZeroMemory(&This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE));
+                Status = STATUS_SUCCESS;
+                if (This->ClockFileObject)
+                {
+                    FileObject = This->ClockFileObject;
+                    This->ClockFileObject = NULL;
+
+                    ObDereferenceObject(This->ClockFileObject);
+                }
+            }
+        }
+    }
+
+    /* release processing mutex */
+    KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+    DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status);
+    return Status;
+}
+
+
+
+NTSTATUS
+NTAPI
+IKsPin_PinPipeId(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    UNIMPLEMENTED
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+NTAPI
+IKsPin_PinStatePropertyHandler(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+    NTSTATUS Status = STATUS_SUCCESS;
+    KSSTATE OldState;
+    PKSSTATE NewState;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("IKsPin_PinStatePropertyHandler\n");
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* 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);
+
+    /* grab state */
+    NewState = (PKSSTATE)Data;
+
+    if (Request->Flags & KSPROPERTY_TYPE_GET)
+    {
+        *NewState = This->Pin.DeviceState;
+        Irp->IoStatus.Information = sizeof(KSSTATE);
+    }
+    else if (Request->Flags & KSPROPERTY_TYPE_SET)
+    {
+        if (This->Pin.Descriptor->Dispatch->SetDeviceState)
+        {
+            /* backup old state */
+            OldState = This->Pin.ClientState;
+
+            /* set new state */
+            This->Pin.ClientState  = *NewState;
+
+            /* check if it supported */
+            Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState);
+
+            DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n", *NewState, Status);
+
+            if (!NT_SUCCESS(Status))
+            {
+                /* revert to old state */
+                This->Pin.ClientState = OldState;
+                DbgBreakPoint();
+            }
+            else
+            {
+                /* update device state */
+                This->Pin.DeviceState = *NewState;
+            }
+        }
+        else
+        {
+            /* just set new state */
+            This->Pin.DeviceState = *NewState;
+            This->Pin.ClientState = *NewState;
+        }
+    }
+
+    /* release processing mutex */
+    KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+    DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinAllocatorFramingPropertyHandler(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    UNIMPLEMENTED
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_PinDataFormatPropertyHandler(
+    IN PIRP Irp,
+    IN PKSPROPERTY Request,
+    IN OUT PVOID Data)
+{
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("IKsPin_PinDataFormatPropertyHandler\n");
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* 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);
+
+    if (Request->Flags & KSPROPERTY_TYPE_GET)
+    {
+        if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < This->Pin.ConnectionFormat->FormatSize)
+        {
+            /* buffer too small */
+            Irp->IoStatus.Information = This->Pin.ConnectionFormat->FormatSize;
+            Status = STATUS_BUFFER_TOO_SMALL;
+        }
+        else
+        {
+            /* copy format */
+            RtlMoveMemory(Data, This->Pin.ConnectionFormat, This->Pin.ConnectionFormat->FormatSize);
+        }
+    }
+    else if (Request->Flags & KSPROPERTY_TYPE_SET)
+    {
+        /* set format */
+        if (This->Pin.Descriptor->Flags & KSPIN_FLAG_FIXED_FORMAT)
+        {
+            /* format cannot be changed */
+            Status = STATUS_INVALID_DEVICE_REQUEST;
+        }
+        else
+        {
+            /* FIXME check if the format is supported */
+            Status = _KsEdit(This->Pin.Bag, (PVOID*)&This->Pin.ConnectionFormat, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This->Pin.ConnectionFormat->FormatSize, 0);
+
+            if (NT_SUCCESS(Status))
+            {
+                /* store new format */
+                RtlMoveMemory(This->Pin.ConnectionFormat, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+            }
+        }
+    }
+
+    /* release processing mutex */
+    KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
+
+    DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status);
+
+    return Status;
+}
 
 NTSTATUS
 NTAPI
@@ -67,6 +415,7 @@
         _InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
+    DbgBreakPoint();
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -270,6 +619,209 @@
 
 //==============================================================
 
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnQueryInterface(
+    IKsReferenceClock * iface,
+    IN  REFIID refiid,
+    OUT PVOID* Output)
+{
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    return IKsPin_fnQueryInterface((IKsPin*)&This->lpVtbl, refiid, Output);
+}
+
+ULONG
+NTAPI
+IKsReferenceClock_fnAddRef(
+    IKsReferenceClock * iface)
+{
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    return IKsPin_fnAddRef((IKsPin*)&This->lpVtbl);
+}
+
+ULONG
+NTAPI
+IKsReferenceClock_fnRelease(
+    IKsReferenceClock * iface)
+{
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    return IKsPin_fnRelease((IKsPin*)&This->lpVtbl);
+}
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetTime(
+    IKsReferenceClock * iface)
+{
+    LONGLONG Result;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    if (!This->ClockFileObject || !This->ClockTable.GetTime)
+    {
+        Result = 0;
+    }
+    else
+    {
+        Result = This->ClockTable.GetTime(This->ClockFileObject);
+    }
+
+    return Result;
+}
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetPhysicalTime(
+    IKsReferenceClock * iface)
+{
+    LONGLONG Result;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    if (!This->ClockFileObject || !This->ClockTable.GetPhysicalTime)
+    {
+        Result = 0;
+    }
+    else
+    {
+        Result = This->ClockTable.GetPhysicalTime(This->ClockFileObject);
+    }
+
+    return Result;
+}
+
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetCorrelatedTime(
+    IKsReferenceClock * iface,
+    OUT PLONGLONG SystemTime)
+{
+    LONGLONG Result;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedTime)
+    {
+        Result = 0;
+    }
+    else
+    {
+        Result = This->ClockTable.GetCorrelatedTime(This->ClockFileObject, SystemTime);
+    }
+
+    return Result;
+}
+
+
+LONGLONG
+NTAPI
+IKsReferenceClock_fnGetCorrelatedPhysicalTime(
+    IKsReferenceClock * iface,
+    OUT PLONGLONG SystemTime)
+{
+    LONGLONG Result;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedPhysicalTime)
+    {
+        Result = 0;
+    }
+    else
+    {
+        Result = This->ClockTable.GetCorrelatedPhysicalTime(This->ClockFileObject, SystemTime);
+    }
+
+    return Result;
+}
+
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnGetResolution(
+    IKsReferenceClock * iface,
+    OUT PKSRESOLUTION Resolution)
+{
+    KSPROPERTY Property;
+    ULONG BytesReturned;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    DPRINT1("IKsReferenceClock_fnGetResolution\n");
+
+    if (!This->ClockFileObject)
+    {
+        Resolution->Error = 0;
+        Resolution->Granularity = 1;
+        DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n");
+        return STATUS_SUCCESS;
+    }
+
+
+    if (!This->ClockFileObject)
+        return STATUS_DEVICE_NOT_READY;
+
+
+    Property.Set = KSPROPSETID_Clock;
+    Property.Id = KSPROPERTY_CLOCK_RESOLUTION;
+    Property.Flags = KSPROPERTY_TYPE_GET;
+
+    return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), Resolution, sizeof(KSRESOLUTION), &BytesReturned);
+
+}
+
+NTSTATUS
+NTAPI
+IKsReferenceClock_fnGetState(
+    IKsReferenceClock * iface,
+     OUT PKSSTATE State)
+{
+    KSPROPERTY Property;
+    ULONG BytesReturned;
+
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock);
+
+    DPRINT1("IKsReferenceClock_fnGetState\n");
+
+    if (!This->ClockFileObject)
+    {
+        *State = This->Pin.ClientState;
+        DPRINT1("IKsReferenceClock_fnGetState Using HACK\n");
+        return STATUS_SUCCESS;
+    }
+
+
+    if (!This->ClockFileObject)
+        return STATUS_DEVICE_NOT_READY;
+
+
+    Property.Set = KSPROPSETID_Clock;
+    Property.Id = KSPROPERTY_CLOCK_RESOLUTION;
+    Property.Flags = KSPROPERTY_TYPE_GET;
+
+    return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), State, sizeof(KSSTATE), &BytesReturned);
+}
+
+static IKsReferenceClockVtbl vt_ReferenceClock =
+{
+    IKsReferenceClock_fnQueryInterface,
+    IKsReferenceClock_fnAddRef,
+    IKsReferenceClock_fnRelease,
+    IKsReferenceClock_fnGetTime,
+    IKsReferenceClock_fnGetPhysicalTime,
+    IKsReferenceClock_fnGetCorrelatedTime,
+    IKsReferenceClock_fnGetCorrelatedPhysicalTime,
+    IKsReferenceClock_fnGetResolution,
+    IKsReferenceClock_fnGetState
+};
+
+
+//==============================================================
+
+
 /*
     @implemented
 */
@@ -340,6 +892,7 @@
     IN BOOLEAN  Asynchronous)
 {
     DPRINT("KsPinAttemptProcessing\n");
+DbgBreakPoint();
     UNIMPLEMENTED
 }
 
@@ -448,7 +1001,7 @@
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 NTSTATUS
 NTAPI
@@ -456,9 +1009,22 @@
     IN PKSPIN  Pin,
     OUT PIKSREFERENCECLOCK*  Interface)
 {
-    UNIMPLEMENTED
-    DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p\n", Pin, Interface);
-    return STATUS_UNSUCCESSFUL;
+    NTSTATUS Status = STATUS_DEVICE_NOT_READY;
+    IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+    if (This->ClockFileObject)
+    {
+        /* clock is available */
+        *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
+        Status = STATUS_SUCCESS;
+    }
+//HACK
+        *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock;
+        Status = STATUS_SUCCESS;
+
+    DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status);
+
+    return Status;
 }
 
 /*
@@ -547,15 +1113,26 @@
     IN PIRP Irp)
 {
     PKSIOBJECT_HEADER ObjectHeader;
+    PKSPIN Pin;
+    PKSBASIC_HEADER Header;
     PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
 
     DPRINT("KsGetPinFromIrp\n");
 
     /* get object header */
     ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    if (!ObjectHeader)
+        return NULL;
+
+    Pin = (PKSPIN)ObjectHeader->ObjectType;
+    Header = (PKSBASIC_HEADER)((ULONG_PTR)Pin - sizeof(KSBASIC_HEADER));
+
+    /* sanity check */
+    ASSERT(Header->Type == KsObjectTypePin);
+
     /* return object type */
-    return (PKSPIN)ObjectHeader->ObjectType;
-
+    return Pin;
 }
 
 
@@ -629,6 +1206,7 @@
 {
     UNIMPLEMENTED
     DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x\n", Pin, State);
+DbgBreakPoint();
     return NULL;
 }
 
@@ -685,6 +1263,7 @@
 {
     UNIMPLEMENTED
     DPRINT("KsStreamPointerUnlock\n");
+DbgBreakPoint();
 }
 
 /*
@@ -700,7 +1279,7 @@
     IN BOOLEAN Eject)
 {
     DPRINT("KsStreamPointerAdvanceOffsets\n");
-
+DbgBreakPoint();
     UNIMPLEMENTED
 }
 
@@ -718,7 +1297,7 @@
     PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
 
     DPRINT("KsStreamPointerDelete\n");
-
+DbgBreakPoint();
     This = (IKsPinImpl*)CONTAINING_RECORD(Pointer->StreamPointer.Pin, IKsPinImpl, Pin);
 
     /* point to first stream pointer */
@@ -766,6 +1345,7 @@
 {
     UNIMPLEMENTED
     DPRINT("KsStreamPointerClone\n");
+DbgBreakPoint();
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -878,7 +1458,7 @@
     IKsPinImpl * This;
 
     DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin);
-
+DbgBreakPoint();
     This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
     /* return first cloned stream pointer */
     return &This->ClonedStreamPointer->StreamPointer;
@@ -896,7 +1476,7 @@
     PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer;
 
     DPRINT("KsStreamPointerGetNextClone\n");
-
+DbgBreakPoint();
     /* is there a another cloned stream pointer */
     if (!Pointer->Next)
         return NULL;
@@ -904,6 +1484,64 @@
     /* return next stream pointer */
     return &Pointer->Next->StreamPointer;
 }
+NTSTATUS
+IKsPin_DispatchKsStream(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp,
+    IKsPinImpl * This)
+{
+    PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
+    PKSFILTER Filter;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    DPRINT("IKsPin_DispatchKsStream\n");
+
+    /* FIXME handle reset states */
+    ASSERT(This->Pin.ResetState == KSRESET_END);
+
+    /* mark irp as pending */
+    IoMarkIrpPending(Irp);
+
+    /* add irp to cancelable queue */
+    KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */);
+
+    if (This->Pin.Descriptor->Dispatch->Process)
+    {
+        /* it is a pin centric avstream */
+        ASSERT(0);
+        //Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin);
+        /* TODO */
+    }
+    else
+    {
+        /* filter-centric avstream */
+        ASSERT(This->Filter);
+
+        ProcessPinIndex = This->Filter->lpVtbl->GetProcessDispatch(This->Filter);
+        Filter = This->Filter->lpVtbl->GetStruct(This->Filter);
+
+        ASSERT(ProcessPinIndex);
+        ASSERT(Filter);
+        ASSERT(Filter->Descriptor);
+        ASSERT(Filter->Descriptor->Dispatch);
+
+        if (!Filter->Descriptor->Dispatch->Process)
+        {
+            /* invalid device request */
+            DPRINT("Filter Centric Processing No Process Routine\n");
+            Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_UNSUCCESSFUL;
+        }
+
+        Status = Filter->Descriptor->Dispatch->Process(Filter, ProcessPinIndex);
+
+        DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status);
+    }
+
+    return Status;
+}
+
 
 NTSTATUS
 IKsPin_DispatchKsProperty(
@@ -940,8 +1578,6 @@
                                 PropertySets,
                                 NULL,
                                 PropertyItemSize);
-
-    DPRINT("IKsPin_DispatchKsProperty PropertySetCount %lu Status %lu\n", PropertySetsCount, Status);
 
     if (Status != STATUS_NOT_FOUND)
     {
@@ -954,6 +1590,24 @@
         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;
 
@@ -971,6 +1625,48 @@
 NTSTATUS
 NTAPI
 IKsPin_DispatchDeviceIoControl(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack;
+    PKSIOBJECT_HEADER ObjectHeader;
+    IKsPinImpl * This;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->FsContext2);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* 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;
+}
+
+NTSTATUS
+NTAPI
+IKsPin_Close(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
@@ -989,75 +1685,11 @@
     /* get the object header */
     ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
 
-    /* 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)
-    {
-        UNIMPLEMENTED;
-        Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-        Irp->IoStatus.Information = 0;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        return STATUS_NOT_IMPLEMENTED;
-    }
-
-    /* mark irp as pending */
-    IoMarkIrpPending(Irp);
-
-    /* add irp to cancelable queue */
-    KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */);
-
-    if (This->Pin.Descriptor->Dispatch->Process)
-    {
-        /* it is a pin centric avstream */
-        Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin);
-
-        /* TODO */
-    }
-    else
-    {
-        /* TODO
-         * filter-centric avstream 
-         */
-        UNIMPLEMENTED
-    }
-
-    return Status;
-}
-
-NTSTATUS
-NTAPI
-IKsPin_Close(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp)
-{
-    PIO_STACK_LOCATION IoStack;
-    PKSIOBJECT_HEADER ObjectHeader;
-    IKsPinImpl * This;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    /* get current irp stack */
-    IoStack = IoGetCurrentIrpStackLocation(Irp);
-
-    /* sanity check */
-    ASSERT(IoStack->FileObject);
-    ASSERT(IoStack->FileObject->FsContext2);
-
-    /* get the object header */
-    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
-
     /* locate ks pin implemention fro KSPIN offset */
     This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
 
     /* acquire filter control mutex */
-    KsFilterAcquireControl(This->BasicHeader.Parent.KsFilter);
+    KsFilterAcquireControl(&This->Pin);
 
     if (This->Pin.Descriptor->Dispatch->Close)
     {
@@ -1082,6 +1714,9 @@
         }
     }
 
+    /* release filter control mutex */
+    KsFilterReleaseControl(&This->Pin);
+
     return Status;
 }
 
@@ -1104,11 +1739,80 @@
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-
-    Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+    PKSPIN Pin;
+    NTSTATUS Status = STATUS_SUCCESS;
+    IKsPinImpl * This;
+    KSRESOLUTION Resolution;
+    PKSRESOLUTION pResolution = NULL;
+    PKSOBJECT_CREATE_ITEM CreateItem;
+
+    DPRINT("IKsPin_DispatchCreateClock\n");
+
+    /* get the create item */
+    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+
+    /* sanity check */
+    ASSERT(CreateItem);
+
+    /* get the pin object */
+    Pin = (PKSPIN)CreateItem->Context;
+
+    /* sanity check */
+    ASSERT(Pin);
+
+    /* locate ks pin implemention fro KSPIN offset */
+    This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+    /* sanity check */
+    ASSERT(This->BasicHeader.Type == KsObjectTypePin);
+    ASSERT(This->BasicHeader.ControlMutex);
+
+    /* acquire control mutex */
+    KsAcquireControl(Pin);
+
+    if ((This->Pin.Descriptor->PinDescriptor.Communication != KSPIN_COMMUNICATION_NONE &&
+        This->Pin.Descriptor->Dispatch) ||
+        (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK))
+    {
+        if (!This->DefaultClock)
+        {
+            if (This->Pin.Descriptor->Dispatch && This->Pin.Descriptor->Dispatch->Clock)
+            {
+                if (This->Pin.Descriptor->Dispatch->Clock->Resolution)
+                {
+                   This->Pin.Descriptor->Dispatch->Clock->Resolution(&This->Pin, &Resolution);
+                   pResolution = &Resolution;
+                }
+
+                Status = KsAllocateDefaultClockEx(&This->DefaultClock, 
+                                                  (PVOID)&This->Pin,
+                                                  (PFNKSSETTIMER)This->Pin.Descriptor->Dispatch->Clock->SetTimer,
+                                                  (PFNKSCANCELTIMER)This->Pin.Descriptor->Dispatch->Clock->CancelTimer,
+                                                  (PFNKSCORRELATEDTIME)This->Pin.Descriptor->Dispatch->Clock->CorrelatedTime,
+                                                  pResolution,
+                                                  0);
+            }
+            else
+            {
+                Status = KsAllocateDefaultClockEx(&This->DefaultClock, (PVOID)&This->Pin, NULL, NULL, NULL, NULL, 0);
+            }
+        }
+
+        if (NT_SUCCESS(Status))
+        {
+            Status = KsCreateDefaultClock(Irp, This->DefaultClock);
+        }
+    }
+
+    DPRINT("IKsPin_DispatchCreateClock %lx\n", Status);
+
+    /* release control mutex */
+    KsReleaseControl(Pin);
+
+    /* done */
+    Irp->IoStatus.Status = Status;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return STATUS_NOT_IMPLEMENTED;
+    return Status;
 }
 
 NTSTATUS
@@ -1141,7 +1845,7 @@
 NTSTATUS
 KspCreatePin(
     IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp, 
+    IN PIRP Irp,
     IN PKSDEVICE KsDevice,
     IN IKsFilterFactory * FilterFactory,
     IN IKsFilter* Filter,
@@ -1155,11 +1859,15 @@
     PKSOBJECT_CREATE_ITEM CreateItem;
     NTSTATUS Status;
     PKSDATAFORMAT DataFormat;
+    PKSBASIC_HEADER BasicHeader;
 
     /* sanity checks */
     ASSERT(Descriptor->Dispatch);
 
-    DPRINT("KspCreatePin\n");
+    DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect->PinId, Descriptor->Flags);
+
+//Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY
+//Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING
 
     /* get current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -1192,14 +1900,24 @@
     This->BasicHeader.KsDevice = KsDevice;
     This->BasicHeader.Type = KsObjectTypePin;
     This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
-    KeInitializeMutex(&This->BasicHeader.ControlMutex, 0);
+
+    ASSERT(This->BasicHeader.Parent.KsFilter);
+
+    BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)This->BasicHeader.Parent.KsFilter - sizeof(KSBASIC_HEADER));
+
+    This->BasicHeader.ControlMutex = BasicHeader->ControlMutex;
+    ASSERT(This->BasicHeader.ControlMutex);
+
+
     InitializeListHead(&This->BasicHeader.EventList);
     KeInitializeSpinLock(&This->BasicHeader.EventListLock);
 
     /* initialize pin */
     This->lpVtbl = &vt_IKsPin;
+    This->lpVtblReferenceClock = &vt_ReferenceClock;
     This->ref = 1;
     This->FileObject = IoStack->FileObject;
+    This->Filter = Filter;
     KeInitializeMutex(&This->ProcessingMutex, 0);
     InitializeListHead(&This->IrpList);
     KeInitializeSpinLock(&This->IrpListLock);
@@ -1216,12 +1934,12 @@
     }
 
     /* initialize object bag */
-    Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, &This->BasicHeader.ControlMutex); /* is using control mutex right? */
+    Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, NULL);
 
     /* get format */
     DataFormat = (PKSDATAFORMAT)(Connect + 1);
 
-    /* initialize ks pin descriptor */
+    /* initialize pin descriptor */
     This->Pin.Descriptor = Descriptor;
     This->Pin.Context = NULL;
     This->Pin.Id = Connect->PinId;
@@ -1253,19 +1971,19 @@
     This->Pin.ClientState = KSSTATE_STOP;
 
     /* intialize allocator create item */
-    CreateItem[0].Context = (PVOID)This;
+    CreateItem[0].Context = (PVOID)&This->Pin;
     CreateItem[0].Create = IKsPin_DispatchCreateAllocator;
     CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP;
     RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Allocator);
 
     /* intialize clock create item */
-    CreateItem[1].Context = (PVOID)This;
+    CreateItem[1].Context = (PVOID)&This->Pin;
     CreateItem[1].Create = IKsPin_DispatchCreateClock;
     CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP;
     RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Clock);
 
     /* intialize topology node create item */
-    CreateItem[2].Context = (PVOID)This;
+    CreateItem[2].Context = (PVOID)&This->Pin;
     CreateItem[2].Create = IKsPin_DispatchCreateNode;
     CreateItem[2].Flags = KSCREATE_ITEM_FREEONSTOP;
     RtlInitUnicodeString(&CreateItem[2].ObjectClass, KSSTRING_TopologyNode);
@@ -1289,15 +2007,21 @@
     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
          */
+        This->ProcessPin.BytesAvailable = 0;
+        This->ProcessPin.BytesUsed = 0;
+        This->ProcessPin.CopySource = NULL;
+        This->ProcessPin.Data = NULL;
+        This->ProcessPin.DelegateBranch = NULL;
+        This->ProcessPin.Flags = 0;
+        This->ProcessPin.InPlaceCounterpart = NULL;
+        This->ProcessPin.Pin = &This->Pin;
+        This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)This->LeadingEdgeStreamPointer;
+        This->ProcessPin.Terminate = FALSE;
 
         Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin);
         DPRINT("KspCreatePin AddProcessPin %lx\n", Status);
@@ -1307,7 +2031,8 @@
             /* failed to add process pin */
             KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
             KsFreeObjectHeader(&This->ObjectHeader);
-
+            FreeItem(This);
+            FreeItem(CreateItem);
             /* return failure code */
             return Status;
         }
@@ -1315,6 +2040,15 @@
 
     /* FIXME add pin instance to filter instance */
 
+
+    if (Descriptor->Dispatch && Descriptor->Dispatch->SetDataFormat)
+    {
+        Status = Descriptor->Dispatch->SetDataFormat(&This->Pin, NULL, NULL, This->Pin.ConnectionFormat, NULL);
+        DPRINT("KspCreatePin SetDataFormat %lx\n", Status);
+        DbgBreakPoint();
+    }
+
+
     /* does the driver have a pin dispatch */
     if (Descriptor->Dispatch && Descriptor->Dispatch->Create)
     {
@@ -1322,6 +2056,8 @@
         Status = Descriptor->Dispatch->Create(&This->Pin, Irp);
         DPRINT("KspCreatePin DispatchCreate %lx\n", Status);
     }
+
+
 
     DPRINT("KspCreatePin Status %lx\n", Status);
 

Modified: trunk/reactos/drivers/ksfilter/ks/priv.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/priv.h?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/priv.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/priv.h [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -35,3 +35,24 @@
     DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral),\
     DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\
 }
+
+#define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\
+    PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\
+DEFINE_KSPROPERTY_TABLE(PinSet) {\
+    DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\
+    DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\
+    DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(PropAllocatorFraming)\
+}
+
+
+#define DEFINE_KSPROPERTY_STREAMSET(PinSet,\
+    PropStreamAllocator, PropMasterClock, PropPipeId)\
+DEFINE_KSPROPERTY_TABLE(PinSet) {\
+    DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(PropStreamAllocator, PropStreamAllocator),\
+    DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(PropMasterClock, PropMasterClock),\
+    DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(PropPipeId, PropPipeId)\
+}
+
+
+
+

Modified: trunk/reactos/drivers/ksfilter/ks/property.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/property.c?rev=46685&r1=46684&r2=46685&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/property.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/property.c [iso-8859-1] Fri Apr  2 18:38:48 2010
@@ -137,7 +137,7 @@
     /* get input property request */
     Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
 
-    DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
+//    DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
 
     /* sanity check */
     ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM));




More information about the Ros-diffs mailing list