- 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 */
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);
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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)
{

View file

@ -58,7 +58,7 @@ typedef struct
{
KSOBJECTTYPE Type;
PKSDEVICE KsDevice;
KMUTEX ControlMutex;
PRKMUTEX ControlMutex;
LIST_ENTRY EventList;
KSPIN_LOCK EventListLock;
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_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 */
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));