- 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
This commit is contained in:
Johannes Anderwald 2010-04-02 16:38:48 +00:00
parent b4a44e7a78
commit 215e199219
9 changed files with 903 additions and 101 deletions

View file

@ -1589,7 +1589,7 @@ KsAcquireControl(
/* sanity check */ /* sanity check */
ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); 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 */ /* sanity check */
ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
KeReleaseMutex(&BasicHeader->ControlMutex, FALSE); KeReleaseMutex(BasicHeader->ControlMutex, FALSE);
} }

View file

@ -492,7 +492,7 @@ IKsDevice_Pnp(
} }
case IRP_MN_QUERY_INTERFACE: case IRP_MN_QUERY_INTERFACE:
{ {
Status = STATUS_SUCCESS; Status = STATUS_UNSUCCESSFUL;
/* check for pnp notification support */ /* check for pnp notification support */
if (Dispatch) if (Dispatch)
{ {
@ -508,6 +508,7 @@ IKsDevice_Pnp(
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* driver supports a private interface */ /* driver supports a private interface */
DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;

View file

@ -39,10 +39,10 @@ KsGetDevice(
{ {
PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); 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 == KsObjectTypePin);
ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == BasicHeader->Type);
ASSERT(BasicHeader->KsDevice); ASSERT(BasicHeader->KsDevice);
ASSERT(BasicHeader->KsDevice->Started);
ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject);
return BasicHeader->KsDevice; return BasicHeader->KsDevice;
} }

View file

@ -26,6 +26,7 @@ typedef struct
ULONG PinDescriptorCount; ULONG PinDescriptorCount;
PKSFILTERFACTORY Factory; PKSFILTERFACTORY Factory;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
KMUTEX ControlMutex;
KMUTEX ProcessingMutex; KMUTEX ProcessingMutex;
@ -34,7 +35,7 @@ typedef struct
ULONG *PinInstanceCount; ULONG *PinInstanceCount;
PKSPIN * FirstPin; PKSPIN * FirstPin;
KSPROCESSPIN_INDEXENTRY ProcessPinIndex; PKSPROCESSPIN_INDEXENTRY ProcessPinIndex;
}IKsFilterImpl; }IKsFilterImpl;
@ -294,18 +295,20 @@ IKsFilter_fnAddProcessPin(
/* first acquire processing mutex */ /* first acquire processing mutex */
KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
/* edit process pin descriptor */ /* sanity check */
Status = _KsEdit(This->Filter.Bag, ASSERT(This->PinDescriptorCount > ProcessPin->Pin->Id);
(PVOID*)&This->ProcessPinIndex.Pins,
(This->ProcessPinIndex.Count + 1) * sizeof(PKSPROCESSPIN), /* allocate new process pin array */
(This->ProcessPinIndex.Count) * sizeof(PKSPROCESSPIN), Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins,
(This->PinDescriptorCount + 1) * sizeof(PKSPROCESSPIN),
This->PinDescriptorCount * sizeof(PKSPROCESSPIN),
0); 0);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* add new process pin */ /* store process pin */
This->ProcessPinIndex.Pins[This->ProcessPinIndex.Count] = ProcessPin; This->ProcessPinIndex[ProcessPin->Pin->Id].Pins[This->ProcessPinIndex[ProcessPin->Pin->Id].Count] = ProcessPin;
This->ProcessPinIndex.Count++; This->ProcessPinIndex[ProcessPin->Pin->Id].Count++;
} }
/* release process mutex */ /* release process mutex */
@ -321,25 +324,39 @@ IKsFilter_fnRemoveProcessPin(
IN PKSPROCESSPIN ProcessPin) IN PKSPROCESSPIN ProcessPin)
{ {
ULONG Index; ULONG Index;
ULONG Count;
PKSPROCESSPIN * Pins;
IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
/* first acquire processing mutex */ /* first acquire processing mutex */
KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
/* iterate through process pin index array and search for the process pin to be removed */ /* sanity check */
for(Index = 0; Index < This->ProcessPinIndex.Count; Index++) 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 */ RtlMoveMemory(&Pins[Index], &Pins[Index + 1], (Count - (Index + 1)) * sizeof(PKSPROCESSPIN));
if (Index + 1 < This->ProcessPinIndex.Count) break;
{
/* erase entry */
RtlMoveMemory(&This->ProcessPinIndex.Pins[Index], &This->ProcessPinIndex.Pins[Index+1], This->ProcessPinIndex.Count - Index - 1);
}
/* decrement process pin count */
This->ProcessPinIndex.Count--;
} }
}
/* 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 */ /* release process mutex */
@ -394,8 +411,9 @@ NTAPI
IKsFilter_fnGetProcessDispatch( IKsFilter_fnGetProcessDispatch(
IKsFilter * iface) IKsFilter * iface)
{ {
UNIMPLEMENTED IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl);
return NULL;
return This->ProcessPinIndex;
} }
static IKsFilterVtbl vt_IKsFilter = static IKsFilterVtbl vt_IKsFilter =
@ -619,7 +637,7 @@ KspHandleDataIntersection(
Data, Data,
&Length); &Length);
if (Status == STATUS_SUCCESS) if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW)
{ {
IoStatus->Information = Length; IoStatus->Information = Length;
break; break;
@ -784,6 +802,7 @@ IKsFilter_CreateDescriptors(
This->PinInstanceCount = NULL; This->PinInstanceCount = NULL;
This->PinDescriptors = NULL; This->PinDescriptors = NULL;
This->PinDescriptorsEx = NULL; This->PinDescriptorsEx = NULL;
This->ProcessPinIndex = NULL;
This->PinDescriptorCount = 0; This->PinDescriptorCount = 0;
/* initialize topology descriptor */ /* initialize topology descriptor */
@ -842,8 +861,6 @@ IKsFilter_CreateDescriptors(
return Status; return Status;
} }
/* add new pin factory */ /* add new pin factory */
RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount); 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)); 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 */ /* store new pin descriptor count */
This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount; This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount;
} }
if (FilterDescriptor->NodeDescriptorsCount) if (FilterDescriptor->NodeDescriptorsCount)
@ -991,7 +1019,7 @@ IKsFilter_DispatchCreatePin(
ASSERT(This->Header.Type == KsObjectTypeFilter); ASSERT(This->Header.Type == KsObjectTypeFilter);
/* acquire control mutex */ /* acquire control mutex */
KeWaitForSingleObject(&This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
/* now validate the connect request */ /* now validate the connect request */
Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect); Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect);
@ -1029,7 +1057,7 @@ IKsFilter_DispatchCreatePin(
} }
/* release control mutex */ /* release control mutex */
KeReleaseMutex(&This->Header.ControlMutex, FALSE); KeReleaseMutex(This->Header.ControlMutex, FALSE);
if (Status != STATUS_PENDING) if (Status != STATUS_PENDING)
{ {
@ -1176,6 +1204,8 @@ KspCreateFilter(
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
DPRINT("KspCreateFilter Flags %lx\n", Factory->FilterDescriptor->Flags);
/* initialize pin create item */ /* initialize pin create item */
CreateItem[0].Create = IKsFilter_DispatchCreatePin; CreateItem[0].Create = IKsFilter_DispatchCreatePin;
CreateItem[0].Context = (PVOID)This; CreateItem[0].Context = (PVOID)This;
@ -1202,7 +1232,8 @@ KspCreateFilter(
This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice; This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface); This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface);
This->Header.Type = KsObjectTypeFilter; This->Header.Type = KsObjectTypeFilter;
KeInitializeMutex(&This->Header.ControlMutex, 0); This->Header.ControlMutex = &This->ControlMutex;
KeInitializeMutex(This->Header.ControlMutex, 0);
InitializeListHead(&This->Header.EventList); InitializeListHead(&This->Header.EventList);
KeInitializeSpinLock(&This->Header.EventListLock); KeInitializeSpinLock(&This->Header.EventListLock);
@ -1224,8 +1255,9 @@ KspCreateFilter(
if (Factory->FilterDescriptor->Dispatch->Create) if (Factory->FilterDescriptor->Dispatch->Create)
{ {
/* now let driver initialize the filter instance */ /* 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);
ASSERT(This->Header.KsDevice->Started);
Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp); Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp);
if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
@ -1432,6 +1464,17 @@ KsFilterCreatePinFactory (
RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX)); RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount], &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR)); 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 */ /* store new pin id */
*PinID = This->PinDescriptorCount; *PinID = This->PinDescriptorCount;

View file

@ -21,6 +21,8 @@ typedef struct
PFNKSFILTERFACTORYPOWER WakeCallback; PFNKSFILTERFACTORYPOWER WakeCallback;
LIST_ENTRY SymbolicLinkList; LIST_ENTRY SymbolicLinkList;
KMUTEX ControlMutex;
}IKsFilterFactoryImpl; }IKsFilterFactoryImpl;
VOID VOID
@ -225,17 +227,16 @@ IKsFilterFactory_fnInitialize(
This->Header.Parent.KsDevice = &DeviceExtension->DeviceHeader->KsDevice; This->Header.Parent.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
This->DeviceHeader = DeviceExtension->DeviceHeader; This->DeviceHeader = DeviceExtension->DeviceHeader;
/* initialize filter factory control mutex */
This->Header.ControlMutex = &This->ControlMutex;
KeInitializeMutex(This->Header.ControlMutex, 0);
/* unused fields */ /* unused fields */
KeInitializeMutex(&This->Header.ControlMutex, 0);
InitializeListHead(&This->Header.EventList); InitializeListHead(&This->Header.EventList);
KeInitializeSpinLock(&This->Header.EventListLock); KeInitializeSpinLock(&This->Header.EventListLock);
InitializeListHead(&This->SymbolicLinkList); InitializeListHead(&This->SymbolicLinkList);
/* initialize filter factory control mutex */
KeInitializeMutex(&This->Header.ControlMutex, 0);
/* does the device use a reference string */ /* does the device use a reference string */
if (RefString || !Descriptor->ReferenceGuid) if (RefString || !Descriptor->ReferenceGuid)
{ {

View file

@ -58,7 +58,7 @@ typedef struct
{ {
KSOBJECTTYPE Type; KSOBJECTTYPE Type;
PKSDEVICE KsDevice; PKSDEVICE KsDevice;
KMUTEX ControlMutex; PRKMUTEX ControlMutex;
LIST_ENTRY EventList; LIST_ENTRY EventList;
KSPIN_LOCK EventListLock; KSPIN_LOCK EventListLock;
union union

File diff suppressed because it is too large Load diff

View file

@ -35,3 +35,24 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral),\ DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral),\
DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(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)\
}

View file

@ -137,7 +137,7 @@ KspPropertyHandler(
/* get input property request */ /* get input property request */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 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 */ /* sanity check */
ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM)); ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM));