From 215e19921976ca34e1c34f0dfbcf37a8bbd8e069 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 2 Apr 2010 16:38:48 +0000 Subject: [PATCH] [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 svn path=/trunk/; revision=46685 --- reactos/drivers/ksfilter/ks/api.c | 4 +- reactos/drivers/ksfilter/ks/device.c | 3 +- reactos/drivers/ksfilter/ks/driver.c | 6 +- reactos/drivers/ksfilter/ks/filter.c | 101 ++- reactos/drivers/ksfilter/ks/filterfactory.c | 11 +- reactos/drivers/ksfilter/ks/kstypes.h | 2 +- reactos/drivers/ksfilter/ks/pin.c | 854 ++++++++++++++++++-- reactos/drivers/ksfilter/ks/priv.h | 21 + reactos/drivers/ksfilter/ks/property.c | 2 +- 9 files changed, 903 insertions(+), 101 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/api.c b/reactos/drivers/ksfilter/ks/api.c index ef83f9dbedf..8ec11860e02 100644 --- a/reactos/drivers/ksfilter/ks/api.c +++ b/reactos/drivers/ksfilter/ks/api.c @@ -1589,7 +1589,7 @@ KsAcquireControl( /* 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 @@ KsReleaseControl( /* sanity check */ ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); - KeReleaseMutex(&BasicHeader->ControlMutex, FALSE); + KeReleaseMutex(BasicHeader->ControlMutex, FALSE); } diff --git a/reactos/drivers/ksfilter/ks/device.c b/reactos/drivers/ksfilter/ks/device.c index 345689f49b8..cf1d3f73216 100644 --- a/reactos/drivers/ksfilter/ks/device.c +++ b/reactos/drivers/ksfilter/ks/device.c @@ -492,7 +492,7 @@ IKsDevice_Pnp( } case IRP_MN_QUERY_INTERFACE: { - Status = STATUS_SUCCESS; + Status = STATUS_UNSUCCESSFUL; /* check for pnp notification support */ if (Dispatch) { @@ -508,6 +508,7 @@ IKsDevice_Pnp( 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; diff --git a/reactos/drivers/ksfilter/ks/driver.c b/reactos/drivers/ksfilter/ks/driver.c index 409977d63d5..949e1285c54 100644 --- a/reactos/drivers/ksfilter/ks/driver.c +++ b/reactos/drivers/ksfilter/ks/driver.c @@ -39,10 +39,10 @@ KsGetDevice( { 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; } diff --git a/reactos/drivers/ksfilter/ks/filter.c b/reactos/drivers/ksfilter/ks/filter.c index 5d06ca2f49d..5c8fe7f463f 100644 --- a/reactos/drivers/ksfilter/ks/filter.c +++ b/reactos/drivers/ksfilter/ks/filter.c @@ -26,6 +26,7 @@ typedef struct ULONG PinDescriptorCount; PKSFILTERFACTORY Factory; PFILE_OBJECT FileObject; + KMUTEX ControlMutex; KMUTEX ProcessingMutex; @@ -34,7 +35,7 @@ typedef struct ULONG *PinInstanceCount; PKSPIN * FirstPin; - KSPROCESSPIN_INDEXENTRY ProcessPinIndex; + PKSPROCESSPIN_INDEXENTRY ProcessPinIndex; }IKsFilterImpl; @@ -294,18 +295,20 @@ IKsFilter_fnAddProcessPin( /* 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 @@ IKsFilter_fnRemoveProcessPin( 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++) + /* 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 (This->ProcessPinIndex.Pins[Index] == ProcessPin) + if (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--; + 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 @@ NTAPI 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 @@ KspHandleDataIntersection( Data, &Length); - if (Status == STATUS_SUCCESS) + if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW) { IoStatus->Information = Length; break; @@ -784,6 +802,7 @@ IKsFilter_CreateDescriptors( This->PinInstanceCount = NULL; This->PinDescriptors = NULL; This->PinDescriptorsEx = NULL; + This->ProcessPinIndex = NULL; This->PinDescriptorCount = 0; /* initialize topology descriptor */ @@ -842,8 +861,6 @@ IKsFilter_CreateDescriptors( return Status; } - - /* add new pin factory */ RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount); @@ -852,8 +869,19 @@ IKsFilter_CreateDescriptors( 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 @@ IKsFilter_DispatchCreatePin( 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 @@ IKsFilter_DispatchCreatePin( } /* release control mutex */ - KeReleaseMutex(&This->Header.ControlMutex, FALSE); + KeReleaseMutex(This->Header.ControlMutex, FALSE); if (Status != STATUS_PENDING) { @@ -1176,6 +1204,8 @@ KspCreateFilter( return STATUS_INSUFFICIENT_RESOURCES; } + DPRINT("KspCreateFilter Flags %lx\n", Factory->FilterDescriptor->Flags); + /* initialize pin create item */ CreateItem[0].Create = IKsFilter_DispatchCreatePin; CreateItem[0].Context = (PVOID)This; @@ -1202,7 +1232,8 @@ KspCreateFilter( 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 @@ KspCreateFilter( 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 @@ KsFilterCreatePinFactory ( 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; diff --git a/reactos/drivers/ksfilter/ks/filterfactory.c b/reactos/drivers/ksfilter/ks/filterfactory.c index a16b2900069..18b2147b679 100644 --- a/reactos/drivers/ksfilter/ks/filterfactory.c +++ b/reactos/drivers/ksfilter/ks/filterfactory.c @@ -21,6 +21,8 @@ typedef struct PFNKSFILTERFACTORYPOWER WakeCallback; LIST_ENTRY SymbolicLinkList; + KMUTEX ControlMutex; + }IKsFilterFactoryImpl; VOID @@ -225,17 +227,16 @@ IKsFilterFactory_fnInitialize( 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) { diff --git a/reactos/drivers/ksfilter/ks/kstypes.h b/reactos/drivers/ksfilter/ks/kstypes.h index 4bdc04c0bcb..d5c7588fda1 100644 --- a/reactos/drivers/ksfilter/ks/kstypes.h +++ b/reactos/drivers/ksfilter/ks/kstypes.h @@ -58,7 +58,7 @@ typedef struct { KSOBJECTTYPE Type; PKSDEVICE KsDevice; - KMUTEX ControlMutex; + PRKMUTEX ControlMutex; LIST_ENTRY EventList; KSPIN_LOCK EventListLock; union diff --git a/reactos/drivers/ksfilter/ks/pin.c b/reactos/drivers/ksfilter/ks/pin.c index 5d1ee77a6df..70e17e6607a 100644 --- a/reactos/drivers/ksfilter/ks/pin.c +++ b/reactos/drivers/ksfilter/ks/pin.c @@ -29,8 +29,9 @@ typedef struct LIST_ENTRY Entry; IKsPinVtbl *lpVtbl; - LONG ref; + + IKsFilter * Filter; KMUTEX ProcessingMutex; PFILE_OBJECT FileObject; @@ -50,8 +51,355 @@ typedef struct 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 IKsPin_fnQueryInterface( @@ -67,6 +415,7 @@ IKsPin_fnQueryInterface( _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } + DbgBreakPoint(); return STATUS_UNSUCCESSFUL; } @@ -270,6 +619,209 @@ static IKsPinVtbl vt_IKsPin = //============================================================== +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 @@ KsPinAttemptProcessing( IN BOOLEAN Asynchronous) { DPRINT("KsPinAttemptProcessing\n"); +DbgBreakPoint(); UNIMPLEMENTED } @@ -448,7 +1001,7 @@ KsPinGetParentFilter( } /* - @unimplemented + @implemented */ NTSTATUS NTAPI @@ -456,9 +1009,22 @@ NTAPI 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 @@ KsGetPinFromIrp( 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; - /* return object type */ - return (PKSPIN)ObjectHeader->ObjectType; + 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 Pin; } @@ -629,6 +1206,7 @@ KsPinGetLeadingEdgeStreamPointer( { UNIMPLEMENTED DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x\n", Pin, State); +DbgBreakPoint(); return NULL; } @@ -685,6 +1263,7 @@ KsStreamPointerUnlock( { UNIMPLEMENTED DPRINT("KsStreamPointerUnlock\n"); +DbgBreakPoint(); } /* @@ -700,7 +1279,7 @@ KsStreamPointerAdvanceOffsetsAndUnlock( IN BOOLEAN Eject) { DPRINT("KsStreamPointerAdvanceOffsets\n"); - +DbgBreakPoint(); UNIMPLEMENTED } @@ -718,7 +1297,7 @@ KsStreamPointerDelete( 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 @@ KsStreamPointerClone( { UNIMPLEMENTED DPRINT("KsStreamPointerClone\n"); +DbgBreakPoint(); return STATUS_NOT_IMPLEMENTED; } @@ -878,7 +1458,7 @@ KsPinGetFirstCloneStreamPointer( 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 @@ KsStreamPointerGetNextClone( 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 @@ KsStreamPointerGetNextClone( /* 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( @@ -941,7 +1579,23 @@ IKsPin_DispatchKsProperty( NULL, PropertyItemSize); - DPRINT("IKsPin_DispatchKsProperty PropertySetCount %lu Status %lu\n", PropertySetsCount, Status); + 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) { @@ -977,7 +1631,6 @@ IKsPin_DispatchDeviceIoControl( PIO_STACK_LOCATION IoStack; PKSIOBJECT_HEADER ObjectHeader; IKsPinImpl * This; - NTSTATUS Status = STATUS_SUCCESS; /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -998,38 +1651,17 @@ IKsPin_DispatchDeviceIoControl( return IKsPin_DispatchKsProperty(DeviceObject, Irp, This); } - - if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_WRITE_STREAM && IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_READ_STREAM) + 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; + /* handle ks properties */ + return IKsPin_DispatchKsStream(DeviceObject, Irp, This); } - /* 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; + UNIMPLEMENTED; + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; } NTSTATUS @@ -1057,7 +1689,7 @@ IKsPin_Close( 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 @@ IKsPin_Close( } } + /* release filter control mutex */ + KsFilterReleaseControl(&This->Pin); + return Status; } @@ -1104,11 +1739,80 @@ IKsPin_DispatchCreateClock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; + PKSPIN Pin; + NTSTATUS Status = STATUS_SUCCESS; + IKsPinImpl * This; + KSRESOLUTION Resolution; + PKSRESOLUTION pResolution = NULL; + PKSOBJECT_CREATE_ITEM CreateItem; - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + 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 @@ static KSDISPATCH_TABLE PinDispatchTable = 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 @@ KspCreatePin( 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 @@ KspCreatePin( 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 @@ KspCreatePin( } /* 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 @@ KspCreatePin( 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 @@ 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 */ + 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 @@ KspCreatePin( /* 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 @@ KspCreatePin( /* 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) { @@ -1323,6 +2057,8 @@ KspCreatePin( DPRINT("KspCreatePin DispatchCreate %lx\n", Status); } + + DPRINT("KspCreatePin Status %lx\n", Status); if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) diff --git a/reactos/drivers/ksfilter/ks/priv.h b/reactos/drivers/ksfilter/ks/priv.h index cc0b8f95fef..86ea4ebba64 100644 --- a/reactos/drivers/ksfilter/ks/priv.h +++ b/reactos/drivers/ksfilter/ks/priv.h @@ -35,3 +35,24 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\ 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)\ +} + + + + diff --git a/reactos/drivers/ksfilter/ks/property.c b/reactos/drivers/ksfilter/ks/property.c index a2e759ca07a..b1a17e3ed09 100644 --- a/reactos/drivers/ksfilter/ks/property.c +++ b/reactos/drivers/ksfilter/ks/property.c @@ -137,7 +137,7 @@ KspPropertyHandler( /* 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));