2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/filter.c
5 * PURPOSE: KS IKsFilter interface functions
6 * PROGRAMMER: Johannes Anderwald
14 KSBASIC_HEADER Header
;
17 IKsControlVtbl
*lpVtblKsControl
;
18 IKsFilterFactory
* FilterFactory
;
21 PKSIOBJECT_HEADER ObjectHeader
;
23 PKSFILTERFACTORY Factory
;
24 PFILE_OBJECT FileObject
;
26 KMUTEX ProcessingMutex
;
29 PFNKSFILTERPOWER Sleep
;
30 PFNKSFILTERPOWER Wake
;
32 ULONG
*PinInstanceCount
;
34 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
38 const GUID IID_IKsControl
= {0x28F54685L
, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
39 const GUID IID_IKsFilter
= {0x3ef6ee44L
, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}};
40 const GUID KSPROPSETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
41 const GUID KSPROPSETID_Pin
= {0x8C134960L
, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
44 IKsFilter_RemoveFilterFromFilterFactory(
46 PKSFILTERFACTORY FilterFactory
);
48 NTSTATUS NTAPI
FilterTopologyPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
49 NTSTATUS NTAPI
FilterPinPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
52 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet
, FilterTopologyPropertyHandler
);
53 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet
, FilterPinPropertyHandler
, FilterPinPropertyHandler
, FilterPinPropertyHandler
);
55 KSPROPERTY_SET FilterPropertySet
[] =
58 &KSPROPSETID_Topology
,
59 sizeof(IKsFilterTopologySet
) / sizeof(KSPROPERTY_ITEM
),
60 (const KSPROPERTY_ITEM
*)&IKsFilterTopologySet
,
66 sizeof(IKsFilterPinSet
) / sizeof(KSPROPERTY_ITEM
),
67 (const KSPROPERTY_ITEM
*)&IKsFilterPinSet
,
75 IKsControl_fnQueryInterface(
80 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
82 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
84 *Output
= &This
->Header
.OuterUnknown
;
85 _InterlockedIncrement(&This
->ref
);
86 return STATUS_SUCCESS
;
88 return STATUS_UNSUCCESSFUL
;
96 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
98 return InterlockedIncrement(&This
->ref
);
103 IKsControl_fnRelease(
106 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
108 InterlockedDecrement(&This
->ref
);
110 /* Return new reference count */
116 IKsControl_fnKsProperty(
118 IN PKSPROPERTY Property
,
119 IN ULONG PropertyLength
,
120 IN OUT PVOID PropertyData
,
122 OUT ULONG
* BytesReturned
)
124 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
126 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, Property
, PropertyLength
, PropertyData
, DataLength
, BytesReturned
);
132 IKsControl_fnKsMethod(
135 IN ULONG MethodLength
,
136 IN OUT PVOID MethodData
,
138 OUT ULONG
* BytesReturned
)
140 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
142 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_METHOD
, Method
, MethodLength
, MethodData
, DataLength
, BytesReturned
);
148 IKsControl_fnKsEvent(
150 IN PKSEVENT Event OPTIONAL
,
151 IN ULONG EventLength
,
152 IN OUT PVOID EventData
,
154 OUT ULONG
* BytesReturned
)
156 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
160 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_ENABLE_EVENT
, Event
, EventLength
, EventData
, DataLength
, BytesReturned
);
164 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_DISABLE_EVENT
, EventData
, DataLength
, NULL
, 0, BytesReturned
);
169 static IKsControlVtbl vt_IKsControl
=
171 IKsControl_fnQueryInterface
,
173 IKsControl_fnRelease
,
174 IKsControl_fnKsProperty
,
175 IKsControl_fnKsMethod
,
182 IKsFilter_fnQueryInterface(
188 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
190 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
) ||
191 IsEqualGUIDAligned(refiid
, &IID_IKsFilter
))
193 *Output
= &This
->Header
.OuterUnknown
;
194 _InterlockedIncrement(&This
->ref
);
195 return STATUS_SUCCESS
;
197 else if (IsEqualGUIDAligned(refiid
, &IID_IKsControl
))
199 *Output
= &This
->lpVtblKsControl
;
200 _InterlockedIncrement(&This
->ref
);
201 return STATUS_SUCCESS
;
204 if (This
->Header
.ClientAggregate
)
206 /* using client aggregate */
207 Status
= This
->Header
.ClientAggregate
->lpVtbl
->QueryInterface(This
->Header
.ClientAggregate
, refiid
, Output
);
209 if (NT_SUCCESS(Status
))
211 /* client aggregate supports interface */
216 DPRINT("IKsFilter_fnQueryInterface no interface\n");
217 return STATUS_NOT_SUPPORTED
;
225 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
227 return InterlockedIncrement(&This
->ref
);
235 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
237 InterlockedDecrement(&This
->ref
);
244 /* Return new reference count */
251 IKsFilter_fnGetStruct(
254 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
256 return &This
->Filter
;
261 IKsFilter_fnDoAllNecessaryPinsExist(
270 IKsFilter_fnCreateNode(
274 IN PLIST_ENTRY ListEntry
)
277 return STATUS_NOT_IMPLEMENTED
;
282 IKsFilter_fnBindProcessPinsToPipeSection(
284 IN
struct KSPROCESSPIPESECTION
*Section
,
288 OUT PKSGATE
*OutGate
)
291 return STATUS_NOT_IMPLEMENTED
;
296 IKsFilter_fnUnbindProcessPinsFromPipeSection(
298 IN
struct KSPROCESSPIPESECTION
*Section
)
301 return STATUS_NOT_IMPLEMENTED
;
306 IKsFilter_fnAddProcessPin(
308 IN PKSPROCESSPIN ProcessPin
)
311 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
313 /* first acquire processing mutex */
314 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
317 ASSERT(This
->Filter
.Descriptor
->PinDescriptorsCount
> ProcessPin
->Pin
->Id
);
319 /* allocate new process pin array */
320 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
,
321 (This
->Filter
.Descriptor
->PinDescriptorsCount
+ 1) * sizeof(PKSPROCESSPIN
),
322 This
->Filter
.Descriptor
->PinDescriptorsCount
* sizeof(PKSPROCESSPIN
),
325 if (NT_SUCCESS(Status
))
327 /* store process pin */
328 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
[This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
] = ProcessPin
;
329 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
++;
332 /* release process mutex */
333 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
340 IKsFilter_fnRemoveProcessPin(
342 IN PKSPROCESSPIN ProcessPin
)
346 PKSPROCESSPIN
* Pins
;
348 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
350 /* first acquire processing mutex */
351 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
354 ASSERT(ProcessPin
->Pin
);
355 ASSERT(ProcessPin
->Pin
->Id
);
357 Count
= This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
;
358 Pins
= This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
;
360 /* search for current process pin */
361 for(Index
= 0; Index
< Count
; Index
++)
363 if (Pins
[Index
] == ProcessPin
)
365 RtlMoveMemory(&Pins
[Index
], &Pins
[Index
+ 1], (Count
- (Index
+ 1)) * sizeof(PKSPROCESSPIN
));
371 /* decrement pin count */
372 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
--;
374 if (!This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
)
376 /* clear entry object bag will delete it */
377 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
= NULL
;
380 /* release process mutex */
381 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
384 return STATUS_SUCCESS
;
389 IKsFilter_fnReprepareProcessPipeSection(
391 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
400 IKsFilter_fnDeliverResetState(
402 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
403 IN KSRESET ResetState
)
410 IKsFilter_fnIsFrameHolding(
419 IKsFilter_fnRegisterForCopyCallbacks(
427 PKSPROCESSPIN_INDEXENTRY
429 IKsFilter_fnGetProcessDispatch(
432 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
434 return This
->ProcessPinIndex
;
437 static IKsFilterVtbl vt_IKsFilter
=
439 IKsFilter_fnQueryInterface
,
442 IKsFilter_fnGetStruct
,
443 IKsFilter_fnDoAllNecessaryPinsExist
,
444 IKsFilter_fnCreateNode
,
445 IKsFilter_fnBindProcessPinsToPipeSection
,
446 IKsFilter_fnUnbindProcessPinsFromPipeSection
,
447 IKsFilter_fnAddProcessPin
,
448 IKsFilter_fnRemoveProcessPin
,
449 IKsFilter_fnReprepareProcessPipeSection
,
450 IKsFilter_fnDeliverResetState
,
451 IKsFilter_fnIsFrameHolding
,
452 IKsFilter_fnRegisterForCopyCallbacks
,
453 IKsFilter_fnGetProcessDispatch
457 IKsFilter_GetFilterFromIrp(
459 OUT IKsFilter
**Filter
)
461 PIO_STACK_LOCATION IoStack
;
462 PKSIOBJECT_HEADER ObjectHeader
;
465 /* get current irp stack */
466 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
469 ASSERT(IoStack
->FileObject
!= NULL
);
471 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
473 /* sanity is important */
474 ASSERT(ObjectHeader
!= NULL
);
475 ASSERT(ObjectHeader
->Type
== KsObjectTypeFilter
);
476 ASSERT(ObjectHeader
->Unknown
!= NULL
);
478 /* get our private interface */
479 Status
= ObjectHeader
->Unknown
->lpVtbl
->QueryInterface(ObjectHeader
->Unknown
, &IID_IKsFilter
, (PVOID
*)Filter
);
481 if (!NT_SUCCESS(Status
))
483 /* something is wrong here */
484 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader
->Unknown
);
485 Irp
->IoStatus
.Status
= Status
;
487 /* complete and forget irp */
488 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
497 IKsFilter_DispatchClose(
498 IN PDEVICE_OBJECT DeviceObject
,
502 IKsFilterImpl
* This
;
505 /* obtain filter from object header */
506 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
507 if (!NT_SUCCESS(Status
))
510 /* get our real implementation */
511 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Header
.OuterUnknown
);
513 /* does the driver support notifications */
514 if (This
->Filter
.Descriptor
&& This
->Filter
.Descriptor
->Dispatch
&& This
->Filter
.Descriptor
->Dispatch
->Close
)
516 /* call driver's filter close function */
517 Status
= This
->Filter
.Descriptor
->Dispatch
->Close(&This
->Filter
, Irp
);
520 if (NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
522 /* save the result */
523 Irp
->IoStatus
.Status
= Status
;
525 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
527 /* remove our instance from the filter factory */
528 IKsFilter_RemoveFilterFromFilterFactory(This
, This
->Factory
);
530 /* free object header */
531 KsFreeObjectHeader(This
->ObjectHeader
);
535 /* complete and forget */
536 Irp
->IoStatus
.Status
= Status
;
538 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
546 KspHandlePropertyInstances(
547 IN PIO_STATUS_BLOCK IoStatus
,
548 IN PKSIDENTIFIER Request
,
550 IN IKsFilterImpl
* This
,
553 KSPIN_CINSTANCES
* Instances
;
554 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
556 if (!This
->Filter
.Descriptor
|| !This
->Filter
.Descriptor
->PinDescriptorsCount
)
558 /* no filter / pin descriptor */
559 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
560 return STATUS_NOT_IMPLEMENTED
;
563 /* ignore custom structs for now */
564 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
565 ASSERT(This
->Filter
.Descriptor
->PinDescriptorsCount
> Pin
->PinId
);
567 Instances
= (KSPIN_CINSTANCES
*)Data
;
568 /* max instance count */
569 Instances
->PossibleCount
= This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].InstancesPossible
;
570 /* current instance count */
571 Instances
->CurrentCount
= This
->PinInstanceCount
[Pin
->PinId
];
573 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
574 IoStatus
->Status
= STATUS_SUCCESS
;
575 return STATUS_SUCCESS
;
579 KspHandleNecessaryPropertyInstances(
580 IN PIO_STATUS_BLOCK IoStatus
,
581 IN PKSIDENTIFIER Request
,
583 IN IKsFilterImpl
* This
)
586 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
588 if (!This
->Filter
.Descriptor
|| !This
->Filter
.Descriptor
->PinDescriptorsCount
)
590 /* no filter / pin descriptor */
591 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
592 return STATUS_NOT_IMPLEMENTED
;
595 /* ignore custom structs for now */
596 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
597 ASSERT(This
->Filter
.Descriptor
->PinDescriptorsCount
> Pin
->PinId
);
599 Result
= (PULONG
)Data
;
600 *Result
= This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].InstancesNecessary
;
602 IoStatus
->Information
= sizeof(ULONG
);
603 IoStatus
->Status
= STATUS_SUCCESS
;
604 return STATUS_SUCCESS
;
608 KspHandleDataIntersection(
610 IN PIO_STATUS_BLOCK IoStatus
,
611 IN PKSIDENTIFIER Request
,
614 IN IKsFilterImpl
* This
)
616 PKSMULTIPLE_ITEM MultipleItem
;
617 PKSDATARANGE DataRange
;
618 NTSTATUS Status
= STATUS_NO_MATCH
;
620 PIO_STACK_LOCATION IoStack
;
621 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
623 /* get stack location */
624 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
627 ASSERT(DataLength
== IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
629 /* Access parameters */
630 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
631 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
633 /* FIXME make sure its 64 bit aligned */
634 ASSERT(((ULONG_PTR
)DataRange
& 0x7) == 0);
636 if (!This
->Filter
.Descriptor
|| !This
->Filter
.Descriptor
->PinDescriptorsCount
)
638 /* no filter / pin descriptor */
639 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
640 return STATUS_NOT_IMPLEMENTED
;
643 /* ignore custom structs for now */
644 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
645 ASSERT(This
->Filter
.Descriptor
->PinDescriptorsCount
> Pin
->PinId
);
647 if (This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].IntersectHandler
== NULL
||
648 This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
== NULL
||
649 This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRangesCount
== 0)
651 /* no driver supported intersect handler / no provided data ranges */
652 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
653 return STATUS_NOT_IMPLEMENTED
;
656 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
658 UNICODE_STRING MajorFormat
, SubFormat
, Specifier
;
659 /* convert the guid to string */
660 RtlStringFromGUID(&DataRange
->MajorFormat
, &MajorFormat
);
661 RtlStringFromGUID(&DataRange
->SubFormat
, &SubFormat
);
662 RtlStringFromGUID(&DataRange
->Specifier
, &Specifier
);
664 DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index
, Pin
->PinId
, MajorFormat
.Buffer
, SubFormat
.Buffer
, Specifier
.Buffer
,
665 DataRange
->FormatSize
, DataRange
->SampleSize
, DataRange
->Alignment
, DataRange
->Flags
, DataRange
->Reserved
, DataLength
);
667 /* FIXME implement KsPinDataIntersectionEx */
668 /* Call miniport's properitary handler */
669 Status
= This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].IntersectHandler(&This
->Filter
,
673 This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
[0], /* HACK */
677 DPRINT("KspHandleDataIntersection Status %lx\n", Status
);
679 if (Status
== STATUS_SUCCESS
|| Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
682 IoStatus
->Information
= Length
;
686 DataRange
= UlongToPtr(PtrToUlong(DataRange
) + DataRange
->FormatSize
);
687 /* FIXME make sure its 64 bit aligned */
688 ASSERT(((ULONG_PTR
)DataRange
& 0x7) == 0);
690 IoStatus
->Status
= Status
;
696 FilterTopologyPropertyHandler(
698 IN PKSIDENTIFIER Request
,
701 IKsFilterImpl
* This
;
703 /* get filter implementation */
704 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
709 return KsTopologyPropertyHandler(Irp
, Request
, Data
, &This
->Topology
);
716 FilterPinPropertyHandler(
718 IN PKSIDENTIFIER Request
,
721 PIO_STACK_LOCATION IoStack
;
722 IKsFilterImpl
* This
;
723 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
725 /* get filter implementation */
726 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
731 /* get current stack location */
732 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
736 case KSPROPERTY_PIN_CTYPES
:
737 case KSPROPERTY_PIN_DATAFLOW
:
738 case KSPROPERTY_PIN_DATARANGES
:
739 case KSPROPERTY_PIN_INTERFACES
:
740 case KSPROPERTY_PIN_MEDIUMS
:
741 case KSPROPERTY_PIN_COMMUNICATION
:
742 case KSPROPERTY_PIN_CATEGORY
:
743 case KSPROPERTY_PIN_NAME
:
744 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
745 Status
= KspPinPropertyHandler(Irp
, Request
, Data
, This
->Filter
.Descriptor
->PinDescriptorsCount
, (const KSPIN_DESCRIPTOR
*)This
->Filter
.Descriptor
->PinDescriptors
, This
->Filter
.Descriptor
->PinDescriptorSize
);
747 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
748 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, TRUE
);
750 case KSPROPERTY_PIN_CINSTANCES
:
751 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, FALSE
);
753 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
754 Status
= KspHandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
);
757 case KSPROPERTY_PIN_DATAINTERSECTION
:
758 Status
= KspHandleDataIntersection(Irp
, &Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
);
762 Status
= STATUS_NOT_FOUND
;
764 //DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status);
772 IKsFilter_DispatchDeviceIoControl(
773 IN PDEVICE_OBJECT DeviceObject
,
776 PIO_STACK_LOCATION IoStack
;
778 IKsFilterImpl
* This
;
780 PKSFILTER FilterInstance
;
781 UNICODE_STRING GuidString
;
782 PKSPROPERTY Property
;
785 /* obtain filter from object header */
786 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
787 if (!NT_SUCCESS(Status
))
790 /* get our real implementation */
791 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Header
.OuterUnknown
);
793 /* current irp stack */
794 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
796 /* get property from input buffer */
797 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
799 /* get filter instance */
800 FilterInstance
= Filter
->lpVtbl
->GetStruct(Filter
);
803 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSIDENTIFIER
));
804 ASSERT(FilterInstance
);
805 ASSERT(FilterInstance
->Descriptor
);
806 ASSERT(FilterInstance
->Descriptor
->AutomationTable
);
808 /* acquire control mutex */
809 KeWaitForSingleObject(This
->Header
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
811 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_METHOD
)
813 const KSMETHOD_SET
*MethodSet
= NULL
;
814 ULONG MethodItemSize
= 0;
816 /* check if the driver supports method sets */
817 if (FilterInstance
->Descriptor
->AutomationTable
->MethodSetsCount
)
819 SetCount
= FilterInstance
->Descriptor
->AutomationTable
->MethodSetsCount
;
820 MethodSet
= FilterInstance
->Descriptor
->AutomationTable
->MethodSets
;
821 MethodItemSize
= FilterInstance
->Descriptor
->AutomationTable
->MethodItemSize
;
824 /* call method set handler */
825 Status
= KspMethodHandlerWithAllocator(Irp
, SetCount
, MethodSet
, NULL
, MethodItemSize
);
827 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
829 const KSPROPERTY_SET
*PropertySet
= NULL
;
830 ULONG PropertyItemSize
= 0;
832 /* check if the driver supports method sets */
833 if (FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
)
835 SetCount
= FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
;
836 PropertySet
= FilterInstance
->Descriptor
->AutomationTable
->PropertySets
;
837 PropertyItemSize
= FilterInstance
->Descriptor
->AutomationTable
->PropertyItemSize
;
840 /* needed for our property handlers */
841 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
843 /* call property handler */
844 Status
= KspPropertyHandler(Irp
, SetCount
, PropertySet
, NULL
, PropertyItemSize
);
849 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
||
850 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_DISABLE_EVENT
);
852 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
)
854 /* call enable event handlers */
855 Status
= KspEnableEvent(Irp
,
856 FilterInstance
->Descriptor
->AutomationTable
->EventSetsCount
,
857 (PKSEVENT_SET
)FilterInstance
->Descriptor
->AutomationTable
->EventSets
,
858 &This
->Header
.EventList
,
860 (PVOID
)&This
->Header
.EventListLock
,
862 FilterInstance
->Descriptor
->AutomationTable
->EventItemSize
);
866 /* disable event handler */
867 Status
= KsDisableEvent(Irp
, &This
->Header
.EventList
, KSEVENTS_SPINLOCK
, &This
->Header
.EventListLock
);
871 RtlStringFromGUID(&Property
->Set
, &GuidString
);
872 DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
, Status
, Irp
->IoStatus
.Information
);
873 RtlFreeUnicodeString(&GuidString
);
876 Filter
->lpVtbl
->Release(Filter
);
878 /* release control mutex */
879 KeReleaseMutex(This
->Header
.ControlMutex
, FALSE
);
881 if (Status
!= STATUS_PENDING
)
883 Irp
->IoStatus
.Status
= Status
;
884 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
891 static KSDISPATCH_TABLE DispatchTable
=
893 IKsFilter_DispatchDeviceIoControl
,
894 KsDispatchInvalidDeviceRequest
,
895 KsDispatchInvalidDeviceRequest
,
896 KsDispatchInvalidDeviceRequest
,
897 IKsFilter_DispatchClose
,
898 KsDispatchQuerySecurity
,
899 KsDispatchSetSecurity
,
900 KsDispatchFastIoDeviceControlFailure
,
901 KsDispatchFastReadFailure
,
902 KsDispatchFastReadFailure
,
907 IKsFilter_CreateDescriptors(
908 IKsFilterImpl
* This
,
909 KSFILTER_DESCRIPTOR
* FilterDescriptor
)
914 /* initialize pin descriptors */
915 This
->FirstPin
= NULL
;
916 This
->PinInstanceCount
= NULL
;
917 This
->ProcessPinIndex
= NULL
;
919 /* initialize topology descriptor */
920 This
->Topology
.CategoriesCount
= FilterDescriptor
->CategoriesCount
;
921 This
->Topology
.Categories
= FilterDescriptor
->Categories
;
922 This
->Topology
.TopologyNodesCount
= FilterDescriptor
->NodeDescriptorsCount
;
923 This
->Topology
.TopologyConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
924 This
->Topology
.TopologyConnections
= FilterDescriptor
->Connections
;
926 /* are there any templates */
927 if (FilterDescriptor
->PinDescriptorsCount
)
930 ASSERT(FilterDescriptor
->PinDescriptors
);
932 /* FIXME handle variable sized pin descriptors */
933 ASSERT(FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
935 /* store pin descriptors ex */
936 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->Filter
.Descriptor
->PinDescriptors
, FilterDescriptor
->PinDescriptorSize
* FilterDescriptor
->PinDescriptorsCount
,
937 FilterDescriptor
->PinDescriptorSize
* FilterDescriptor
->PinDescriptorsCount
, 0);
939 if (!NT_SUCCESS(Status
))
941 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
945 /* store pin instance count */
946 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
,
947 sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
, 0);
949 if (!NT_SUCCESS(Status
))
951 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
955 /* store instantiated pin arrays */
956 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->FirstPin
, sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
,
957 sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
, 0);
959 if (!NT_SUCCESS(Status
))
961 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
965 /* add new pin factory */
966 RtlMoveMemory((PVOID
)This
->Filter
.Descriptor
->PinDescriptors
, FilterDescriptor
->PinDescriptors
, FilterDescriptor
->PinDescriptorSize
* FilterDescriptor
->PinDescriptorsCount
);
968 /* allocate process pin index */
969 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
, sizeof(KSPROCESSPIN_INDEXENTRY
) * FilterDescriptor
->PinDescriptorsCount
,
970 sizeof(KSPROCESSPIN_INDEXENTRY
) * FilterDescriptor
->PinDescriptorsCount
, 0);
972 if (!NT_SUCCESS(Status
))
974 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
981 if (FilterDescriptor
->ConnectionsCount
)
983 /* modify connections array */
984 Status
= _KsEdit(This
->Filter
.Bag
,
985 (PVOID
*)&This
->Filter
.Descriptor
->Connections
,
986 FilterDescriptor
->ConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
),
987 FilterDescriptor
->ConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
),
990 This
->Topology
.TopologyConnections
= This
->Filter
.Descriptor
->Connections
;
991 This
->Topology
.TopologyConnectionsCount
= ((PKSFILTER_DESCRIPTOR
)This
->Filter
.Descriptor
)->ConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
994 if (FilterDescriptor
->NodeDescriptorsCount
)
997 ASSERT(FilterDescriptor
->NodeDescriptors
);
999 /* FIXME handle variable sized node descriptors */
1000 ASSERT(FilterDescriptor
->NodeDescriptorSize
== sizeof(KSNODE_DESCRIPTOR
));
1002 This
->Topology
.TopologyNodes
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
1003 /* allocate topology node types array */
1004 if (!This
->Topology
.TopologyNodes
)
1006 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
1007 return STATUS_INSUFFICIENT_RESOURCES
;
1010 This
->Topology
.TopologyNodesNames
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
1011 /* allocate topology names array */
1012 if (!This
->Topology
.TopologyNodesNames
)
1014 FreeItem((PVOID
)This
->Topology
.TopologyNodes
);
1015 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
1016 return STATUS_INSUFFICIENT_RESOURCES
;
1019 DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
1020 for(Index
= 0; Index
< FilterDescriptor
->NodeDescriptorsCount
; Index
++)
1022 DPRINT("Index %lu Type %p Name %p\n", Index
, FilterDescriptor
->NodeDescriptors
[Index
].Type
, FilterDescriptor
->NodeDescriptors
[Index
].Name
);
1024 /* copy topology type */
1025 if (FilterDescriptor
->NodeDescriptors
[Index
].Type
)
1026 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodes
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Type
, sizeof(GUID
));
1028 /* copy topology name */
1029 if (FilterDescriptor
->NodeDescriptors
[Index
].Name
)
1030 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodesNames
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Name
, sizeof(GUID
));
1034 return STATUS_SUCCESS
;
1038 IKsFilter_CopyFilterDescriptor(
1039 IKsFilterImpl
* This
,
1040 const KSFILTER_DESCRIPTOR
* FilterDescriptor
)
1043 KSAUTOMATION_TABLE AutomationTable
;
1045 This
->Filter
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSFILTER_DESCRIPTOR
));
1046 if (!This
->Filter
.Descriptor
)
1047 return STATUS_INSUFFICIENT_RESOURCES
;
1049 Status
= KsAddItemToObjectBag(This
->Filter
.Bag
, (PVOID
)This
->Filter
.Descriptor
, NULL
);
1050 if (!NT_SUCCESS(Status
))
1052 FreeItem((PVOID
)This
->Filter
.Descriptor
);
1053 This
->Filter
.Descriptor
= NULL
;
1054 return STATUS_INSUFFICIENT_RESOURCES
;
1057 /* copy filter descriptor fields */
1058 RtlMoveMemory((PVOID
)This
->Filter
.Descriptor
, FilterDescriptor
, sizeof(KSFILTER_DESCRIPTOR
));
1060 /* zero automation table */
1061 RtlZeroMemory(&AutomationTable
, sizeof(KSAUTOMATION_TABLE
));
1063 /* setup filter property sets */
1064 AutomationTable
.PropertyItemSize
= sizeof(KSPROPERTY_ITEM
);
1065 AutomationTable
.PropertySetsCount
= 2;
1066 AutomationTable
.PropertySets
= FilterPropertySet
;
1068 /* merge filter automation table */
1069 Status
= KsMergeAutomationTables((PKSAUTOMATION_TABLE
*)&This
->Filter
.Descriptor
->AutomationTable
, (PKSAUTOMATION_TABLE
)FilterDescriptor
->AutomationTable
, &AutomationTable
, This
->Filter
.Bag
);
1080 PKSPIN NextPin
, CurPin
;
1081 PKSBASIC_HEADER BasicHeader
;
1082 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1085 ASSERT(Pin
->Id
< This
->Filter
.Descriptor
->PinDescriptorsCount
);
1087 if (This
->FirstPin
[Pin
->Id
] == NULL
)
1089 /* welcome first pin */
1090 This
->FirstPin
[Pin
->Id
] = Pin
;
1091 This
->PinInstanceCount
[Pin
->Id
]++;
1096 CurPin
= This
->FirstPin
[Pin
->Id
];
1100 /* get next instantiated pin */
1101 NextPin
= KsPinGetNextSiblingPin(CurPin
);
1107 }while(NextPin
!= NULL
);
1109 /* get basic header */
1110 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)CurPin
- sizeof(KSBASIC_HEADER
));
1113 BasicHeader
->Next
.Pin
= Pin
;
1117 IKsFilter_RemovePin(
1121 PKSPIN NextPin
, CurPin
, LastPin
;
1122 PKSBASIC_HEADER BasicHeader
;
1123 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1126 ASSERT(Pin
->Id
< This
->Filter
.Descriptor
->PinDescriptorsCount
);
1129 CurPin
= This
->FirstPin
[Pin
->Id
];
1134 /* get next instantiated pin */
1135 NextPin
= KsPinGetNextSiblingPin(CurPin
);
1141 /* get basic header of last pin */
1142 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)LastPin
- sizeof(KSBASIC_HEADER
));
1144 BasicHeader
->Next
.Pin
= NextPin
;
1148 /* erase last pin */
1149 This
->FirstPin
[Pin
->Id
] = NextPin
;
1151 /* decrement pin instance count */
1152 This
->PinInstanceCount
[Pin
->Id
]--;
1162 }while(NextPin
!= NULL
);
1171 IKsFilter_DispatchCreatePin(
1172 IN PDEVICE_OBJECT DeviceObject
,
1175 IKsFilterImpl
* This
;
1176 PKSOBJECT_CREATE_ITEM CreateItem
;
1177 PKSPIN_CONNECT Connect
;
1180 DPRINT("IKsFilter_DispatchCreatePin\n");
1182 /* get the create item */
1183 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
1185 /* get the filter object */
1186 This
= (IKsFilterImpl
*)CreateItem
->Context
;
1189 ASSERT(This
->Header
.Type
== KsObjectTypeFilter
);
1191 /* acquire control mutex */
1192 KeWaitForSingleObject(This
->Header
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1194 /* now validate the connect request */
1195 Status
= KspValidateConnectRequest(Irp
, This
->Filter
.Descriptor
->PinDescriptorsCount
, (PVOID
)This
->Filter
.Descriptor
->PinDescriptors
, This
->Filter
.Descriptor
->PinDescriptorSize
, &Connect
);
1197 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status
);
1199 if (NT_SUCCESS(Status
))
1202 ASSERT(Connect
->PinId
< This
->Filter
.Descriptor
->PinDescriptorsCount
);
1204 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect
->PinId
,
1205 This
->PinInstanceCount
[Connect
->PinId
],
1206 This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
].InstancesPossible
);
1208 if (This
->PinInstanceCount
[Connect
->PinId
] < This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
].InstancesPossible
)
1210 /* create the pin */
1211 Status
= KspCreatePin(DeviceObject
, Irp
, This
->Header
.KsDevice
, This
->FilterFactory
, (IKsFilter
*)&This
->Header
.OuterUnknown
, Connect
, (KSPIN_DESCRIPTOR_EX
*)&This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
]);
1213 DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status
);
1217 /* maximum instance count reached, bye-bye */
1218 Status
= STATUS_UNSUCCESSFUL
;
1219 DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
].InstancesPossible
, This
->PinInstanceCount
[Connect
->PinId
]);
1223 /* release control mutex */
1224 KeReleaseMutex(This
->Header
.ControlMutex
, FALSE
);
1226 if (Status
!= STATUS_PENDING
)
1228 /* complete request */
1229 Irp
->IoStatus
.Status
= Status
;
1230 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1234 DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status
);
1240 IKsFilter_DispatchCreateNode(
1241 IN PDEVICE_OBJECT DeviceObject
,
1245 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1246 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1247 return STATUS_UNSUCCESSFUL
;
1252 IKsFilter_AttachFilterToFilterFactory(
1253 IKsFilterImpl
* This
,
1254 PKSFILTERFACTORY FilterFactory
)
1256 PKSBASIC_HEADER BasicHeader
;
1260 /* get filter factory basic header */
1261 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1264 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1266 if (BasicHeader
->FirstChild
.FilterFactory
== NULL
)
1268 /* welcome first instantiated filter */
1269 BasicHeader
->FirstChild
.Filter
= &This
->Filter
;
1273 /* set to first entry */
1274 Filter
= BasicHeader
->FirstChild
.Filter
;
1278 /* get basic header */
1279 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1281 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1283 if (BasicHeader
->Next
.Filter
)
1285 /* iterate to next filter factory */
1286 Filter
= BasicHeader
->Next
.Filter
;
1290 /* found last entry */
1295 /* attach filter factory */
1296 BasicHeader
->Next
.Filter
= &This
->Filter
;
1300 IKsFilter_RemoveFilterFromFilterFactory(
1301 IKsFilterImpl
* This
,
1302 PKSFILTERFACTORY FilterFactory
)
1304 PKSBASIC_HEADER BasicHeader
;
1305 PKSFILTER Filter
, LastFilter
;
1307 /* get filter factory basic header */
1308 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1311 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1312 ASSERT(BasicHeader
->FirstChild
.Filter
!= NULL
);
1315 /* set to first entry */
1316 Filter
= BasicHeader
->FirstChild
.Filter
;
1321 if (Filter
== &This
->Filter
)
1325 /* get basic header */
1326 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)LastFilter
- sizeof(KSBASIC_HEADER
));
1327 /* remove filter instance */
1328 BasicHeader
->Next
.Filter
= This
->Header
.Next
.Filter
;
1333 /* remove filter instance */
1334 BasicHeader
->FirstChild
.Filter
= This
->Header
.Next
.Filter
;
1339 /* get basic header */
1340 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1342 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1344 LastFilter
= Filter
;
1345 if (BasicHeader
->Next
.Filter
)
1347 /* iterate to next filter factory */
1348 Filter
= BasicHeader
->Next
.Filter
;
1352 /* filter is not in list */
1362 IN PDEVICE_OBJECT DeviceObject
,
1364 IN IKsFilterFactory
*iface
)
1366 IKsFilterImpl
* This
;
1367 IKsDevice
*KsDevice
;
1368 PKSFILTERFACTORY Factory
;
1369 PIO_STACK_LOCATION IoStack
;
1370 PDEVICE_EXTENSION DeviceExtension
;
1372 PKSOBJECT_CREATE_ITEM CreateItem
;
1374 /* get device extension */
1375 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1377 /* get the filter factory */
1378 Factory
= iface
->lpVtbl
->GetStruct(iface
);
1380 if (!Factory
|| !Factory
->FilterDescriptor
|| !Factory
->FilterDescriptor
->Dispatch
|| !Factory
->FilterDescriptor
->Dispatch
->Create
)
1382 /* Sorry it just will not work */
1383 return STATUS_UNSUCCESSFUL
;
1386 /* allocate filter instance */
1387 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterImpl
));
1390 DPRINT("KspCreateFilter OutOfMemory\n");
1391 return STATUS_INSUFFICIENT_RESOURCES
;
1394 /* initialize object bag */
1395 This
->Filter
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1396 if (!This
->Filter
.Bag
)
1400 DPRINT("KspCreateFilter OutOfMemory\n");
1401 return STATUS_INSUFFICIENT_RESOURCES
;
1403 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->BasicHeader
.OuterUnknown
;
1404 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->Filter
.Bag
, NULL
);
1406 /* copy filter descriptor */
1407 Status
= IKsFilter_CopyFilterDescriptor(This
, Factory
->FilterDescriptor
);
1408 if (!NT_SUCCESS(Status
))
1410 /* not enough memory */
1411 FreeItem(This
->Filter
.Bag
);
1413 DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status
);
1414 return STATUS_INSUFFICIENT_RESOURCES
;
1417 /* get current irp stack */
1418 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1420 /* allocate create items */
1421 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 2);
1425 FreeItem(This
->Filter
.Bag
);
1427 DPRINT("KspCreateFilter OutOfMemory\n");
1428 return STATUS_INSUFFICIENT_RESOURCES
;
1431 DPRINT("KspCreateFilter Flags %lx\n", Factory
->FilterDescriptor
->Flags
);
1433 /* initialize pin create item */
1434 CreateItem
[0].Create
= IKsFilter_DispatchCreatePin
;
1435 CreateItem
[0].Context
= (PVOID
)This
;
1436 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1437 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Pin
);
1438 /* initialize node create item */
1439 CreateItem
[1].Create
= IKsFilter_DispatchCreateNode
;
1440 CreateItem
[1].Context
= (PVOID
)This
;
1441 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1442 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_TopologyNode
);
1445 /* initialize filter instance */
1447 This
->Header
.OuterUnknown
= (PUNKNOWN
)&vt_IKsFilter
;
1448 This
->lpVtblKsControl
= &vt_IKsControl
;
1450 This
->Factory
= Factory
;
1451 This
->FilterFactory
= iface
;
1452 This
->FileObject
= IoStack
->FileObject
;
1453 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1454 /* initialize basic header */
1455 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
1456 This
->Header
.Parent
.KsFilterFactory
= iface
->lpVtbl
->GetStruct(iface
);
1457 This
->Header
.Type
= KsObjectTypeFilter
;
1458 This
->Header
.ControlMutex
= &This
->ControlMutex
;
1459 KeInitializeMutex(This
->Header
.ControlMutex
, 0);
1460 InitializeListHead(&This
->Header
.EventList
);
1461 KeInitializeSpinLock(&This
->Header
.EventListLock
);
1463 /* allocate the stream descriptors */
1464 Status
= IKsFilter_CreateDescriptors(This
, (PKSFILTER_DESCRIPTOR
)Factory
->FilterDescriptor
);
1465 if (!NT_SUCCESS(Status
))
1467 /* what can go wrong, goes wrong */
1469 FreeItem(CreateItem
);
1470 DPRINT("IKsFilter_CreateDescriptors failed with %lx\n", Status
);
1474 /* does the filter have a filter dispatch */
1475 if (Factory
->FilterDescriptor
->Dispatch
)
1477 /* does it have a create routine */
1478 if (Factory
->FilterDescriptor
->Dispatch
->Create
)
1480 /* now let driver initialize the filter instance */
1482 ASSERT(This
->Header
.KsDevice
);
1483 ASSERT(This
->Header
.KsDevice
->Started
);
1484 Status
= Factory
->FilterDescriptor
->Dispatch
->Create(&This
->Filter
, Irp
);
1486 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
1488 /* driver failed to initialize */
1489 DPRINT1("Driver: Status %x\n", Status
);
1491 /* free filter instance */
1493 FreeItem(CreateItem
);
1499 /* now allocate the object header */
1500 Status
= KsAllocateObjectHeader((PVOID
*)&This
->ObjectHeader
, 2, CreateItem
, Irp
, &DispatchTable
);
1501 if (!NT_SUCCESS(Status
))
1503 /* failed to allocate object header */
1504 DPRINT1("Failed to allocate object header %x\n", Status
);
1509 /* initialize object header extra fields */
1510 This
->ObjectHeader
->Type
= KsObjectTypeFilter
;
1511 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->Header
.OuterUnknown
;
1512 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Filter
;
1514 /* attach filter to filter factory */
1515 IKsFilter_AttachFilterToFilterFactory(This
, This
->Header
.Parent
.KsFilterFactory
);
1517 /* completed initialization */
1518 DPRINT("KspCreateFilter done %lx KsDevice %p\n", Status
, This
->Header
.KsDevice
);
1528 KsFilterAcquireProcessingMutex(
1529 IN PKSFILTER Filter
)
1531 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1533 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1542 KsFilterReleaseProcessingMutex(
1543 IN PKSFILTER Filter
)
1545 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1547 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1557 KsFilterAddTopologyConnections (
1558 IN PKSFILTER Filter
,
1559 IN ULONG NewConnectionsCount
,
1560 IN
const KSTOPOLOGY_CONNECTION
*const NewTopologyConnections
)
1564 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1566 DPRINT("KsFilterAddTopologyConnections\n");
1568 ASSERT(This
->Filter
.Descriptor
);
1569 Count
= This
->Filter
.Descriptor
->ConnectionsCount
+ NewConnectionsCount
;
1572 /* modify connections array */
1573 Status
= _KsEdit(This
->Filter
.Bag
,
1574 (PVOID
*)&This
->Filter
.Descriptor
->Connections
,
1575 Count
* sizeof(KSTOPOLOGY_CONNECTION
),
1576 This
->Filter
.Descriptor
->ConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
),
1579 if (!NT_SUCCESS(Status
))
1582 DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status
);
1586 /* FIXME verify connections */
1588 /* copy new connections */
1589 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->Connections
[This
->Filter
.Descriptor
->ConnectionsCount
],
1590 NewTopologyConnections
,
1591 NewConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
));
1593 /* update topology */
1594 This
->Topology
.TopologyConnectionsCount
+= NewConnectionsCount
;
1595 ((PKSFILTER_DESCRIPTOR
)This
->Filter
.Descriptor
)->ConnectionsCount
+= NewConnectionsCount
;
1596 This
->Topology
.TopologyConnections
= This
->Filter
.Descriptor
->Connections
;
1607 KsFilterAttemptProcessing(
1608 IN PKSFILTER Filter
,
1609 IN BOOLEAN Asynchronous
)
1620 KsFilterCreateNode (
1621 IN PKSFILTER Filter
,
1622 IN
const KSNODE_DESCRIPTOR
*const NodeDescriptor
,
1626 return STATUS_NOT_IMPLEMENTED
;
1635 KsFilterCreatePinFactory (
1636 IN PKSFILTER Filter
,
1637 IN
const KSPIN_DESCRIPTOR_EX
*const InPinDescriptor
,
1642 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1644 DPRINT("KsFilterCreatePinFactory\n");
1646 /* calculate new count */
1647 Count
= This
->Filter
.Descriptor
->PinDescriptorsCount
+ 1;
1650 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
1652 /* modify pin descriptors ex array */
1653 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->Filter
.Descriptor
->PinDescriptors
, Count
* This
->Filter
.Descriptor
->PinDescriptorSize
, This
->Filter
.Descriptor
->PinDescriptorsCount
* This
->Filter
.Descriptor
->PinDescriptorSize
, 0);
1654 if (!NT_SUCCESS(Status
))
1657 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1661 /* modify pin instance count array */
1662 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * Count
, sizeof(ULONG
) * This
->Filter
.Descriptor
->PinDescriptorsCount
, 0);
1663 if (!NT_SUCCESS(Status
))
1666 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1670 /* modify first pin array */
1671 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->FirstPin
, sizeof(PKSPIN
) * Count
, sizeof(PKSPIN
) * This
->Filter
.Descriptor
->PinDescriptorsCount
, 0);
1672 if (!NT_SUCCESS(Status
))
1675 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1679 /* add new pin factory */
1680 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->PinDescriptors
[This
->Filter
.Descriptor
->PinDescriptorsCount
], InPinDescriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
1682 /* allocate process pin index */
1683 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
, sizeof(KSPROCESSPIN_INDEXENTRY
) * Count
,
1684 sizeof(KSPROCESSPIN_INDEXENTRY
) * This
->Filter
.Descriptor
->PinDescriptorsCount
, 0);
1686 if (!NT_SUCCESS(Status
))
1688 DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status
);
1692 /* store new pin id */
1693 *PinID
= This
->Filter
.Descriptor
->PinDescriptorsCount
;
1695 /* increment pin descriptor count */
1696 ((PKSFILTER_DESCRIPTOR
)This
->Filter
.Descriptor
)->PinDescriptorsCount
++;
1699 DPRINT("KsFilterCreatePinFactory done\n");
1700 return STATUS_SUCCESS
;
1711 IN PKSFILTER Filter
)
1723 KsFilterGetChildPinCount(
1724 IN PKSFILTER Filter
,
1727 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1729 if (PinId
>= This
->Filter
.Descriptor
->PinDescriptorsCount
)
1731 /* index is out of bounds */
1734 /* return pin instance count */
1735 return This
->PinInstanceCount
[PinId
];
1744 KsFilterGetFirstChildPin(
1745 IN PKSFILTER Filter
,
1748 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1750 if (PinId
>= This
->Filter
.Descriptor
->PinDescriptorsCount
)
1752 /* index is out of bounds */
1756 /* return first pin index */
1757 return This
->FirstPin
[PinId
];
1766 KsFilterRegisterPowerCallbacks(
1767 IN PKSFILTER Filter
,
1768 IN PFNKSFILTERPOWER Sleep OPTIONAL
,
1769 IN PFNKSFILTERPOWER Wake OPTIONAL
)
1771 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1773 This
->Sleep
= Sleep
;
1786 PIO_STACK_LOCATION IoStack
;
1787 PKSIOBJECT_HEADER ObjectHeader
;
1789 DPRINT("KsGetFilterFromIrp\n");
1791 /* get current irp stack location */
1792 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1795 ASSERT(IoStack
->FileObject
);
1797 /* get object header */
1798 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1800 if (ObjectHeader
->Type
== KsObjectTypeFilter
)
1802 /* irp is targeted at the filter */
1803 return (PKSFILTER
)ObjectHeader
->ObjectType
;
1805 else if (ObjectHeader
->Type
== KsObjectTypePin
)
1807 /* irp is for a pin */
1808 return KsPinGetParentFilter((PKSPIN
)ObjectHeader
->ObjectType
);
1812 /* irp is unappropiate to retrieve a filter */