/* get property from input buffer */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
- /* sanity check */
- ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
-
/* get filter instance */
FilterInstance = Filter->lpVtbl->GetStruct(Filter);
+
+ /* sanity check */
+ ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
+ ASSERT(FilterInstance);
+ ASSERT(FilterInstance->Descriptor);
+ ASSERT(FilterInstance->Descriptor->AutomationTable);
+
RtlStringFromGUID(&Property->Set, &GuidString);
DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString);
ULONG MethodItemSize = 0;
/* check if the driver supports method sets */
- if (FilterInstance->Descriptor->AutomationTable && FilterInstance->Descriptor->AutomationTable->MethodSetsCount)
+ if (FilterInstance->Descriptor->AutomationTable->MethodSetsCount)
{
SetCount = FilterInstance->Descriptor->AutomationTable->MethodSetsCount;
MethodSet = FilterInstance->Descriptor->AutomationTable->MethodSets;
ULONG PropertyItemSize = 0;
/* check if the driver supports method sets */
- if (FilterInstance->Descriptor->AutomationTable && FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
+ if (FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
{
SetCount = FilterInstance->Descriptor->AutomationTable->PropertySetsCount;
PropertySet = FilterInstance->Descriptor->AutomationTable->PropertySets;
ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT ||
IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT);
- Status = STATUS_NOT_FOUND;
- UNIMPLEMENTED;
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
+ {
+ /* call enable event handlers */
+ Status = KspEnableEvent(Irp,
+ FilterInstance->Descriptor->AutomationTable->EventSetsCount,
+ (PKSEVENT_SET)FilterInstance->Descriptor->AutomationTable->EventSets,
+ &This->Header.EventList,
+ KSEVENTS_SPINLOCK,
+ (PVOID)&This->Header.EventListLock,
+ NULL,
+ FilterInstance->Descriptor->AutomationTable->EventItemSize);
+ }
+ else
+ {
+ /* disable event handler */
+ Status = KsDisableEvent(Irp, &This->Header.EventList, KSEVENTS_SPINLOCK, &This->Header.EventListLock);
+ }
}
RtlStringFromGUID(&Property->Set, &GuidString);
}
-NTSTATUS
+VOID
IKsFilter_AddPin(
- IKsFilter * Filter,
+ PKSFILTER Filter,
PKSPIN Pin)
{
PKSPIN NextPin, CurPin;
PKSBASIC_HEADER BasicHeader;
- IKsFilterImpl * This = (IKsFilterImpl*)Filter;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
/* sanity check */
ASSERT(Pin->Id < This->PinDescriptorCount);
{
/* welcome first pin */
This->FirstPin[Pin->Id] = Pin;
- return STATUS_SUCCESS;
+ This->PinInstanceCount[Pin->Id]++;
+ return;
}
/* get first pin */
/* store pin */
BasicHeader->Next.Pin = Pin;
+}
- return STATUS_SUCCESS;
+VOID
+IKsFilter_RemovePin(
+ PKSFILTER Filter,
+ PKSPIN Pin)
+{
+ PKSPIN NextPin, CurPin, LastPin;
+ PKSBASIC_HEADER BasicHeader;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
+
+ /* sanity check */
+ ASSERT(Pin->Id < This->PinDescriptorCount);
+
+ /* get first pin */
+ CurPin = This->FirstPin[Pin->Id];
+
+ LastPin = NULL;
+ do
+ {
+ /* get next instantiated pin */
+ NextPin = KsPinGetNextSiblingPin(CurPin);
+
+ if (CurPin == Pin)
+ {
+ if (LastPin)
+ {
+ /* get basic header of last pin */
+ BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastPin - sizeof(KSBASIC_HEADER));
+
+ BasicHeader->Next.Pin = NextPin;
+ }
+ else
+ {
+ /* erase last pin */
+ This->FirstPin[Pin->Id] = NextPin;
+ }
+ /* decrement pin instance count */
+ This->PinInstanceCount[Pin->Id]--;
+ return;
+ }
+
+ if (!NextPin)
+ break;
+
+ LastPin = CurPin;
+ NextPin = CurPin;
+
+ }while(NextPin != NULL);
+
+ /* pin not found */
+ ASSERT(0);
}
Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, &This->PinDescriptorsEx[Connect->PinId]);
DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status);
-
- if (NT_SUCCESS(Status))
- {
- /* successfully created pin, increment pin instance count */
- This->PinInstanceCount[Connect->PinId]++;
- }
}
else
{
KeReleaseMutex(&This->ProcessingMutex, FALSE);
}
+
/*
@implemented
*/
/* get the object header */
ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+ /* sanity check */
+ ASSERT(ObjectHeader);
+
/* 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);
+ /* sanity check */
+ ASSERT(This);
Handle = (PHANDLE)Data;
}
}
- /* release processing mutex */
- KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE);
-
- DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status);
+ DPRINT("IKsPin_PinMasterClock Status %lx\n", Status);
return Status;
}
return Status;
}
-
NTSTATUS
-IKsPin_DispatchKsProperty(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- IKsPinImpl * This)
+NTAPI
+IKsPin_DispatchDeviceIoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- NTSTATUS Status;
- PKSPROPERTY Property;
PIO_STACK_LOCATION IoStack;
+ PKSIOBJECT_HEADER ObjectHeader;
+ IKsPinImpl * This;
+ NTSTATUS Status;
UNICODE_STRING GuidString;
- ULONG PropertySetsCount = 0, PropertyItemSize = 0;
- const KSPROPERTY_SET* PropertySets = NULL;
+ PKSPROPERTY Property;
+ ULONG SetCount = 0;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
/* sanity check */
- ASSERT(This->Pin.Descriptor);
+ ASSERT(IoStack->FileObject);
+ ASSERT(IoStack->FileObject->FsContext2);
- /* get current irp stack */
+ /* 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);
+
+ /* current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
+ /* get property from input buffer */
+ Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
- if (This->Pin.Descriptor->AutomationTable)
- {
- /* use available driver property sets */
- PropertySetsCount = This->Pin.Descriptor->AutomationTable->PropertySetsCount;
- PropertySets = This->Pin.Descriptor->AutomationTable->PropertySets;
- PropertyItemSize = This->Pin.Descriptor->AutomationTable->PropertyItemSize;
- }
+ /* sanity check */
+ ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
+ ASSERT(This->Pin.Descriptor->AutomationTable);
+ RtlStringFromGUID(&Property->Set, &GuidString);
+ DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
+ RtlFreeUnicodeString(&GuidString);
- /* try driver provided property sets */
- Status = KspPropertyHandler(Irp,
- PropertySetsCount,
- PropertySets,
- NULL,
- PropertyItemSize);
- if (Status != STATUS_NOT_FOUND)
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD)
{
- /* property was handled by driver */
- if (Status != STATUS_PENDING)
+ const KSMETHOD_SET *MethodSet = NULL;
+ ULONG MethodItemSize = 0;
+
+ /* check if the driver supports method sets */
+ if (This->Pin.Descriptor->AutomationTable->MethodSetsCount)
{
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ SetCount = This->Pin.Descriptor->AutomationTable->MethodSetsCount;
+ MethodSet = This->Pin.Descriptor->AutomationTable->MethodSets;
+ MethodItemSize = This->Pin.Descriptor->AutomationTable->MethodItemSize;
}
- return Status;
+
+ /* call method set handler */
+ Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize);
}
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
+ {
+ const KSPROPERTY_SET *PropertySet = NULL;
+ ULONG PropertyItemSize = 0;
+
+ /* check if the driver supports method sets */
+ if (This->Pin.Descriptor->AutomationTable->PropertySetsCount)
+ {
+ SetCount = This->Pin.Descriptor->AutomationTable->PropertySetsCount;
+ PropertySet = This->Pin.Descriptor->AutomationTable->PropertySets;
+ PropertyItemSize = This->Pin.Descriptor->AutomationTable->PropertyItemSize;
+ }
- /* try our properties */
- Status = KspPropertyHandler(Irp,
- sizeof(PinPropertySet) / sizeof(KSPROPERTY_SET),
- PinPropertySet,
- NULL,
- 0);
+ /* needed for our property handlers */
+ KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This;
- if (Status != STATUS_NOT_FOUND)
+ /* call property handler */
+ Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize);
+ }
+ else
{
- /* property was handled by driver */
- if (Status != STATUS_PENDING)
+ /* sanity check */
+ ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT ||
+ IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT);
+
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
{
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ /* call enable event handlers */
+ Status = KspEnableEvent(Irp,
+ This->Pin.Descriptor->AutomationTable->EventSetsCount,
+ (PKSEVENT_SET)This->Pin.Descriptor->AutomationTable->EventSets,
+ &This->BasicHeader.EventList,
+ KSEVENTS_SPINLOCK,
+ (PVOID)&This->BasicHeader.EventListLock,
+ NULL,
+ This->Pin.Descriptor->AutomationTable->EventItemSize);
+ }
+ else
+ {
+ /* disable event handler */
+ Status = KsDisableEvent(Irp, &This->BasicHeader.EventList, KSEVENTS_SPINLOCK, &This->BasicHeader.EventListLock);
}
- return Status;
}
- /* property was not handled */
- Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
-
RtlStringFromGUID(&Property->Set, &GuidString);
- DPRINT("IKsPin_DispatchKsProperty Unhandled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
+ DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information);
RtlFreeUnicodeString(&GuidString);
- Irp->IoStatus.Status = STATUS_NOT_FOUND;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return STATUS_NOT_FOUND;
-
-}
-
-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)
+ if (Status != STATUS_PENDING)
{
- /* handle ks properties */
- return IKsPin_DispatchKsStream(DeviceObject, Irp, This);
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
- UNIMPLEMENTED;
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED;
+ /* done */
+ return Status;
}
NTSTATUS
/* locate ks pin implemention fro KSPIN offset */
This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin);
- /* acquire filter control mutex */
- KsFilterAcquireControl(&This->Pin);
-
if (This->Pin.Descriptor->Dispatch->Close)
{
/* call pin close routine */
return Status;
}
- /* FIXME remove pin from filter pin list and decrement reference count */
+ /* remove pin from filter pin list and decrement reference count */
+ IKsFilter_RemovePin(This->Filter->lpVtbl->GetStruct(This->Filter), &This->Pin);
if (Status != STATUS_PENDING)
{
}
}
- /* release filter control mutex */
- KsFilterReleaseControl(&This->Pin);
-
return Status;
}
ULONG Index;
ULONG FrameSize = 0;
ULONG NumFrames = 0;
+ KSAUTOMATION_TABLE AutomationTable;
/* sanity checks */
ASSERT(Descriptor->Dispatch);
This->BasicHeader.KsDevice = KsDevice;
This->BasicHeader.Type = KsObjectTypePin;
This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter);
+ InitializeListHead(&This->BasicHeader.EventList);
+ KeInitializeSpinLock(&This->BasicHeader.EventListLock);
ASSERT(This->BasicHeader.Parent.KsFilter);
/* initialize object bag */
Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, NULL);
+ /* allocate pin descriptor */
+ This->Pin.Descriptor = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR_EX));
+ if (!This->Pin.Descriptor)
+ {
+ /* not enough memory */
+ KsFreeObjectBag(This->Pin.Bag);
+ FreeItem(This);
+ FreeItem(CreateItem);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* copy pin descriptor */
+ RtlMoveMemory((PVOID)This->Pin.Descriptor, Descriptor, sizeof(KSPIN_DESCRIPTOR_EX));
+
+ /* initialize automation table */
+ RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE));
+
+ AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM);
+ AutomationTable.PropertySets = PinPropertySet;
+ AutomationTable.PropertySetsCount = sizeof(PinPropertySet) / sizeof(KSPROPERTY_SET);
+
+ /* merge in pin property sets */
+ Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Pin.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)Descriptor->AutomationTable, &AutomationTable, This->Pin.Bag);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* not enough memory */
+ KsFreeObjectBag(This->Pin.Bag);
+ FreeItem(This);
+ FreeItem(CreateItem);
+ return Status;
+ }
+
/* get format */
DataFormat = (PKSDATAFORMAT)(Connect + 1);
/* initialize pin descriptor */
- This->Pin.Descriptor = Descriptor;
This->Pin.Context = NULL;
This->Pin.Id = Connect->PinId;
This->Pin.Communication = Descriptor->PinDescriptor.Communication;
}
/* FIXME add pin instance to filter instance */
-
+ IKsFilter_AddPin(Filter->lpVtbl->GetStruct(Filter), &This->Pin);
if (Descriptor->Dispatch && Descriptor->Dispatch->SetDataFormat)
{
if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
{
/* failed to create pin, release resources */
+ IKsFilter_RemovePin(Filter->lpVtbl->GetStruct(Filter), &This->Pin);
KsFreeObjectHeader((KSOBJECT_HEADER)This->ObjectHeader);
KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag);
FreeItem(This);