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
* PinDescriptors
;
25 ULONG PinDescriptorCount
;
26 PKSFILTERFACTORY Factory
;
27 PFILE_OBJECT FileObject
;
30 ULONG
*PinInstanceCount
;
33 const GUID IID_IKsControl
= {0x28F54685L
, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
34 const GUID IID_IKsFilter
= {0x3ef6ee44L
, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}};
35 const GUID KSPROPSETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
36 const GUID KSPROPSETID_Pin
= {0x8C134960L
, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
39 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet
, KspTopologyPropertyHandler
);
40 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet
, KspPinPropertyHandler
, KspPinPropertyHandler
, KspPinPropertyHandler
);
42 KSPROPERTY_SET FilterPropertySet
[] =
45 &KSPROPSETID_Topology
,
46 sizeof(IKsFilterTopologySet
) / sizeof(KSPROPERTY_ITEM
),
47 (const KSPROPERTY_ITEM
*)&IKsFilterTopologySet
,
53 sizeof(IKsFilterPinSet
) / sizeof(KSPROPERTY_ITEM
),
54 (const KSPROPERTY_ITEM
*)&IKsFilterPinSet
,
62 IKsControl_fnQueryInterface(
67 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
69 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
71 *Output
= &This
->lpVtbl
;
72 _InterlockedIncrement(&This
->ref
);
73 return STATUS_SUCCESS
;
75 return STATUS_UNSUCCESSFUL
;
83 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
85 return InterlockedIncrement(&This
->ref
);
93 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
95 InterlockedDecrement(&This
->ref
);
97 /* Return new reference count */
103 IKsControl_fnKsProperty(
105 IN PKSPROPERTY Property
,
106 IN ULONG PropertyLength
,
107 IN OUT PVOID PropertyData
,
109 OUT ULONG
* BytesReturned
)
111 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
113 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, Property
, PropertyLength
, PropertyData
, DataLength
, BytesReturned
);
119 IKsControl_fnKsMethod(
122 IN ULONG MethodLength
,
123 IN OUT PVOID MethodData
,
125 OUT ULONG
* BytesReturned
)
127 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
129 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_METHOD
, Method
, MethodLength
, MethodData
, DataLength
, BytesReturned
);
135 IKsControl_fnKsEvent(
137 IN PKSEVENT Event OPTIONAL
,
138 IN ULONG EventLength
,
139 IN OUT PVOID EventData
,
141 OUT ULONG
* BytesReturned
)
143 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
147 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_ENABLE_EVENT
, Event
, EventLength
, EventData
, DataLength
, BytesReturned
);
151 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_DISABLE_EVENT
, EventData
, DataLength
, NULL
, 0, BytesReturned
);
156 static IKsControlVtbl vt_IKsControl
=
158 IKsControl_fnQueryInterface
,
160 IKsControl_fnRelease
,
161 IKsControl_fnKsProperty
,
162 IKsControl_fnKsMethod
,
169 IKsFilter_fnQueryInterface(
174 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
176 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
) ||
177 IsEqualGUIDAligned(refiid
, &IID_IKsFilter
))
179 *Output
= &This
->lpVtbl
;
180 _InterlockedIncrement(&This
->ref
);
181 return STATUS_SUCCESS
;
183 else if (IsEqualGUIDAligned(refiid
, &IID_IKsControl
))
185 *Output
= &This
->lpVtblKsControl
;
186 _InterlockedIncrement(&This
->ref
);
187 return STATUS_SUCCESS
;
190 return STATUS_UNSUCCESSFUL
;
198 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
200 return InterlockedIncrement(&This
->ref
);
208 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
210 InterlockedDecrement(&This
->ref
);
217 /* Return new reference count */
224 IKsFilter_fnGetStruct(
227 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
229 return &This
->Filter
;
234 IKsFilter_fnDoAllNecessaryPinsExist(
243 IKsFilter_fnCreateNode(
247 IN PLIST_ENTRY ListEntry
)
250 return STATUS_NOT_IMPLEMENTED
;
255 IKsFilter_fnBindProcessPinsToPipeSection(
257 IN
struct KSPROCESSPIPESECTION
*Section
,
261 OUT PKSGATE
*OutGate
)
264 return STATUS_NOT_IMPLEMENTED
;
269 IKsFilter_fnUnbindProcessPinsFromPipeSection(
271 IN
struct KSPROCESSPIPESECTION
*Section
)
274 return STATUS_NOT_IMPLEMENTED
;
279 IKsFilter_fnAddProcessPin(
281 IN PKSPROCESSPIN ProcessPin
)
284 return STATUS_NOT_IMPLEMENTED
;
289 IKsFilter_fnRemoveProcessPin(
291 IN PKSPROCESSPIN ProcessPin
)
294 return STATUS_NOT_IMPLEMENTED
;
299 IKsFilter_fnReprepareProcessPipeSection(
301 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
310 IKsFilter_fnDeliverResetState(
312 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
313 IN KSRESET ResetState
)
320 IKsFilter_fnIsFrameHolding(
329 IKsFilter_fnRegisterForCopyCallbacks(
337 PKSPROCESSPIN_INDEXENTRY
339 IKsFilter_fnGetProcessDispatch(
346 static IKsFilterVtbl vt_IKsFilter
=
348 IKsFilter_fnQueryInterface
,
351 IKsFilter_fnGetStruct
,
352 IKsFilter_fnDoAllNecessaryPinsExist
,
353 IKsFilter_fnCreateNode
,
354 IKsFilter_fnBindProcessPinsToPipeSection
,
355 IKsFilter_fnUnbindProcessPinsFromPipeSection
,
356 IKsFilter_fnAddProcessPin
,
357 IKsFilter_fnRemoveProcessPin
,
358 IKsFilter_fnReprepareProcessPipeSection
,
359 IKsFilter_fnDeliverResetState
,
360 IKsFilter_fnIsFrameHolding
,
361 IKsFilter_fnRegisterForCopyCallbacks
,
362 IKsFilter_fnGetProcessDispatch
366 IKsFilter_GetFilterFromIrp(
368 OUT IKsFilter
**Filter
)
370 PIO_STACK_LOCATION IoStack
;
371 PKSIOBJECT_HEADER ObjectHeader
;
374 /* get current irp stack */
375 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
378 ASSERT(IoStack
->FileObject
!= NULL
);
380 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext
;
382 /* sanity is important */
383 ASSERT(ObjectHeader
!= NULL
);
384 ASSERT(ObjectHeader
->Type
== KsObjectTypeFilter
);
385 ASSERT(ObjectHeader
->Unknown
!= NULL
);
387 /* get our private interface */
388 Status
= ObjectHeader
->Unknown
->lpVtbl
->QueryInterface(ObjectHeader
->Unknown
, &IID_IKsFilter
, (PVOID
*)Filter
);
390 if (!NT_SUCCESS(Status
))
392 /* something is wrong here */
393 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader
->Unknown
);
394 Irp
->IoStatus
.Status
= Status
;
396 /* complete and forget irp */
397 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
406 IKsFilter_DispatchClose(
407 IN PDEVICE_OBJECT DeviceObject
,
411 IKsFilterImpl
* This
;
414 /* obtain filter from object header */
415 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
416 if (!NT_SUCCESS(Status
))
419 /* get our real implementation */
420 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
422 /* does the driver support notifications */
423 if (This
->Factory
->FilterDescriptor
&& This
->Factory
->FilterDescriptor
->Dispatch
&& This
->Factory
->FilterDescriptor
->Dispatch
->Close
)
425 /* call driver's filter close function */
426 Status
= This
->Factory
->FilterDescriptor
->Dispatch
->Close(&This
->Filter
, Irp
);
429 if (Status
!= STATUS_PENDING
)
431 /* save the result */
432 Irp
->IoStatus
.Status
= Status
;
434 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
436 /* remove our instance from the filter factory */
437 This
->FilterFactory
->lpVtbl
->RemoveFilterInstance(This
->FilterFactory
, Filter
);
439 /* now release the acquired interface */
440 Filter
->lpVtbl
->Release(Filter
);
442 /* free object header */
443 KsFreeObjectHeader(This
->ObjectHeader
);
451 KspHandlePropertyInstances(
452 IN PIO_STATUS_BLOCK IoStatus
,
453 IN PKSIDENTIFIER Request
,
455 IN IKsFilterImpl
* This
,
458 KSPIN_CINSTANCES
* Instances
;
459 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
461 if (!This
->Factory
->FilterDescriptor
|| !This
->Factory
->FilterDescriptor
->PinDescriptorsCount
)
463 /* no filter / pin descriptor */
464 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
465 return STATUS_NOT_IMPLEMENTED
;
468 /* ignore custom structs for now */
469 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
470 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorsCount
> Pin
->PinId
);
472 Instances
= (KSPIN_CINSTANCES
*)Data
;
473 /* max instance count */
474 Instances
->PossibleCount
= This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].InstancesPossible
;
475 /* current instance count */
476 Instances
->CurrentCount
= This
->PinInstanceCount
[Pin
->PinId
];
478 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
479 IoStatus
->Status
= STATUS_SUCCESS
;
480 return STATUS_SUCCESS
;
484 KspHandleNecessaryPropertyInstances(
485 IN PIO_STATUS_BLOCK IoStatus
,
486 IN PKSIDENTIFIER Request
,
488 IN IKsFilterImpl
* This
)
491 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
493 if (!This
->Factory
->FilterDescriptor
|| !This
->Factory
->FilterDescriptor
->PinDescriptorsCount
)
495 /* no filter / pin descriptor */
496 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
497 return STATUS_NOT_IMPLEMENTED
;
500 /* ignore custom structs for now */
501 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
502 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorsCount
> Pin
->PinId
);
504 Result
= (PULONG
)Data
;
505 *Result
= This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].InstancesNecessary
;
507 IoStatus
->Information
= sizeof(ULONG
);
508 IoStatus
->Status
= STATUS_SUCCESS
;
509 return STATUS_SUCCESS
;
513 KspHandleDataIntersection(
515 IN PIO_STATUS_BLOCK IoStatus
,
516 IN PKSIDENTIFIER Request
,
519 IN IKsFilterImpl
* This
)
521 PKSMULTIPLE_ITEM MultipleItem
;
522 PKSDATARANGE DataRange
;
523 NTSTATUS Status
= STATUS_NO_MATCH
;
525 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
527 /* Access parameters */
528 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
529 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
531 if (!This
->Factory
->FilterDescriptor
|| !This
->Factory
->FilterDescriptor
->PinDescriptorsCount
)
533 /* no filter / pin descriptor */
534 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
535 return STATUS_NOT_IMPLEMENTED
;
538 /* ignore custom structs for now */
539 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
540 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorsCount
> Pin
->PinId
);
542 if (This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].IntersectHandler
== NULL
||
543 This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
== NULL
||
544 This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRangesCount
== 0)
546 /* no driver supported intersect handler / no provided data ranges */
547 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
548 return STATUS_NOT_IMPLEMENTED
;
551 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
553 /* Call miniport's properitary handler */
554 Status
= This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].IntersectHandler(NULL
, /* context */
558 (PKSDATAFORMAT
)This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
,
563 if (Status
== STATUS_SUCCESS
)
565 IoStatus
->Information
= Length
;
568 DataRange
= UlongToPtr(PtrToUlong(DataRange
) + DataRange
->FormatSize
);
571 IoStatus
->Status
= Status
;
577 KspPinPropertyHandler(
579 IN PKSIDENTIFIER Request
,
582 PIO_STACK_LOCATION IoStack
;
583 IKsFilterImpl
* This
;
584 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
586 /* get filter implementation */
587 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
589 /* get current stack location */
590 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
594 case KSPROPERTY_PIN_CTYPES
:
595 case KSPROPERTY_PIN_DATAFLOW
:
596 case KSPROPERTY_PIN_DATARANGES
:
597 case KSPROPERTY_PIN_INTERFACES
:
598 case KSPROPERTY_PIN_MEDIUMS
:
599 case KSPROPERTY_PIN_COMMUNICATION
:
600 case KSPROPERTY_PIN_CATEGORY
:
601 case KSPROPERTY_PIN_NAME
:
602 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
603 Status
= KsPinPropertyHandler(Irp
, Request
, Data
, This
->PinDescriptorCount
, This
->PinDescriptors
);
605 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
606 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, TRUE
);
608 case KSPROPERTY_PIN_CINSTANCES
:
609 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, FALSE
);
611 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
612 Status
= KspHandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
);
615 case KSPROPERTY_PIN_DATAINTERSECTION
:
616 Status
= KspHandleDataIntersection(Irp
, &Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
);
618 case KSPROPERTY_PIN_PHYSICALCONNECTION
:
619 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
621 Status
= STATUS_NOT_IMPLEMENTED
;
625 Status
= STATUS_UNSUCCESSFUL
;
633 IN PIO_STATUS_BLOCK IoStatus
,
634 IN KSPROPERTY_SET
* FilterPropertySet
,
635 IN ULONG FilterPropertySetCount
,
636 IN PKSPROPERTY Property
,
637 IN ULONG InputBufferLength
,
638 IN ULONG OutputBufferLength
,
639 OUT PFNKSHANDLER
*PropertyHandler
)
641 ULONG Index
, ItemIndex
;
643 for(Index
= 0; Index
< FilterPropertySetCount
; Index
++)
645 if (IsEqualGUIDAligned(&Property
->Set
, FilterPropertySet
[Index
].Set
))
647 for(ItemIndex
= 0; ItemIndex
< FilterPropertySet
[Index
].PropertiesCount
; ItemIndex
++)
649 if (FilterPropertySet
[Index
].PropertyItem
[ItemIndex
].PropertyId
== Property
->Id
)
651 if (Property
->Flags
& KSPROPERTY_TYPE_SET
)
652 *PropertyHandler
= FilterPropertySet
[Index
].PropertyItem
[ItemIndex
].SetPropertyHandler
;
654 if (Property
->Flags
& KSPROPERTY_TYPE_GET
)
655 *PropertyHandler
= FilterPropertySet
[Index
].PropertyItem
[ItemIndex
].GetPropertyHandler
;
657 if (FilterPropertySet
[Index
].PropertyItem
[ItemIndex
].MinProperty
> InputBufferLength
)
659 /* too small input buffer */
660 IoStatus
->Information
= FilterPropertySet
[Index
].PropertyItem
[ItemIndex
].MinProperty
;
661 IoStatus
->Status
= STATUS_BUFFER_TOO_SMALL
;
662 return STATUS_BUFFER_TOO_SMALL
;
665 if (FilterPropertySet
[Index
].PropertyItem
[ItemIndex
].MinData
> OutputBufferLength
)
667 /* too small output buffer */
668 IoStatus
->Information
= FilterPropertySet
[Index
].PropertyItem
[ItemIndex
].MinData
;
669 IoStatus
->Status
= STATUS_BUFFER_TOO_SMALL
;
670 return STATUS_BUFFER_TOO_SMALL
;
672 return STATUS_SUCCESS
;
677 return STATUS_UNSUCCESSFUL
;
684 IKsFilter_DispatchDeviceIoControl(
685 IN PDEVICE_OBJECT DeviceObject
,
688 PIO_STACK_LOCATION IoStack
;
689 PFNKSHANDLER PropertyHandler
= NULL
;
691 IKsFilterImpl
* This
;
694 /* obtain filter from object header */
695 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
696 if (!NT_SUCCESS(Status
))
699 /* get our real implementation */
700 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
702 /* current irp stack */
703 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
705 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
709 /* release filter interface */
710 Filter
->lpVtbl
->Release(Filter
);
712 /* complete and forget irp */
713 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
714 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
715 return STATUS_NOT_IMPLEMENTED
;
718 /* find a supported property handler */
719 Status
= FindPropertyHandler(&Irp
->IoStatus
, FilterPropertySet
, 2, IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, &PropertyHandler
);
720 if (NT_SUCCESS(Status
))
722 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (PVOID
)This
;
723 DPRINT("Calling property handler %p\n", PropertyHandler
);
724 Status
= PropertyHandler(Irp
, IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
, Irp
->UserBuffer
);
728 /* call driver's property handler */
730 Status
= STATUS_NOT_IMPLEMENTED
;
733 Irp
->IoStatus
.Status
= Status
;
734 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
740 static KSDISPATCH_TABLE DispatchTable
=
742 IKsFilter_DispatchDeviceIoControl
,
743 KsDispatchInvalidDeviceRequest
,
744 KsDispatchInvalidDeviceRequest
,
745 KsDispatchInvalidDeviceRequest
,
746 IKsFilter_DispatchClose
,
747 KsDispatchQuerySecurity
,
748 KsDispatchSetSecurity
,
749 KsDispatchFastIoDeviceControlFailure
,
750 KsDispatchFastReadFailure
,
751 KsDispatchFastReadFailure
,
756 IKsFilter_CreateDescriptors(
757 IKsFilterImpl
* This
,
758 KSFILTER_DESCRIPTOR
* FilterDescriptor
)
762 /* initialize pin descriptors */
763 if (FilterDescriptor
->PinDescriptorsCount
)
765 /* allocate pin instance count array */
766 This
->PinInstanceCount
= AllocateItem(NonPagedPool
, sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
);
767 if(!This
->PinDescriptors
)
769 return STATUS_INSUFFICIENT_RESOURCES
;
773 /* allocate pin descriptor array */
774 This
->PinDescriptors
= AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescriptor
->PinDescriptorsCount
);
775 if(!This
->PinDescriptors
)
777 FreeItem(This
->PinInstanceCount
);
778 return STATUS_INSUFFICIENT_RESOURCES
;
782 This
->PinDescriptorCount
= FilterDescriptor
->PinDescriptorsCount
;
783 /* now copy those pin descriptors over */
784 for(Index
= 0; Index
< FilterDescriptor
->PinDescriptorsCount
; Index
++)
786 /* copy one pin per time */
787 RtlMoveMemory(&This
->PinDescriptors
[Index
], &FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
791 /* initialize topology descriptor */
792 This
->Topology
.CategoriesCount
= FilterDescriptor
->CategoriesCount
;
793 This
->Topology
.Categories
= FilterDescriptor
->Categories
;
794 This
->Topology
.TopologyNodesCount
= FilterDescriptor
->NodeDescriptorsCount
;
795 This
->Topology
.TopologyConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
796 This
->Topology
.TopologyConnections
= FilterDescriptor
->Connections
;
798 if (This
->Topology
.TopologyNodesCount
> 0)
800 This
->Topology
.TopologyNodes
= AllocateItem(NonPagedPool
, sizeof(GUID
) * This
->Topology
.TopologyNodesCount
);
801 /* allocate topology node types array */
802 if (!This
->Topology
.TopologyNodes
)
803 return STATUS_INSUFFICIENT_RESOURCES
;
805 This
->Topology
.TopologyNodesNames
= AllocateItem(NonPagedPool
, sizeof(GUID
) * This
->Topology
.TopologyNodesCount
);
806 /* allocate topology names array */
807 if (!This
->Topology
.TopologyNodesNames
)
809 FreeItem((PVOID
)This
->Topology
.TopologyNodes
);
810 return STATUS_INSUFFICIENT_RESOURCES
;
813 for(Index
= 0; Index
< This
->Topology
.TopologyNodesCount
; Index
++)
815 /* copy topology type */
816 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodes
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Type
, sizeof(GUID
));
817 /* copy topology name */
818 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodesNames
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Name
, sizeof(GUID
));
823 return STATUS_SUCCESS
;
829 IN PDEVICE_OBJECT DeviceObject
,
831 IN IKsFilterFactory
*iface
)
833 IKsFilterImpl
* This
;
834 PKSFILTERFACTORY Factory
;
835 PIO_STACK_LOCATION IoStack
;
836 PDEVICE_EXTENSION DeviceExtension
;
839 /* get device extension */
840 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
842 /* get the filter factory */
843 Factory
= iface
->lpVtbl
->GetStruct(iface
);
845 if (!Factory
|| !Factory
->FilterDescriptor
|| !Factory
->FilterDescriptor
->Dispatch
|| !Factory
->FilterDescriptor
->Dispatch
->Create
)
847 /* Sorry it just will not work */
848 return STATUS_UNSUCCESSFUL
;
851 /* allocate filter instance */
852 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterFactory
));
854 return STATUS_INSUFFICIENT_RESOURCES
;
856 /* get current irp stack */
857 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
859 /* initialize filter instance */
861 This
->lpVtbl
= &vt_IKsFilter
;
862 This
->lpVtblKsControl
= &vt_IKsControl
;
863 This
->Filter
.Descriptor
= Factory
->FilterDescriptor
;
864 This
->Factory
= Factory
;
865 This
->FilterFactory
= iface
;
866 This
->FileObject
= IoStack
->FileObject
;
867 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
868 This
->Header
.Parent
.KsFilterFactory
= iface
->lpVtbl
->GetStruct(iface
);
869 This
->Header
.Type
= KsObjectTypeFilter
;
871 /* allocate the stream descriptors */
872 Status
= IKsFilter_CreateDescriptors(This
, (PKSFILTER_DESCRIPTOR
)Factory
->FilterDescriptor
);
873 if (!NT_SUCCESS(Status
))
875 /* what can go wrong, goes wrong */
880 /* now add the filter instance to the filter factory */
881 Status
= iface
->lpVtbl
->AddFilterInstance(iface
, (IKsFilter
*)&This
->lpVtbl
);
883 if (!NT_SUCCESS(Status
))
885 /* failed to add filter */
891 /* now let driver initialize the filter instance */
892 Status
= Factory
->FilterDescriptor
->Dispatch
->Create(&This
->Filter
, Irp
);
894 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
896 /* driver failed to initialize */
897 DPRINT1("Driver: Status %x\n", Status
);
899 /* remove filter instance from filter factory */
900 iface
->lpVtbl
->RemoveFilterInstance(iface
, (IKsFilter
*)&This
->lpVtbl
);
902 /* free filter instance */
908 /* now allocate the object header */
909 Status
= KsAllocateObjectHeader((PVOID
*)&This
->ObjectHeader
, 0, NULL
, Irp
, &DispatchTable
);
910 if (!NT_SUCCESS(Status
))
912 /* failed to allocate object header */
913 DPRINT1("Failed to allocate object header %x\n", Status
);
918 /* initialize object header */
919 This
->Header
.Type
= KsObjectTypeFilter
;
920 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
921 This
->ObjectHeader
->Type
= KsObjectTypeFilter
;
922 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
923 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Filter
;
926 /* completed initialization */
936 KsFilterAcquireProcessingMutex(
948 KsFilterReleaseProcessingMutex(
960 KsFilterAddTopologyConnections (
962 IN ULONG NewConnectionsCount
,
963 IN
const KSTOPOLOGY_CONNECTION
*const NewTopologyConnections
)
966 return STATUS_NOT_IMPLEMENTED
;
975 KsFilterAttemptProcessing(
977 IN BOOLEAN Asynchronous
)
990 IN
const KSNODE_DESCRIPTOR
*const NodeDescriptor
,
994 return STATUS_NOT_IMPLEMENTED
;
1003 KsFilterCreatePinFactory (
1004 IN PKSFILTER Filter
,
1005 IN
const KSPIN_DESCRIPTOR_EX
*const PinDescriptor
,
1009 return STATUS_NOT_IMPLEMENTED
;
1019 IN PKSFILTER Filter
)
1031 KsFilterGetChildPinCount(
1032 IN PKSFILTER Filter
,
1045 KsFilterGetFirstChildPin(
1046 IN PKSFILTER Filter
,
1059 KsFilterRegisterPowerCallbacks(
1060 IN PKSFILTER Filter
,
1061 IN PFNKSFILTERPOWER Sleep OPTIONAL
,
1062 IN PFNKSFILTERPOWER Wake OPTIONAL
)