mirror of
https://github.com/reactos/reactos.git
synced 2025-01-06 06:20:13 +00:00
[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
This commit is contained in:
parent
b4a44e7a78
commit
215e199219
9 changed files with 903 additions and 101 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
@ -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)\
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue