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 IKsFilterVtbl
*lpVtbl
;
18 IKsControlVtbl
*lpVtblKsControl
;
19 IKsFilterFactory
* FilterFactory
;
22 PKSIOBJECT_HEADER ObjectHeader
;
24 KSPIN_DESCRIPTOR_EX
* PinDescriptorsEx
;
25 KSPIN_DESCRIPTOR
* PinDescriptors
;
26 ULONG PinDescriptorCount
;
27 PKSFILTERFACTORY Factory
;
28 PFILE_OBJECT FileObject
;
30 KMUTEX ProcessingMutex
;
33 PFNKSFILTERPOWER Sleep
;
34 PFNKSFILTERPOWER Wake
;
36 ULONG
*PinInstanceCount
;
38 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
42 const GUID IID_IKsControl
= {0x28F54685L
, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
43 const GUID IID_IKsFilter
= {0x3ef6ee44L
, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}};
44 const GUID KSPROPSETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
45 const GUID KSPROPSETID_Pin
= {0x8C134960L
, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
48 IKsFilter_RemoveFilterFromFilterFactory(
50 PKSFILTERFACTORY FilterFactory
);
53 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet
, KspTopologyPropertyHandler
);
54 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet
, KspPinPropertyHandler
, KspPinPropertyHandler
, KspPinPropertyHandler
);
56 KSPROPERTY_SET FilterPropertySet
[] =
59 &KSPROPSETID_Topology
,
60 sizeof(IKsFilterTopologySet
) / sizeof(KSPROPERTY_ITEM
),
61 (const KSPROPERTY_ITEM
*)&IKsFilterTopologySet
,
67 sizeof(IKsFilterPinSet
) / sizeof(KSPROPERTY_ITEM
),
68 (const KSPROPERTY_ITEM
*)&IKsFilterPinSet
,
76 IKsControl_fnQueryInterface(
81 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
83 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
85 *Output
= &This
->lpVtbl
;
86 _InterlockedIncrement(&This
->ref
);
87 return STATUS_SUCCESS
;
89 return STATUS_UNSUCCESSFUL
;
97 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
99 return InterlockedIncrement(&This
->ref
);
104 IKsControl_fnRelease(
107 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
109 InterlockedDecrement(&This
->ref
);
111 /* Return new reference count */
117 IKsControl_fnKsProperty(
119 IN PKSPROPERTY Property
,
120 IN ULONG PropertyLength
,
121 IN OUT PVOID PropertyData
,
123 OUT ULONG
* BytesReturned
)
125 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
127 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, Property
, PropertyLength
, PropertyData
, DataLength
, BytesReturned
);
133 IKsControl_fnKsMethod(
136 IN ULONG MethodLength
,
137 IN OUT PVOID MethodData
,
139 OUT ULONG
* BytesReturned
)
141 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
143 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_METHOD
, Method
, MethodLength
, MethodData
, DataLength
, BytesReturned
);
149 IKsControl_fnKsEvent(
151 IN PKSEVENT Event OPTIONAL
,
152 IN ULONG EventLength
,
153 IN OUT PVOID EventData
,
155 OUT ULONG
* BytesReturned
)
157 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
161 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_ENABLE_EVENT
, Event
, EventLength
, EventData
, DataLength
, BytesReturned
);
165 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_DISABLE_EVENT
, EventData
, DataLength
, NULL
, 0, BytesReturned
);
170 static IKsControlVtbl vt_IKsControl
=
172 IKsControl_fnQueryInterface
,
174 IKsControl_fnRelease
,
175 IKsControl_fnKsProperty
,
176 IKsControl_fnKsMethod
,
183 IKsFilter_fnQueryInterface(
188 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
190 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
) ||
191 IsEqualGUIDAligned(refiid
, &IID_IKsFilter
))
193 *Output
= &This
->lpVtbl
;
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 return STATUS_UNSUCCESSFUL
;
212 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
214 return InterlockedIncrement(&This
->ref
);
222 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
224 InterlockedDecrement(&This
->ref
);
231 /* Return new reference count */
238 IKsFilter_fnGetStruct(
241 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
243 return &This
->Filter
;
248 IKsFilter_fnDoAllNecessaryPinsExist(
257 IKsFilter_fnCreateNode(
261 IN PLIST_ENTRY ListEntry
)
264 return STATUS_NOT_IMPLEMENTED
;
269 IKsFilter_fnBindProcessPinsToPipeSection(
271 IN
struct KSPROCESSPIPESECTION
*Section
,
275 OUT PKSGATE
*OutGate
)
278 return STATUS_NOT_IMPLEMENTED
;
283 IKsFilter_fnUnbindProcessPinsFromPipeSection(
285 IN
struct KSPROCESSPIPESECTION
*Section
)
288 return STATUS_NOT_IMPLEMENTED
;
293 IKsFilter_fnAddProcessPin(
295 IN PKSPROCESSPIN ProcessPin
)
298 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
300 /* first acquire processing mutex */
301 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
304 ASSERT(This
->PinDescriptorCount
> ProcessPin
->Pin
->Id
);
306 /* allocate new process pin array */
307 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
,
308 (This
->PinDescriptorCount
+ 1) * sizeof(PKSPROCESSPIN
),
309 This
->PinDescriptorCount
* sizeof(PKSPROCESSPIN
),
312 if (NT_SUCCESS(Status
))
314 /* store process pin */
315 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
[This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
] = ProcessPin
;
316 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
++;
319 /* release process mutex */
320 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
327 IKsFilter_fnRemoveProcessPin(
329 IN PKSPROCESSPIN ProcessPin
)
333 PKSPROCESSPIN
* Pins
;
335 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
337 /* first acquire processing mutex */
338 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
341 ASSERT(ProcessPin
->Pin
);
342 ASSERT(ProcessPin
->Pin
->Id
);
344 Count
= This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
;
345 Pins
= This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
;
347 /* search for current process pin */
348 for(Index
= 0; Index
< Count
; Index
++)
350 if (Pins
[Index
] == ProcessPin
)
352 RtlMoveMemory(&Pins
[Index
], &Pins
[Index
+ 1], (Count
- (Index
+ 1)) * sizeof(PKSPROCESSPIN
));
358 /* decrement pin count */
359 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
--;
361 if (!This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
)
363 /* clear entry object bag will delete it */
364 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
= NULL
;
367 /* release process mutex */
368 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
371 return STATUS_SUCCESS
;
376 IKsFilter_fnReprepareProcessPipeSection(
378 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
387 IKsFilter_fnDeliverResetState(
389 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
390 IN KSRESET ResetState
)
397 IKsFilter_fnIsFrameHolding(
406 IKsFilter_fnRegisterForCopyCallbacks(
414 PKSPROCESSPIN_INDEXENTRY
416 IKsFilter_fnGetProcessDispatch(
419 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
421 return This
->ProcessPinIndex
;
424 static IKsFilterVtbl vt_IKsFilter
=
426 IKsFilter_fnQueryInterface
,
429 IKsFilter_fnGetStruct
,
430 IKsFilter_fnDoAllNecessaryPinsExist
,
431 IKsFilter_fnCreateNode
,
432 IKsFilter_fnBindProcessPinsToPipeSection
,
433 IKsFilter_fnUnbindProcessPinsFromPipeSection
,
434 IKsFilter_fnAddProcessPin
,
435 IKsFilter_fnRemoveProcessPin
,
436 IKsFilter_fnReprepareProcessPipeSection
,
437 IKsFilter_fnDeliverResetState
,
438 IKsFilter_fnIsFrameHolding
,
439 IKsFilter_fnRegisterForCopyCallbacks
,
440 IKsFilter_fnGetProcessDispatch
444 IKsFilter_GetFilterFromIrp(
446 OUT IKsFilter
**Filter
)
448 PIO_STACK_LOCATION IoStack
;
449 PKSIOBJECT_HEADER ObjectHeader
;
452 /* get current irp stack */
453 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
456 ASSERT(IoStack
->FileObject
!= NULL
);
458 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
460 /* sanity is important */
461 ASSERT(ObjectHeader
!= NULL
);
462 ASSERT(ObjectHeader
->Type
== KsObjectTypeFilter
);
463 ASSERT(ObjectHeader
->Unknown
!= NULL
);
465 /* get our private interface */
466 Status
= ObjectHeader
->Unknown
->lpVtbl
->QueryInterface(ObjectHeader
->Unknown
, &IID_IKsFilter
, (PVOID
*)Filter
);
468 if (!NT_SUCCESS(Status
))
470 /* something is wrong here */
471 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader
->Unknown
);
472 Irp
->IoStatus
.Status
= Status
;
474 /* complete and forget irp */
475 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
484 IKsFilter_DispatchClose(
485 IN PDEVICE_OBJECT DeviceObject
,
489 IKsFilterImpl
* This
;
492 /* obtain filter from object header */
493 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
494 if (!NT_SUCCESS(Status
))
497 /* get our real implementation */
498 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
500 /* does the driver support notifications */
501 if (This
->Factory
->FilterDescriptor
&& This
->Factory
->FilterDescriptor
->Dispatch
&& This
->Factory
->FilterDescriptor
->Dispatch
->Close
)
503 /* call driver's filter close function */
504 Status
= This
->Factory
->FilterDescriptor
->Dispatch
->Close(&This
->Filter
, Irp
);
507 if (NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
509 /* save the result */
510 Irp
->IoStatus
.Status
= Status
;
512 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
514 /* remove our instance from the filter factory */
515 IKsFilter_RemoveFilterFromFilterFactory(This
, This
->Factory
);
517 /* free object header */
518 KsFreeObjectHeader(This
->ObjectHeader
);
522 /* complete and forget */
523 Irp
->IoStatus
.Status
= Status
;
525 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
533 KspHandlePropertyInstances(
534 IN PIO_STATUS_BLOCK IoStatus
,
535 IN PKSIDENTIFIER Request
,
537 IN IKsFilterImpl
* This
,
540 KSPIN_CINSTANCES
* Instances
;
541 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
543 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
545 /* no filter / pin descriptor */
546 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
547 return STATUS_NOT_IMPLEMENTED
;
550 /* ignore custom structs for now */
551 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
552 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
554 Instances
= (KSPIN_CINSTANCES
*)Data
;
555 /* max instance count */
556 Instances
->PossibleCount
= This
->PinDescriptorsEx
[Pin
->PinId
].InstancesPossible
;
557 /* current instance count */
558 Instances
->CurrentCount
= This
->PinInstanceCount
[Pin
->PinId
];
560 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
561 IoStatus
->Status
= STATUS_SUCCESS
;
562 return STATUS_SUCCESS
;
566 KspHandleNecessaryPropertyInstances(
567 IN PIO_STATUS_BLOCK IoStatus
,
568 IN PKSIDENTIFIER Request
,
570 IN IKsFilterImpl
* This
)
573 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
575 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
577 /* no filter / pin descriptor */
578 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
579 return STATUS_NOT_IMPLEMENTED
;
582 /* ignore custom structs for now */
583 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
584 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
586 Result
= (PULONG
)Data
;
587 *Result
= This
->PinDescriptorsEx
[Pin
->PinId
].InstancesNecessary
;
589 IoStatus
->Information
= sizeof(ULONG
);
590 IoStatus
->Status
= STATUS_SUCCESS
;
591 return STATUS_SUCCESS
;
595 KspHandleDataIntersection(
597 IN PIO_STATUS_BLOCK IoStatus
,
598 IN PKSIDENTIFIER Request
,
601 IN IKsFilterImpl
* This
)
603 PKSMULTIPLE_ITEM MultipleItem
;
604 PKSDATARANGE DataRange
;
605 NTSTATUS Status
= STATUS_NO_MATCH
;
607 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
609 /* Access parameters */
610 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
611 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
613 /* FIXME make sure its 64 bit aligned */
614 ASSERT(((ULONG_PTR
)DataRange
& 0x7) == 0);
616 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
618 /* no filter / pin descriptor */
619 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
620 return STATUS_NOT_IMPLEMENTED
;
623 /* ignore custom structs for now */
624 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
625 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
627 if (This
->PinDescriptorsEx
[Pin
->PinId
].IntersectHandler
== NULL
||
628 This
->PinDescriptors
[Pin
->PinId
].DataRanges
== NULL
||
629 This
->PinDescriptors
[Pin
->PinId
].DataRangesCount
== 0)
631 /* no driver supported intersect handler / no provided data ranges */
632 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
633 return STATUS_NOT_IMPLEMENTED
;
636 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
638 UNICODE_STRING MajorFormat
, SubFormat
, Specifier
;
639 /* convert the guid to string */
640 RtlStringFromGUID(&DataRange
->MajorFormat
, &MajorFormat
);
641 RtlStringFromGUID(&DataRange
->SubFormat
, &SubFormat
);
642 RtlStringFromGUID(&DataRange
->Specifier
, &Specifier
);
644 DPRINT("Index %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index
, MajorFormat
.Buffer
, SubFormat
.Buffer
, Specifier
.Buffer
,
645 DataRange
->FormatSize
, DataRange
->SampleSize
, DataRange
->Alignment
, DataRange
->Flags
, DataRange
->Reserved
, DataLength
);
647 /* FIXME implement KsPinDataIntersectionEx */
648 /* Call miniport's properitary handler */
649 Status
= This
->PinDescriptorsEx
[Pin
->PinId
].IntersectHandler(&This
->Filter
,
653 This
->PinDescriptorsEx
[Pin
->PinId
].PinDescriptor
.DataRanges
[0], /* HACK */
658 if (Status
== STATUS_SUCCESS
|| Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
661 IoStatus
->Information
= Length
;
662 if (Status
!= STATUS_SUCCESS
)
663 Status
= STATUS_MORE_ENTRIES
;
667 DataRange
= UlongToPtr(PtrToUlong(DataRange
) + DataRange
->FormatSize
);
668 /* FIXME make sure its 64 bit aligned */
669 ASSERT(((ULONG_PTR
)DataRange
& 0x7) == 0);
672 IoStatus
->Status
= Status
;
678 KspTopologyPropertyHandler(
680 IN PKSIDENTIFIER Request
,
683 IKsFilterImpl
* This
;
685 /* get filter implementation */
686 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
691 return KsTopologyPropertyHandler(Irp
, Request
, Data
, &This
->Topology
);
698 KspPinPropertyHandler(
700 IN PKSIDENTIFIER Request
,
703 PIO_STACK_LOCATION IoStack
;
704 IKsFilterImpl
* This
;
705 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
707 /* get filter implementation */
708 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
713 /* get current stack location */
714 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
718 case KSPROPERTY_PIN_CTYPES
:
719 case KSPROPERTY_PIN_DATAFLOW
:
720 case KSPROPERTY_PIN_DATARANGES
:
721 case KSPROPERTY_PIN_INTERFACES
:
722 case KSPROPERTY_PIN_MEDIUMS
:
723 case KSPROPERTY_PIN_COMMUNICATION
:
724 case KSPROPERTY_PIN_CATEGORY
:
725 case KSPROPERTY_PIN_NAME
:
726 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
727 Status
= KsPinPropertyHandler(Irp
, Request
, Data
, This
->PinDescriptorCount
, This
->PinDescriptors
);
729 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
730 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, TRUE
);
732 case KSPROPERTY_PIN_CINSTANCES
:
733 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, FALSE
);
735 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
736 Status
= KspHandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
);
739 case KSPROPERTY_PIN_DATAINTERSECTION
:
740 Status
= KspHandleDataIntersection(Irp
, &Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
);
744 Status
= STATUS_NOT_FOUND
;
746 //DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status);
754 IKsFilter_DispatchDeviceIoControl(
755 IN PDEVICE_OBJECT DeviceObject
,
758 PIO_STACK_LOCATION IoStack
;
760 IKsFilterImpl
* This
;
762 PKSFILTER FilterInstance
;
763 UNICODE_STRING GuidString
;
764 PKSPROPERTY Property
;
767 /* obtain filter from object header */
768 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
769 if (!NT_SUCCESS(Status
))
772 /* get our real implementation */
773 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
775 /* current irp stack */
776 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
778 /* get property from input buffer */
779 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
782 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSIDENTIFIER
));
784 /* get filter instance */
785 FilterInstance
= Filter
->lpVtbl
->GetStruct(Filter
);
787 RtlStringFromGUID(&Property
->Set
, &GuidString
);
788 DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
789 RtlFreeUnicodeString(&GuidString
);
791 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_METHOD
)
793 const KSMETHOD_SET
*MethodSet
= NULL
;
794 ULONG MethodItemSize
= 0;
796 /* check if the driver supports method sets */
797 if (FilterInstance
->Descriptor
->AutomationTable
&& FilterInstance
->Descriptor
->AutomationTable
->MethodSetsCount
)
799 SetCount
= FilterInstance
->Descriptor
->AutomationTable
->MethodSetsCount
;
800 MethodSet
= FilterInstance
->Descriptor
->AutomationTable
->MethodSets
;
801 MethodItemSize
= FilterInstance
->Descriptor
->AutomationTable
->MethodItemSize
;
804 /* call method set handler */
805 Status
= KspMethodHandlerWithAllocator(Irp
, SetCount
, MethodSet
, NULL
, MethodItemSize
);
807 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
809 const KSPROPERTY_SET
*PropertySet
= NULL
;
810 ULONG PropertyItemSize
= 0;
812 /* check if the driver supports method sets */
813 if (FilterInstance
->Descriptor
->AutomationTable
&& FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
)
815 SetCount
= FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
;
816 PropertySet
= FilterInstance
->Descriptor
->AutomationTable
->PropertySets
;
817 PropertyItemSize
= FilterInstance
->Descriptor
->AutomationTable
->PropertyItemSize
;
820 /* needed for our property handlers */
821 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
823 /* call property handler */
824 Status
= KspPropertyHandler(Irp
, SetCount
, PropertySet
, NULL
, PropertyItemSize
);
829 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
||
830 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_DISABLE_EVENT
);
832 Status
= STATUS_NOT_FOUND
;
836 RtlStringFromGUID(&Property
->Set
, &GuidString
);
837 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
);
838 RtlFreeUnicodeString(&GuidString
);
841 Filter
->lpVtbl
->Release(Filter
);
843 if (Status
!= STATUS_PENDING
)
845 Irp
->IoStatus
.Status
= Status
;
846 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
853 static KSDISPATCH_TABLE DispatchTable
=
855 IKsFilter_DispatchDeviceIoControl
,
856 KsDispatchInvalidDeviceRequest
,
857 KsDispatchInvalidDeviceRequest
,
858 KsDispatchInvalidDeviceRequest
,
859 IKsFilter_DispatchClose
,
860 KsDispatchQuerySecurity
,
861 KsDispatchSetSecurity
,
862 KsDispatchFastIoDeviceControlFailure
,
863 KsDispatchFastReadFailure
,
864 KsDispatchFastReadFailure
,
869 IKsFilter_CreateDescriptors(
870 IKsFilterImpl
* This
,
871 KSFILTER_DESCRIPTOR
* FilterDescriptor
)
876 /* initialize pin descriptors */
877 This
->FirstPin
= NULL
;
878 This
->PinInstanceCount
= NULL
;
879 This
->PinDescriptors
= NULL
;
880 This
->PinDescriptorsEx
= NULL
;
881 This
->ProcessPinIndex
= NULL
;
882 This
->PinDescriptorCount
= 0;
884 /* initialize topology descriptor */
885 This
->Topology
.CategoriesCount
= FilterDescriptor
->CategoriesCount
;
886 This
->Topology
.Categories
= FilterDescriptor
->Categories
;
887 This
->Topology
.TopologyNodesCount
= FilterDescriptor
->NodeDescriptorsCount
;
888 This
->Topology
.TopologyConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
889 This
->Topology
.TopologyConnections
= FilterDescriptor
->Connections
;
891 /* are there any templates */
892 if (FilterDescriptor
->PinDescriptorsCount
)
895 ASSERT(FilterDescriptor
->PinDescriptors
);
897 /* FIXME handle variable sized pin descriptors */
898 ASSERT(FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
900 /* store pin descriptors ex */
901 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptorsEx
, sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
,
902 sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
, 0);
904 if (!NT_SUCCESS(Status
))
906 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
910 /* store pin descriptors */
911 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptors
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescriptor
->PinDescriptorsCount
,
912 sizeof(KSPIN_DESCRIPTOR
) * FilterDescriptor
->PinDescriptorsCount
, 0);
914 if (!NT_SUCCESS(Status
))
916 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
920 /* store pin instance count ex */
921 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
,
922 sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
, 0);
924 if (!NT_SUCCESS(Status
))
926 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
930 /* store instantiated pin arrays */
931 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->FirstPin
, sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
,
932 sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
, 0);
934 if (!NT_SUCCESS(Status
))
936 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
940 /* add new pin factory */
941 RtlMoveMemory(This
->PinDescriptorsEx
, FilterDescriptor
->PinDescriptors
, sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
);
943 for(Index
= 0; Index
< FilterDescriptor
->PinDescriptorsCount
; Index
++)
945 RtlMoveMemory(&This
->PinDescriptors
[Index
], &FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
948 /* allocate process pin index */
949 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
, sizeof(KSPROCESSPIN_INDEXENTRY
) * FilterDescriptor
->PinDescriptorsCount
,
950 sizeof(KSPROCESSPIN_INDEXENTRY
) * FilterDescriptor
->PinDescriptorsCount
, 0);
952 if (!NT_SUCCESS(Status
))
954 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
958 /* store new pin descriptor count */
959 This
->PinDescriptorCount
= FilterDescriptor
->PinDescriptorsCount
;
963 if (FilterDescriptor
->NodeDescriptorsCount
)
966 ASSERT(FilterDescriptor
->NodeDescriptors
);
968 /* FIXME handle variable sized node descriptors */
969 ASSERT(FilterDescriptor
->NodeDescriptorSize
== sizeof(KSNODE_DESCRIPTOR
));
971 This
->Topology
.TopologyNodes
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
972 /* allocate topology node types array */
973 if (!This
->Topology
.TopologyNodes
)
975 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
976 return STATUS_INSUFFICIENT_RESOURCES
;
979 This
->Topology
.TopologyNodesNames
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
980 /* allocate topology names array */
981 if (!This
->Topology
.TopologyNodesNames
)
983 FreeItem((PVOID
)This
->Topology
.TopologyNodes
);
984 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
985 return STATUS_INSUFFICIENT_RESOURCES
;
988 DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
989 for(Index
= 0; Index
< FilterDescriptor
->NodeDescriptorsCount
; Index
++)
991 DPRINT("Index %lu Type %p Name %p\n", Index
, FilterDescriptor
->NodeDescriptors
[Index
].Type
, FilterDescriptor
->NodeDescriptors
[Index
].Name
);
993 /* copy topology type */
994 if (FilterDescriptor
->NodeDescriptors
[Index
].Type
)
995 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodes
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Type
, sizeof(GUID
));
997 /* copy topology name */
998 if (FilterDescriptor
->NodeDescriptors
[Index
].Name
)
999 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodesNames
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Name
, sizeof(GUID
));
1003 return STATUS_SUCCESS
;
1007 IKsFilter_CopyFilterDescriptor(
1008 IKsFilterImpl
* This
,
1009 const KSFILTER_DESCRIPTOR
* FilterDescriptor
)
1012 KSAUTOMATION_TABLE AutomationTable
;
1014 This
->Filter
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSFILTER_DESCRIPTOR
));
1015 if (!This
->Filter
.Descriptor
)
1016 return STATUS_INSUFFICIENT_RESOURCES
;
1018 Status
= KsAddItemToObjectBag(This
->Filter
.Bag
, (PVOID
)This
->Filter
.Descriptor
, NULL
);
1019 if (!NT_SUCCESS(Status
))
1021 FreeItem((PVOID
)This
->Filter
.Descriptor
);
1022 This
->Filter
.Descriptor
= NULL
;
1023 return STATUS_INSUFFICIENT_RESOURCES
;
1026 /* copy filter descriptor fields */
1027 RtlMoveMemory((PVOID
)This
->Filter
.Descriptor
, FilterDescriptor
, sizeof(KSFILTER_DESCRIPTOR
));
1029 /* zero automation table */
1030 RtlZeroMemory(&AutomationTable
, sizeof(KSAUTOMATION_TABLE
));
1032 /* setup filter property sets */
1033 AutomationTable
.PropertyItemSize
= sizeof(KSPROPERTY_ITEM
);
1034 AutomationTable
.PropertySetsCount
= 2;
1035 AutomationTable
.PropertySets
= FilterPropertySet
;
1037 /* merge filter automation table */
1038 Status
= KsMergeAutomationTables((PKSAUTOMATION_TABLE
*)&This
->Filter
.Descriptor
->AutomationTable
, (PKSAUTOMATION_TABLE
)FilterDescriptor
->AutomationTable
, &AutomationTable
, This
->Filter
.Bag
);
1049 PKSPIN NextPin
, CurPin
;
1050 PKSBASIC_HEADER BasicHeader
;
1051 IKsFilterImpl
* This
= (IKsFilterImpl
*)Filter
;
1054 ASSERT(Pin
->Id
< This
->PinDescriptorCount
);
1056 if (This
->FirstPin
[Pin
->Id
] == NULL
)
1058 /* welcome first pin */
1059 This
->FirstPin
[Pin
->Id
] = Pin
;
1060 return STATUS_SUCCESS
;
1064 CurPin
= This
->FirstPin
[Pin
->Id
];
1068 /* get next instantiated pin */
1069 NextPin
= KsPinGetNextSiblingPin(CurPin
);
1075 }while(NextPin
!= NULL
);
1077 /* get basic header */
1078 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)CurPin
- sizeof(KSBASIC_HEADER
));
1081 BasicHeader
->Next
.Pin
= Pin
;
1083 return STATUS_SUCCESS
;
1089 IKsFilter_DispatchCreatePin(
1090 IN PDEVICE_OBJECT DeviceObject
,
1093 IKsFilterImpl
* This
;
1094 PKSOBJECT_CREATE_ITEM CreateItem
;
1095 PKSPIN_CONNECT Connect
;
1098 DPRINT("IKsFilter_DispatchCreatePin\n");
1100 /* get the create item */
1101 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
1103 /* get the filter object */
1104 This
= (IKsFilterImpl
*)CreateItem
->Context
;
1107 ASSERT(This
->Header
.Type
== KsObjectTypeFilter
);
1109 /* acquire control mutex */
1110 KeWaitForSingleObject(This
->Header
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1112 /* now validate the connect request */
1113 Status
= KsValidateConnectRequest(Irp
, This
->PinDescriptorCount
, This
->PinDescriptors
, &Connect
);
1115 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status
);
1117 if (NT_SUCCESS(Status
))
1120 ASSERT(Connect
->PinId
< This
->PinDescriptorCount
);
1122 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect
->PinId
,
1123 This
->PinInstanceCount
[Connect
->PinId
],
1124 This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
);
1126 if (This
->PinInstanceCount
[Connect
->PinId
] < This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
)
1128 /* create the pin */
1129 Status
= KspCreatePin(DeviceObject
, Irp
, This
->Header
.KsDevice
, This
->FilterFactory
, (IKsFilter
*)&This
->lpVtbl
, Connect
, &This
->PinDescriptorsEx
[Connect
->PinId
]);
1131 DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status
);
1133 if (NT_SUCCESS(Status
))
1135 /* successfully created pin, increment pin instance count */
1136 This
->PinInstanceCount
[Connect
->PinId
]++;
1141 /* maximum instance count reached, bye-bye */
1142 Status
= STATUS_UNSUCCESSFUL
;
1143 DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
, This
->PinInstanceCount
[Connect
->PinId
]);
1147 /* release control mutex */
1148 KeReleaseMutex(This
->Header
.ControlMutex
, FALSE
);
1150 if (Status
!= STATUS_PENDING
)
1152 /* complete request */
1153 Irp
->IoStatus
.Status
= Status
;
1154 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1158 DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status
);
1164 IKsFilter_DispatchCreateNode(
1165 IN PDEVICE_OBJECT DeviceObject
,
1169 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1170 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1171 return STATUS_UNSUCCESSFUL
;
1176 IKsFilter_AttachFilterToFilterFactory(
1177 IKsFilterImpl
* This
,
1178 PKSFILTERFACTORY FilterFactory
)
1180 PKSBASIC_HEADER BasicHeader
;
1184 /* get filter factory basic header */
1185 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1188 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1190 if (BasicHeader
->FirstChild
.FilterFactory
== NULL
)
1192 /* welcome first instantiated filter */
1193 BasicHeader
->FirstChild
.Filter
= &This
->Filter
;
1197 /* set to first entry */
1198 Filter
= BasicHeader
->FirstChild
.Filter
;
1202 /* get basic header */
1203 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1205 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1207 if (BasicHeader
->Next
.Filter
)
1209 /* iterate to next filter factory */
1210 Filter
= BasicHeader
->Next
.Filter
;
1214 /* found last entry */
1219 /* attach filter factory */
1220 BasicHeader
->Next
.Filter
= &This
->Filter
;
1224 IKsFilter_RemoveFilterFromFilterFactory(
1225 IKsFilterImpl
* This
,
1226 PKSFILTERFACTORY FilterFactory
)
1228 PKSBASIC_HEADER BasicHeader
;
1229 PKSFILTER Filter
, LastFilter
;
1231 /* get filter factory basic header */
1232 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1235 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1236 ASSERT(BasicHeader
->FirstChild
.Filter
!= NULL
);
1239 /* set to first entry */
1240 Filter
= BasicHeader
->FirstChild
.Filter
;
1245 if (Filter
== &This
->Filter
)
1249 /* get basic header */
1250 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)LastFilter
- sizeof(KSBASIC_HEADER
));
1251 /* remove filter instance */
1252 BasicHeader
->Next
.Filter
= This
->Header
.Next
.Filter
;
1257 /* remove filter instance */
1258 BasicHeader
->FirstChild
.Filter
= This
->Header
.Next
.Filter
;
1263 /* get basic header */
1264 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1266 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1268 LastFilter
= Filter
;
1269 if (BasicHeader
->Next
.Filter
)
1271 /* iterate to next filter factory */
1272 Filter
= BasicHeader
->Next
.Filter
;
1276 /* filter is not in list */
1286 IN PDEVICE_OBJECT DeviceObject
,
1288 IN IKsFilterFactory
*iface
)
1290 IKsFilterImpl
* This
;
1291 IKsDevice
*KsDevice
;
1292 PKSFILTERFACTORY Factory
;
1293 PIO_STACK_LOCATION IoStack
;
1294 PDEVICE_EXTENSION DeviceExtension
;
1296 PKSOBJECT_CREATE_ITEM CreateItem
;
1298 /* get device extension */
1299 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1301 /* get the filter factory */
1302 Factory
= iface
->lpVtbl
->GetStruct(iface
);
1304 if (!Factory
|| !Factory
->FilterDescriptor
|| !Factory
->FilterDescriptor
->Dispatch
|| !Factory
->FilterDescriptor
->Dispatch
->Create
)
1306 /* Sorry it just will not work */
1307 return STATUS_UNSUCCESSFUL
;
1310 /* allocate filter instance */
1311 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterImpl
));
1314 DPRINT("KspCreateFilter OutOfMemory\n");
1315 return STATUS_INSUFFICIENT_RESOURCES
;
1318 /* initialize object bag */
1319 This
->Filter
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1320 if (!This
->Filter
.Bag
)
1324 DPRINT("KspCreateFilter OutOfMemory\n");
1325 return STATUS_INSUFFICIENT_RESOURCES
;
1327 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
1328 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->Filter
.Bag
, NULL
);
1330 /* copy filter descriptor */
1331 Status
= IKsFilter_CopyFilterDescriptor(This
, Factory
->FilterDescriptor
);
1332 if (!NT_SUCCESS(Status
))
1334 /* not enough memory */
1335 FreeItem(This
->Filter
.Bag
);
1337 DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status
);
1338 return STATUS_INSUFFICIENT_RESOURCES
;
1341 /* get current irp stack */
1342 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1344 /* allocate create items */
1345 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 2);
1349 FreeItem(This
->Filter
.Bag
);
1351 DPRINT("KspCreateFilter OutOfMemory\n");
1352 return STATUS_INSUFFICIENT_RESOURCES
;
1355 DPRINT("KspCreateFilter Flags %lx\n", Factory
->FilterDescriptor
->Flags
);
1357 /* initialize pin create item */
1358 CreateItem
[0].Create
= IKsFilter_DispatchCreatePin
;
1359 CreateItem
[0].Context
= (PVOID
)This
;
1360 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1361 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Pin
);
1362 /* initialize node create item */
1363 CreateItem
[1].Create
= IKsFilter_DispatchCreateNode
;
1364 CreateItem
[1].Context
= (PVOID
)This
;
1365 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1366 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_TopologyNode
);
1369 /* initialize filter instance */
1371 This
->lpVtbl
= &vt_IKsFilter
;
1372 This
->lpVtblKsControl
= &vt_IKsControl
;
1374 This
->Factory
= Factory
;
1375 This
->FilterFactory
= iface
;
1376 This
->FileObject
= IoStack
->FileObject
;
1377 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1378 /* initialize basic header */
1379 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
1380 This
->Header
.Parent
.KsFilterFactory
= iface
->lpVtbl
->GetStruct(iface
);
1381 This
->Header
.Type
= KsObjectTypeFilter
;
1382 This
->Header
.ControlMutex
= &This
->ControlMutex
;
1383 KeInitializeMutex(This
->Header
.ControlMutex
, 0);
1384 InitializeListHead(&This
->Header
.EventList
);
1385 KeInitializeSpinLock(&This
->Header
.EventListLock
);
1387 /* allocate the stream descriptors */
1388 Status
= IKsFilter_CreateDescriptors(This
, (PKSFILTER_DESCRIPTOR
)Factory
->FilterDescriptor
);
1389 if (!NT_SUCCESS(Status
))
1391 /* what can go wrong, goes wrong */
1393 FreeItem(CreateItem
);
1394 DPRINT("IKsFilter_CreateDescriptors failed with %lx\n", Status
);
1398 /* does the filter have a filter dispatch */
1399 if (Factory
->FilterDescriptor
->Dispatch
)
1401 /* does it have a create routine */
1402 if (Factory
->FilterDescriptor
->Dispatch
->Create
)
1404 /* now let driver initialize the filter instance */
1406 ASSERT(This
->Header
.KsDevice
);
1407 ASSERT(This
->Header
.KsDevice
->Started
);
1408 Status
= Factory
->FilterDescriptor
->Dispatch
->Create(&This
->Filter
, Irp
);
1410 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
1412 /* driver failed to initialize */
1413 DPRINT1("Driver: Status %x\n", Status
);
1415 /* free filter instance */
1417 FreeItem(CreateItem
);
1423 /* now allocate the object header */
1424 Status
= KsAllocateObjectHeader((PVOID
*)&This
->ObjectHeader
, 2, CreateItem
, Irp
, &DispatchTable
);
1425 if (!NT_SUCCESS(Status
))
1427 /* failed to allocate object header */
1428 DPRINT1("Failed to allocate object header %x\n", Status
);
1433 /* initialize object header extra fields */
1434 This
->ObjectHeader
->Type
= KsObjectTypeFilter
;
1435 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
1436 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Filter
;
1438 /* attach filter to filter factory */
1439 IKsFilter_AttachFilterToFilterFactory(This
, This
->Header
.Parent
.KsFilterFactory
);
1441 /* completed initialization */
1442 DPRINT("KspCreateFilter done %lx\n", Status
);
1452 KsFilterAcquireProcessingMutex(
1453 IN PKSFILTER Filter
)
1455 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1457 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1466 KsFilterReleaseProcessingMutex(
1467 IN PKSFILTER Filter
)
1469 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1471 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1480 KsFilterAddTopologyConnections (
1481 IN PKSFILTER Filter
,
1482 IN ULONG NewConnectionsCount
,
1483 IN
const KSTOPOLOGY_CONNECTION
*const NewTopologyConnections
)
1486 KSTOPOLOGY_CONNECTION
* Connections
;
1487 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1489 Count
= This
->Filter
.Descriptor
->ConnectionsCount
+ NewConnectionsCount
;
1491 /* allocate array */
1492 Connections
= AllocateItem(NonPagedPool
, Count
* sizeof(KSTOPOLOGY_CONNECTION
));
1494 return STATUS_INSUFFICIENT_RESOURCES
;
1496 /* FIXME verify connections */
1498 if (This
->Filter
.Descriptor
->ConnectionsCount
)
1500 /* copy old connections */
1501 RtlMoveMemory(Connections
, This
->Filter
.Descriptor
->Connections
, sizeof(KSTOPOLOGY_CONNECTION
) * This
->Filter
.Descriptor
->ConnectionsCount
);
1504 /* add new connections */
1505 RtlMoveMemory((PVOID
)(Connections
+ This
->Filter
.Descriptor
->ConnectionsCount
), NewTopologyConnections
, NewConnectionsCount
);
1507 /* add the new connections */
1508 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->ConnectionsCount
, &Count
, sizeof(ULONG
)); /* brain-dead gcc hack */
1510 /* free old connections array */
1511 if (This
->Filter
.Descriptor
->ConnectionsCount
)
1513 FreeItem((PVOID
)This
->Filter
.Descriptor
->Connections
);
1516 /* brain-dead gcc hack */
1517 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->Connections
, Connections
, sizeof(KSTOPOLOGY_CONNECTION
*));
1519 return STATUS_SUCCESS
;
1528 KsFilterAttemptProcessing(
1529 IN PKSFILTER Filter
,
1530 IN BOOLEAN Asynchronous
)
1541 KsFilterCreateNode (
1542 IN PKSFILTER Filter
,
1543 IN
const KSNODE_DESCRIPTOR
*const NodeDescriptor
,
1547 return STATUS_NOT_IMPLEMENTED
;
1556 KsFilterCreatePinFactory (
1557 IN PKSFILTER Filter
,
1558 IN
const KSPIN_DESCRIPTOR_EX
*const InPinDescriptor
,
1563 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1565 DPRINT("KsFilterCreatePinFactory\n");
1567 /* calculate new count */
1568 Count
= This
->PinDescriptorCount
+ 1;
1571 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
1573 /* allocate pin descriptors ex array */
1574 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptorsEx
, Count
* sizeof(KSPIN_DESCRIPTOR_EX
), This
->PinDescriptorCount
* sizeof(KSPIN_DESCRIPTOR_EX
), 0);
1575 if (!NT_SUCCESS(Status
))
1578 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1582 /* allocate pin descriptors array */
1583 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptors
, Count
* sizeof(KSPIN_DESCRIPTOR
), This
->PinDescriptorCount
* sizeof(KSPIN_DESCRIPTOR
), 0);
1584 if (!NT_SUCCESS(Status
))
1587 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1592 /* allocate pin instance count array */
1593 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * Count
, sizeof(ULONG
) * This
->PinDescriptorCount
, 0);
1594 if (!NT_SUCCESS(Status
))
1597 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1601 /* allocate first pin array */
1602 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->FirstPin
, sizeof(PKSPIN
) * Count
, sizeof(PKSPIN
) * This
->PinDescriptorCount
, 0);
1603 if (!NT_SUCCESS(Status
))
1606 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1610 /* add new pin factory */
1611 RtlMoveMemory(&This
->PinDescriptorsEx
[This
->PinDescriptorCount
], InPinDescriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
1612 RtlMoveMemory(&This
->PinDescriptors
[This
->PinDescriptorCount
], &InPinDescriptor
->PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
1615 /* allocate process pin index */
1616 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
, sizeof(KSPROCESSPIN_INDEXENTRY
) * Count
,
1617 sizeof(KSPROCESSPIN_INDEXENTRY
) * This
->PinDescriptorCount
, 0);
1619 if (!NT_SUCCESS(Status
))
1621 DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status
);
1625 /* store new pin id */
1626 *PinID
= This
->PinDescriptorCount
;
1628 /* increment pin descriptor count */
1629 This
->PinDescriptorCount
++;
1632 DPRINT("KsFilterCreatePinFactory done\n");
1633 return STATUS_SUCCESS
;
1644 IN PKSFILTER Filter
)
1656 KsFilterGetChildPinCount(
1657 IN PKSFILTER Filter
,
1660 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1662 if (PinId
>= This
->PinDescriptorCount
)
1664 /* index is out of bounds */
1667 /* return pin instance count */
1668 return This
->PinInstanceCount
[PinId
];
1677 KsFilterGetFirstChildPin(
1678 IN PKSFILTER Filter
,
1681 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1683 if (PinId
>= This
->PinDescriptorCount
)
1685 /* index is out of bounds */
1689 /* return first pin index */
1690 return This
->FirstPin
[PinId
];
1699 KsFilterRegisterPowerCallbacks(
1700 IN PKSFILTER Filter
,
1701 IN PFNKSFILTERPOWER Sleep OPTIONAL
,
1702 IN PFNKSFILTERPOWER Wake OPTIONAL
)
1704 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1706 This
->Sleep
= Sleep
;
1719 PIO_STACK_LOCATION IoStack
;
1720 PKSIOBJECT_HEADER ObjectHeader
;
1722 DPRINT("KsGetFilterFromIrp\n");
1724 /* get current irp stack location */
1725 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1728 ASSERT(IoStack
->FileObject
);
1730 /* get object header */
1731 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1733 if (ObjectHeader
->Type
== KsObjectTypeFilter
)
1735 /* irp is targeted at the filter */
1736 return (PKSFILTER
)ObjectHeader
->ObjectType
;
1738 else if (ObjectHeader
->Type
== KsObjectTypePin
)
1740 /* irp is for a pin */
1741 return KsPinGetParentFilter((PKSPIN
)ObjectHeader
->ObjectType
);
1745 /* irp is unappropiate to retrieve a filter */