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?r... ============================================================================== --- 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.... ============================================================================== --- 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.... ============================================================================== --- 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.... ============================================================================== --- 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/filterf... ============================================================================== --- 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... ============================================================================== --- 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?r... ============================================================================== --- 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?... ============================================================================== --- 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/propert... ============================================================================== --- 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));