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 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet
, KspTopologyPropertyHandler
);
49 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet
, KspPinPropertyHandler
, KspPinPropertyHandler
, KspPinPropertyHandler
);
51 KSPROPERTY_SET FilterPropertySet
[] =
54 &KSPROPSETID_Topology
,
55 sizeof(IKsFilterTopologySet
) / sizeof(KSPROPERTY_ITEM
),
56 (const KSPROPERTY_ITEM
*)&IKsFilterTopologySet
,
62 sizeof(IKsFilterPinSet
) / sizeof(KSPROPERTY_ITEM
),
63 (const KSPROPERTY_ITEM
*)&IKsFilterPinSet
,
71 IKsControl_fnQueryInterface(
76 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
78 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
80 *Output
= &This
->lpVtbl
;
81 _InterlockedIncrement(&This
->ref
);
82 return STATUS_SUCCESS
;
84 return STATUS_UNSUCCESSFUL
;
92 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
94 return InterlockedIncrement(&This
->ref
);
102 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
104 InterlockedDecrement(&This
->ref
);
106 /* Return new reference count */
112 IKsControl_fnKsProperty(
114 IN PKSPROPERTY Property
,
115 IN ULONG PropertyLength
,
116 IN OUT PVOID PropertyData
,
118 OUT ULONG
* BytesReturned
)
120 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
122 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, Property
, PropertyLength
, PropertyData
, DataLength
, BytesReturned
);
128 IKsControl_fnKsMethod(
131 IN ULONG MethodLength
,
132 IN OUT PVOID MethodData
,
134 OUT ULONG
* BytesReturned
)
136 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
138 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_METHOD
, Method
, MethodLength
, MethodData
, DataLength
, BytesReturned
);
144 IKsControl_fnKsEvent(
146 IN PKSEVENT Event OPTIONAL
,
147 IN ULONG EventLength
,
148 IN OUT PVOID EventData
,
150 OUT ULONG
* BytesReturned
)
152 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
156 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_ENABLE_EVENT
, Event
, EventLength
, EventData
, DataLength
, BytesReturned
);
160 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_DISABLE_EVENT
, EventData
, DataLength
, NULL
, 0, BytesReturned
);
165 static IKsControlVtbl vt_IKsControl
=
167 IKsControl_fnQueryInterface
,
169 IKsControl_fnRelease
,
170 IKsControl_fnKsProperty
,
171 IKsControl_fnKsMethod
,
178 IKsFilter_fnQueryInterface(
183 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
185 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
) ||
186 IsEqualGUIDAligned(refiid
, &IID_IKsFilter
))
188 *Output
= &This
->lpVtbl
;
189 _InterlockedIncrement(&This
->ref
);
190 return STATUS_SUCCESS
;
192 else if (IsEqualGUIDAligned(refiid
, &IID_IKsControl
))
194 *Output
= &This
->lpVtblKsControl
;
195 _InterlockedIncrement(&This
->ref
);
196 return STATUS_SUCCESS
;
199 return STATUS_UNSUCCESSFUL
;
207 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
209 return InterlockedIncrement(&This
->ref
);
217 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
219 InterlockedDecrement(&This
->ref
);
226 /* Return new reference count */
233 IKsFilter_fnGetStruct(
236 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
238 return &This
->Filter
;
243 IKsFilter_fnDoAllNecessaryPinsExist(
252 IKsFilter_fnCreateNode(
256 IN PLIST_ENTRY ListEntry
)
259 return STATUS_NOT_IMPLEMENTED
;
264 IKsFilter_fnBindProcessPinsToPipeSection(
266 IN
struct KSPROCESSPIPESECTION
*Section
,
270 OUT PKSGATE
*OutGate
)
273 return STATUS_NOT_IMPLEMENTED
;
278 IKsFilter_fnUnbindProcessPinsFromPipeSection(
280 IN
struct KSPROCESSPIPESECTION
*Section
)
283 return STATUS_NOT_IMPLEMENTED
;
288 IKsFilter_fnAddProcessPin(
290 IN PKSPROCESSPIN ProcessPin
)
293 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
295 /* first acquire processing mutex */
296 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
299 ASSERT(This
->PinDescriptorCount
> ProcessPin
->Pin
->Id
);
301 /* allocate new process pin array */
302 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
,
303 (This
->PinDescriptorCount
+ 1) * sizeof(PKSPROCESSPIN
),
304 This
->PinDescriptorCount
* sizeof(PKSPROCESSPIN
),
307 if (NT_SUCCESS(Status
))
309 /* store process pin */
310 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
[This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
] = ProcessPin
;
311 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
++;
314 /* release process mutex */
315 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
322 IKsFilter_fnRemoveProcessPin(
324 IN PKSPROCESSPIN ProcessPin
)
328 PKSPROCESSPIN
* Pins
;
330 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
332 /* first acquire processing mutex */
333 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
336 ASSERT(ProcessPin
->Pin
);
337 ASSERT(ProcessPin
->Pin
->Id
);
339 Count
= This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
;
340 Pins
= This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
;
342 /* search for current process pin */
343 for(Index
= 0; Index
< Count
; Index
++)
345 if (Pins
[Index
] == ProcessPin
)
347 RtlMoveMemory(&Pins
[Index
], &Pins
[Index
+ 1], (Count
- (Index
+ 1)) * sizeof(PKSPROCESSPIN
));
353 /* decrement pin count */
354 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
--;
356 if (!This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
)
358 /* clear entry object bag will delete it */
359 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
= NULL
;
362 /* release process mutex */
363 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
366 return STATUS_SUCCESS
;
371 IKsFilter_fnReprepareProcessPipeSection(
373 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
382 IKsFilter_fnDeliverResetState(
384 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
385 IN KSRESET ResetState
)
392 IKsFilter_fnIsFrameHolding(
401 IKsFilter_fnRegisterForCopyCallbacks(
409 PKSPROCESSPIN_INDEXENTRY
411 IKsFilter_fnGetProcessDispatch(
414 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
416 return This
->ProcessPinIndex
;
419 static IKsFilterVtbl vt_IKsFilter
=
421 IKsFilter_fnQueryInterface
,
424 IKsFilter_fnGetStruct
,
425 IKsFilter_fnDoAllNecessaryPinsExist
,
426 IKsFilter_fnCreateNode
,
427 IKsFilter_fnBindProcessPinsToPipeSection
,
428 IKsFilter_fnUnbindProcessPinsFromPipeSection
,
429 IKsFilter_fnAddProcessPin
,
430 IKsFilter_fnRemoveProcessPin
,
431 IKsFilter_fnReprepareProcessPipeSection
,
432 IKsFilter_fnDeliverResetState
,
433 IKsFilter_fnIsFrameHolding
,
434 IKsFilter_fnRegisterForCopyCallbacks
,
435 IKsFilter_fnGetProcessDispatch
439 IKsFilter_GetFilterFromIrp(
441 OUT IKsFilter
**Filter
)
443 PIO_STACK_LOCATION IoStack
;
444 PKSIOBJECT_HEADER ObjectHeader
;
447 /* get current irp stack */
448 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
451 ASSERT(IoStack
->FileObject
!= NULL
);
453 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
455 /* sanity is important */
456 ASSERT(ObjectHeader
!= NULL
);
457 ASSERT(ObjectHeader
->Type
== KsObjectTypeFilter
);
458 ASSERT(ObjectHeader
->Unknown
!= NULL
);
460 /* get our private interface */
461 Status
= ObjectHeader
->Unknown
->lpVtbl
->QueryInterface(ObjectHeader
->Unknown
, &IID_IKsFilter
, (PVOID
*)Filter
);
463 if (!NT_SUCCESS(Status
))
465 /* something is wrong here */
466 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader
->Unknown
);
467 Irp
->IoStatus
.Status
= Status
;
469 /* complete and forget irp */
470 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
479 IKsFilter_DispatchClose(
480 IN PDEVICE_OBJECT DeviceObject
,
484 IKsFilterImpl
* This
;
487 /* obtain filter from object header */
488 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
489 if (!NT_SUCCESS(Status
))
492 /* get our real implementation */
493 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
495 /* does the driver support notifications */
496 if (This
->Factory
->FilterDescriptor
&& This
->Factory
->FilterDescriptor
->Dispatch
&& This
->Factory
->FilterDescriptor
->Dispatch
->Close
)
498 /* call driver's filter close function */
499 Status
= This
->Factory
->FilterDescriptor
->Dispatch
->Close(&This
->Filter
, Irp
);
502 if (NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
504 /* save the result */
505 Irp
->IoStatus
.Status
= Status
;
507 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
509 /* FIXME remove our instance from the filter factory */
512 /* free object header */
513 KsFreeObjectHeader(This
->ObjectHeader
);
517 /* complete and forget */
518 Irp
->IoStatus
.Status
= Status
;
520 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
528 KspHandlePropertyInstances(
529 IN PIO_STATUS_BLOCK IoStatus
,
530 IN PKSIDENTIFIER Request
,
532 IN IKsFilterImpl
* This
,
535 KSPIN_CINSTANCES
* Instances
;
536 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
538 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
540 /* no filter / pin descriptor */
541 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
542 return STATUS_NOT_IMPLEMENTED
;
545 /* ignore custom structs for now */
546 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
547 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
549 Instances
= (KSPIN_CINSTANCES
*)Data
;
550 /* max instance count */
551 Instances
->PossibleCount
= This
->PinDescriptorsEx
[Pin
->PinId
].InstancesPossible
;
552 /* current instance count */
553 Instances
->CurrentCount
= This
->PinInstanceCount
[Pin
->PinId
];
555 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
556 IoStatus
->Status
= STATUS_SUCCESS
;
557 return STATUS_SUCCESS
;
561 KspHandleNecessaryPropertyInstances(
562 IN PIO_STATUS_BLOCK IoStatus
,
563 IN PKSIDENTIFIER Request
,
565 IN IKsFilterImpl
* This
)
568 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
570 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
572 /* no filter / pin descriptor */
573 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
574 return STATUS_NOT_IMPLEMENTED
;
577 /* ignore custom structs for now */
578 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
579 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
581 Result
= (PULONG
)Data
;
582 *Result
= This
->PinDescriptorsEx
[Pin
->PinId
].InstancesNecessary
;
584 IoStatus
->Information
= sizeof(ULONG
);
585 IoStatus
->Status
= STATUS_SUCCESS
;
586 return STATUS_SUCCESS
;
590 KspHandleDataIntersection(
592 IN PIO_STATUS_BLOCK IoStatus
,
593 IN PKSIDENTIFIER Request
,
596 IN IKsFilterImpl
* This
)
598 PKSMULTIPLE_ITEM MultipleItem
;
599 PKSDATARANGE DataRange
;
600 NTSTATUS Status
= STATUS_NO_MATCH
;
602 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
604 /* Access parameters */
605 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
606 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
608 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
610 /* no filter / pin descriptor */
611 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
612 return STATUS_NOT_IMPLEMENTED
;
615 /* ignore custom structs for now */
616 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
617 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
619 if (This
->PinDescriptorsEx
[Pin
->PinId
].IntersectHandler
== NULL
||
620 This
->PinDescriptors
[Pin
->PinId
].DataRanges
== NULL
||
621 This
->PinDescriptors
[Pin
->PinId
].DataRangesCount
== 0)
623 /* no driver supported intersect handler / no provided data ranges */
624 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
625 return STATUS_NOT_IMPLEMENTED
;
628 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
630 /* Call miniport's properitary handler */
631 Status
= This
->PinDescriptorsEx
[Pin
->PinId
].IntersectHandler(NULL
, /* context */
635 (PKSDATAFORMAT
)This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
,
640 if (Status
== STATUS_SUCCESS
|| Status
== STATUS_BUFFER_OVERFLOW
)
642 IoStatus
->Information
= Length
;
645 DataRange
= UlongToPtr(PtrToUlong(DataRange
) + DataRange
->FormatSize
);
648 IoStatus
->Status
= Status
;
654 KspPinPropertyHandler(
656 IN PKSIDENTIFIER Request
,
659 PIO_STACK_LOCATION IoStack
;
660 IKsFilterImpl
* This
;
661 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
663 /* get filter implementation */
664 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
666 /* get current stack location */
667 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
671 case KSPROPERTY_PIN_CTYPES
:
672 case KSPROPERTY_PIN_DATAFLOW
:
673 case KSPROPERTY_PIN_DATARANGES
:
674 case KSPROPERTY_PIN_INTERFACES
:
675 case KSPROPERTY_PIN_MEDIUMS
:
676 case KSPROPERTY_PIN_COMMUNICATION
:
677 case KSPROPERTY_PIN_CATEGORY
:
678 case KSPROPERTY_PIN_NAME
:
679 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
680 Status
= KsPinPropertyHandler(Irp
, Request
, Data
, This
->PinDescriptorCount
, This
->PinDescriptors
);
682 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
683 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, TRUE
);
685 case KSPROPERTY_PIN_CINSTANCES
:
686 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, FALSE
);
688 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
689 Status
= KspHandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
);
692 case KSPROPERTY_PIN_DATAINTERSECTION
:
693 Status
= KspHandleDataIntersection(Irp
, &Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
);
695 case KSPROPERTY_PIN_PHYSICALCONNECTION
:
696 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
698 Status
= STATUS_NOT_IMPLEMENTED
;
702 Status
= STATUS_UNSUCCESSFUL
;
704 DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This
->PinDescriptorCount
, Request
->Id
, Status
);
712 IKsFilter_DispatchDeviceIoControl(
713 IN PDEVICE_OBJECT DeviceObject
,
716 PIO_STACK_LOCATION IoStack
;
718 IKsFilterImpl
* This
;
720 PKSFILTER FilterInstance
;
722 /* obtain filter from object header */
723 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
724 if (!NT_SUCCESS(Status
))
727 /* get our real implementation */
728 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
730 /* current irp stack */
731 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
733 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
737 /* release filter interface */
738 Filter
->lpVtbl
->Release(Filter
);
740 /* complete and forget irp */
741 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
742 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
743 return STATUS_NOT_IMPLEMENTED
;
746 /* call property handler supported by ks */
747 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
748 Status
= KspPropertyHandler(Irp
, 2, FilterPropertySet
, NULL
, sizeof(KSPROPERTY_ITEM
));
750 if (Status
== STATUS_NOT_FOUND
)
752 /* get filter instance */
753 FilterInstance
= Filter
->lpVtbl
->GetStruct(Filter
);
755 /* check if the driver supports property sets */
756 if (FilterInstance
->Descriptor
->AutomationTable
&& FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
)
758 /* call driver's filter property handler */
759 Status
= KspPropertyHandler(Irp
,
760 FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
,
761 FilterInstance
->Descriptor
->AutomationTable
->PropertySets
,
763 FilterInstance
->Descriptor
->AutomationTable
->PropertyItemSize
);
767 if (Status
!= STATUS_PENDING
)
769 Irp
->IoStatus
.Status
= Status
;
770 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
777 static KSDISPATCH_TABLE DispatchTable
=
779 IKsFilter_DispatchDeviceIoControl
,
780 KsDispatchInvalidDeviceRequest
,
781 KsDispatchInvalidDeviceRequest
,
782 KsDispatchInvalidDeviceRequest
,
783 IKsFilter_DispatchClose
,
784 KsDispatchQuerySecurity
,
785 KsDispatchSetSecurity
,
786 KsDispatchFastIoDeviceControlFailure
,
787 KsDispatchFastReadFailure
,
788 KsDispatchFastReadFailure
,
793 IKsFilter_CreateDescriptors(
794 IKsFilterImpl
* This
,
795 KSFILTER_DESCRIPTOR
* FilterDescriptor
)
800 /* initialize pin descriptors */
801 This
->FirstPin
= NULL
;
802 This
->PinInstanceCount
= NULL
;
803 This
->PinDescriptors
= NULL
;
804 This
->PinDescriptorsEx
= NULL
;
805 This
->ProcessPinIndex
= NULL
;
806 This
->PinDescriptorCount
= 0;
808 /* initialize topology descriptor */
809 This
->Topology
.CategoriesCount
= FilterDescriptor
->CategoriesCount
;
810 This
->Topology
.Categories
= FilterDescriptor
->Categories
;
811 This
->Topology
.TopologyNodesCount
= FilterDescriptor
->NodeDescriptorsCount
;
812 This
->Topology
.TopologyConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
813 This
->Topology
.TopologyConnections
= FilterDescriptor
->Connections
;
815 /* are there any templates */
816 if (FilterDescriptor
->PinDescriptorsCount
)
819 ASSERT(FilterDescriptor
->PinDescriptors
);
821 /* FIXME handle variable sized pin descriptors */
822 ASSERT(FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
824 /* store pin descriptors ex */
825 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptorsEx
, sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
,
826 sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
, 0);
828 if (!NT_SUCCESS(Status
))
830 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
834 /* store pin descriptors */
835 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptors
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescriptor
->PinDescriptorsCount
,
836 sizeof(KSPIN_DESCRIPTOR
) * FilterDescriptor
->PinDescriptorsCount
, 0);
838 if (!NT_SUCCESS(Status
))
840 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
844 /* store pin instance count ex */
845 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
,
846 sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
, 0);
848 if (!NT_SUCCESS(Status
))
850 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
854 /* store instantiated pin arrays */
855 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->FirstPin
, sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
,
856 sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
, 0);
858 if (!NT_SUCCESS(Status
))
860 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
864 /* add new pin factory */
865 RtlMoveMemory(This
->PinDescriptorsEx
, FilterDescriptor
->PinDescriptors
, sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
);
867 for(Index
= 0; Index
< FilterDescriptor
->PinDescriptorsCount
; Index
++)
869 RtlMoveMemory(&This
->PinDescriptors
[Index
], &FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
872 /* allocate process pin index */
873 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
, sizeof(KSPROCESSPIN_INDEXENTRY
) * FilterDescriptor
->PinDescriptorsCount
,
874 sizeof(KSPROCESSPIN_INDEXENTRY
) * FilterDescriptor
->PinDescriptorsCount
, 0);
876 if (!NT_SUCCESS(Status
))
878 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
882 /* store new pin descriptor count */
883 This
->PinDescriptorCount
= FilterDescriptor
->PinDescriptorsCount
;
887 if (FilterDescriptor
->NodeDescriptorsCount
)
890 ASSERT(FilterDescriptor
->NodeDescriptors
);
892 /* FIXME handle variable sized node descriptors */
893 ASSERT(FilterDescriptor
->NodeDescriptorSize
== sizeof(KSNODE_DESCRIPTOR
));
895 This
->Topology
.TopologyNodes
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
896 /* allocate topology node types array */
897 if (!This
->Topology
.TopologyNodes
)
899 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
900 return STATUS_INSUFFICIENT_RESOURCES
;
903 This
->Topology
.TopologyNodesNames
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
904 /* allocate topology names array */
905 if (!This
->Topology
.TopologyNodesNames
)
907 FreeItem((PVOID
)This
->Topology
.TopologyNodes
);
908 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
909 return STATUS_INSUFFICIENT_RESOURCES
;
912 DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
913 for(Index
= 0; Index
< FilterDescriptor
->NodeDescriptorsCount
; Index
++)
915 DPRINT("Index %lu Type %p Name %p\n", Index
, FilterDescriptor
->NodeDescriptors
[Index
].Type
, FilterDescriptor
->NodeDescriptors
[Index
].Name
);
917 /* copy topology type */
918 if (FilterDescriptor
->NodeDescriptors
[Index
].Type
)
919 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodes
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Type
, sizeof(GUID
));
921 /* copy topology name */
922 if (FilterDescriptor
->NodeDescriptors
[Index
].Name
)
923 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodesNames
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Name
, sizeof(GUID
));
927 return STATUS_SUCCESS
;
931 IKsFilter_CopyFilterDescriptor(
932 IKsFilterImpl
* This
,
933 const KSFILTER_DESCRIPTOR
* FilterDescriptor
)
937 This
->Filter
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSFILTER_DESCRIPTOR
));
938 if (!This
->Filter
.Descriptor
)
939 return STATUS_INSUFFICIENT_RESOURCES
;
941 Status
= KsAddItemToObjectBag(This
->Filter
.Bag
, (PVOID
)This
->Filter
.Descriptor
, NULL
);
942 if (!NT_SUCCESS(Status
))
944 FreeItem((PVOID
)This
->Filter
.Descriptor
);
945 This
->Filter
.Descriptor
= NULL
;
946 return STATUS_INSUFFICIENT_RESOURCES
;
949 /* copy filter descriptor fields */
950 RtlMoveMemory((PVOID
)This
->Filter
.Descriptor
, FilterDescriptor
, sizeof(KSFILTER_DESCRIPTOR
));
961 PKSPIN NextPin
, CurPin
;
962 PKSBASIC_HEADER BasicHeader
;
963 IKsFilterImpl
* This
= (IKsFilterImpl
*)Filter
;
966 ASSERT(Pin
->Id
< This
->PinDescriptorCount
);
968 if (This
->FirstPin
[Pin
->Id
] == NULL
)
970 /* welcome first pin */
971 This
->FirstPin
[Pin
->Id
] = Pin
;
972 return STATUS_SUCCESS
;
976 CurPin
= This
->FirstPin
[Pin
->Id
];
980 /* get next instantiated pin */
981 NextPin
= KsPinGetNextSiblingPin(CurPin
);
987 }while(NextPin
!= NULL
);
989 /* get basic header */
990 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)CurPin
- sizeof(KSBASIC_HEADER
));
993 BasicHeader
->Next
.Pin
= Pin
;
995 return STATUS_SUCCESS
;
1001 IKsFilter_DispatchCreatePin(
1002 IN PDEVICE_OBJECT DeviceObject
,
1005 IKsFilterImpl
* This
;
1006 PKSOBJECT_CREATE_ITEM CreateItem
;
1007 PKSPIN_CONNECT Connect
;
1010 DPRINT("IKsFilter_DispatchCreatePin\n");
1012 /* get the create item */
1013 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
1015 /* get the filter object */
1016 This
= (IKsFilterImpl
*)CreateItem
->Context
;
1019 ASSERT(This
->Header
.Type
== KsObjectTypeFilter
);
1021 /* acquire control mutex */
1022 KeWaitForSingleObject(This
->Header
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1024 /* now validate the connect request */
1025 Status
= KsValidateConnectRequest(Irp
, This
->PinDescriptorCount
, This
->PinDescriptors
, &Connect
);
1027 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status
);
1029 if (NT_SUCCESS(Status
))
1032 ASSERT(Connect
->PinId
< This
->PinDescriptorCount
);
1034 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect
->PinId
,
1035 This
->PinInstanceCount
[Connect
->PinId
],
1036 This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
);
1038 if (This
->PinInstanceCount
[Connect
->PinId
] < This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
)
1040 /* create the pin */
1041 Status
= KspCreatePin(DeviceObject
, Irp
, This
->Header
.KsDevice
, This
->FilterFactory
, (IKsFilter
*)&This
->lpVtbl
, Connect
, &This
->PinDescriptorsEx
[Connect
->PinId
]);
1043 DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status
);
1045 if (NT_SUCCESS(Status
))
1047 /* successfully created pin, increment pin instance count */
1048 This
->PinInstanceCount
[Connect
->PinId
]++;
1053 /* maximum instance count reached, bye-bye */
1054 Status
= STATUS_UNSUCCESSFUL
;
1055 DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
, This
->PinInstanceCount
[Connect
->PinId
]);
1059 /* release control mutex */
1060 KeReleaseMutex(This
->Header
.ControlMutex
, FALSE
);
1062 if (Status
!= STATUS_PENDING
)
1064 /* complete request */
1065 Irp
->IoStatus
.Status
= Status
;
1066 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1070 DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status
);
1076 IKsFilter_DispatchCreateNode(
1077 IN PDEVICE_OBJECT DeviceObject
,
1081 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1082 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1083 return STATUS_UNSUCCESSFUL
;
1088 IKsFilter_AttachFilterToFilterFactory(
1089 IKsFilterImpl
* This
,
1090 PKSFILTERFACTORY FilterFactory
)
1092 PKSBASIC_HEADER BasicHeader
;
1096 /* get filter factory basic header */
1097 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1100 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1102 if (BasicHeader
->FirstChild
.FilterFactory
== NULL
)
1104 /* welcome first instantiated filter */
1105 BasicHeader
->FirstChild
.Filter
= &This
->Filter
;
1109 /* set to first entry */
1110 Filter
= BasicHeader
->FirstChild
.Filter
;
1114 /* get basic header */
1115 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1117 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1119 if (BasicHeader
->Next
.Filter
)
1121 /* iterate to next filter factory */
1122 Filter
= BasicHeader
->Next
.Filter
;
1126 /* found last entry */
1129 }while(FilterFactory
);
1131 /* attach filter factory */
1132 BasicHeader
->Next
.Filter
= &This
->Filter
;
1138 IN PDEVICE_OBJECT DeviceObject
,
1140 IN IKsFilterFactory
*iface
)
1142 IKsFilterImpl
* This
;
1143 IKsDevice
*KsDevice
;
1144 PKSFILTERFACTORY Factory
;
1145 PIO_STACK_LOCATION IoStack
;
1146 PDEVICE_EXTENSION DeviceExtension
;
1148 PKSOBJECT_CREATE_ITEM CreateItem
;
1150 /* get device extension */
1151 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1153 /* get the filter factory */
1154 Factory
= iface
->lpVtbl
->GetStruct(iface
);
1156 if (!Factory
|| !Factory
->FilterDescriptor
|| !Factory
->FilterDescriptor
->Dispatch
|| !Factory
->FilterDescriptor
->Dispatch
->Create
)
1158 /* Sorry it just will not work */
1159 return STATUS_UNSUCCESSFUL
;
1162 /* allocate filter instance */
1163 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterImpl
));
1166 DPRINT("KspCreateFilter OutOfMemory\n");
1167 return STATUS_INSUFFICIENT_RESOURCES
;
1170 /* initialize object bag */
1171 This
->Filter
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1172 if (!This
->Filter
.Bag
)
1176 DPRINT("KspCreateFilter OutOfMemory\n");
1177 return STATUS_INSUFFICIENT_RESOURCES
;
1179 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
1180 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->Filter
.Bag
, NULL
);
1182 /* copy filter descriptor */
1183 Status
= IKsFilter_CopyFilterDescriptor(This
, Factory
->FilterDescriptor
);
1184 if (!NT_SUCCESS(Status
))
1186 /* not enough memory */
1187 FreeItem(This
->Filter
.Bag
);
1189 DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status
);
1190 return STATUS_INSUFFICIENT_RESOURCES
;
1193 /* get current irp stack */
1194 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1196 /* allocate create items */
1197 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 2);
1201 FreeItem(This
->Filter
.Bag
);
1203 DPRINT("KspCreateFilter OutOfMemory\n");
1204 return STATUS_INSUFFICIENT_RESOURCES
;
1207 DPRINT("KspCreateFilter Flags %lx\n", Factory
->FilterDescriptor
->Flags
);
1209 /* initialize pin create item */
1210 CreateItem
[0].Create
= IKsFilter_DispatchCreatePin
;
1211 CreateItem
[0].Context
= (PVOID
)This
;
1212 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1213 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Pin
);
1214 /* initialize node create item */
1215 CreateItem
[1].Create
= IKsFilter_DispatchCreateNode
;
1216 CreateItem
[1].Context
= (PVOID
)This
;
1217 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1218 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_TopologyNode
);
1221 /* initialize filter instance */
1223 This
->lpVtbl
= &vt_IKsFilter
;
1224 This
->lpVtblKsControl
= &vt_IKsControl
;
1226 This
->Filter
.Descriptor
= Factory
->FilterDescriptor
;
1227 This
->Factory
= Factory
;
1228 This
->FilterFactory
= iface
;
1229 This
->FileObject
= IoStack
->FileObject
;
1230 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1231 /* initialize basic header */
1232 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
1233 This
->Header
.Parent
.KsFilterFactory
= iface
->lpVtbl
->GetStruct(iface
);
1234 This
->Header
.Type
= KsObjectTypeFilter
;
1235 This
->Header
.ControlMutex
= &This
->ControlMutex
;
1236 KeInitializeMutex(This
->Header
.ControlMutex
, 0);
1237 InitializeListHead(&This
->Header
.EventList
);
1238 KeInitializeSpinLock(&This
->Header
.EventListLock
);
1240 /* allocate the stream descriptors */
1241 Status
= IKsFilter_CreateDescriptors(This
, (PKSFILTER_DESCRIPTOR
)Factory
->FilterDescriptor
);
1242 if (!NT_SUCCESS(Status
))
1244 /* what can go wrong, goes wrong */
1246 FreeItem(CreateItem
);
1247 DPRINT("IKsFilter_CreateDescriptors failed with %lx\n", Status
);
1251 /* does the filter have a filter dispatch */
1252 if (Factory
->FilterDescriptor
->Dispatch
)
1254 /* does it have a create routine */
1255 if (Factory
->FilterDescriptor
->Dispatch
->Create
)
1257 /* now let driver initialize the filter instance */
1259 ASSERT(This
->Header
.KsDevice
);
1260 ASSERT(This
->Header
.KsDevice
->Started
);
1261 Status
= Factory
->FilterDescriptor
->Dispatch
->Create(&This
->Filter
, Irp
);
1263 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
1265 /* driver failed to initialize */
1266 DPRINT1("Driver: Status %x\n", Status
);
1268 /* free filter instance */
1270 FreeItem(CreateItem
);
1276 /* now allocate the object header */
1277 Status
= KsAllocateObjectHeader((PVOID
*)&This
->ObjectHeader
, 2, CreateItem
, Irp
, &DispatchTable
);
1278 if (!NT_SUCCESS(Status
))
1280 /* failed to allocate object header */
1281 DPRINT1("Failed to allocate object header %x\n", Status
);
1286 /* initialize object header extra fields */
1287 This
->ObjectHeader
->Type
= KsObjectTypeFilter
;
1288 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
1289 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Filter
;
1291 /* attach filter to filter factory */
1292 IKsFilter_AttachFilterToFilterFactory(This
, This
->Header
.Parent
.KsFilterFactory
);
1294 /* completed initialization */
1295 DPRINT("KspCreateFilter done %lx\n", Status
);
1305 KsFilterAcquireProcessingMutex(
1306 IN PKSFILTER Filter
)
1308 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1310 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1319 KsFilterReleaseProcessingMutex(
1320 IN PKSFILTER Filter
)
1322 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1324 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1333 KsFilterAddTopologyConnections (
1334 IN PKSFILTER Filter
,
1335 IN ULONG NewConnectionsCount
,
1336 IN
const KSTOPOLOGY_CONNECTION
*const NewTopologyConnections
)
1339 KSTOPOLOGY_CONNECTION
* Connections
;
1340 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1342 Count
= This
->Filter
.Descriptor
->ConnectionsCount
+ NewConnectionsCount
;
1344 /* allocate array */
1345 Connections
= AllocateItem(NonPagedPool
, Count
* sizeof(KSTOPOLOGY_CONNECTION
));
1347 return STATUS_INSUFFICIENT_RESOURCES
;
1349 /* FIXME verify connections */
1351 if (This
->Filter
.Descriptor
->ConnectionsCount
)
1353 /* copy old connections */
1354 RtlMoveMemory(Connections
, This
->Filter
.Descriptor
->Connections
, sizeof(KSTOPOLOGY_CONNECTION
) * This
->Filter
.Descriptor
->ConnectionsCount
);
1357 /* add new connections */
1358 RtlMoveMemory((PVOID
)(Connections
+ This
->Filter
.Descriptor
->ConnectionsCount
), NewTopologyConnections
, NewConnectionsCount
);
1360 /* add the new connections */
1361 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->ConnectionsCount
, &Count
, sizeof(ULONG
)); /* brain-dead gcc hack */
1363 /* free old connections array */
1364 if (This
->Filter
.Descriptor
->ConnectionsCount
)
1366 FreeItem((PVOID
)This
->Filter
.Descriptor
->Connections
);
1369 /* brain-dead gcc hack */
1370 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->Connections
, Connections
, sizeof(KSTOPOLOGY_CONNECTION
*));
1372 return STATUS_SUCCESS
;
1381 KsFilterAttemptProcessing(
1382 IN PKSFILTER Filter
,
1383 IN BOOLEAN Asynchronous
)
1394 KsFilterCreateNode (
1395 IN PKSFILTER Filter
,
1396 IN
const KSNODE_DESCRIPTOR
*const NodeDescriptor
,
1400 return STATUS_NOT_IMPLEMENTED
;
1409 KsFilterCreatePinFactory (
1410 IN PKSFILTER Filter
,
1411 IN
const KSPIN_DESCRIPTOR_EX
*const InPinDescriptor
,
1416 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1418 DPRINT("KsFilterCreatePinFactory\n");
1420 /* calculate new count */
1421 Count
= This
->PinDescriptorCount
+ 1;
1424 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
1426 /* allocate pin descriptors ex array */
1427 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptorsEx
, Count
* sizeof(KSPIN_DESCRIPTOR_EX
), This
->PinDescriptorCount
* sizeof(KSPIN_DESCRIPTOR_EX
), 0);
1428 if (!NT_SUCCESS(Status
))
1431 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1435 /* allocate pin descriptors array */
1436 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptors
, Count
* sizeof(KSPIN_DESCRIPTOR
), This
->PinDescriptorCount
* sizeof(KSPIN_DESCRIPTOR
), 0);
1437 if (!NT_SUCCESS(Status
))
1440 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1445 /* allocate pin instance count array */
1446 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * Count
, sizeof(ULONG
) * This
->PinDescriptorCount
, 0);
1447 if (!NT_SUCCESS(Status
))
1450 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1454 /* allocate first pin array */
1455 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->FirstPin
, sizeof(PKSPIN
) * Count
, sizeof(PKSPIN
) * This
->PinDescriptorCount
, 0);
1456 if (!NT_SUCCESS(Status
))
1459 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1463 /* add new pin factory */
1464 RtlMoveMemory(&This
->PinDescriptorsEx
[This
->PinDescriptorCount
], InPinDescriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
1465 RtlMoveMemory(&This
->PinDescriptors
[This
->PinDescriptorCount
], &InPinDescriptor
->PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
1468 /* allocate process pin index */
1469 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
, sizeof(KSPROCESSPIN_INDEXENTRY
) * Count
,
1470 sizeof(KSPROCESSPIN_INDEXENTRY
) * This
->PinDescriptorCount
, 0);
1472 if (!NT_SUCCESS(Status
))
1474 DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status
);
1478 /* store new pin id */
1479 *PinID
= This
->PinDescriptorCount
;
1481 /* increment pin descriptor count */
1482 This
->PinDescriptorCount
++;
1485 DPRINT("KsFilterCreatePinFactory done\n");
1486 return STATUS_SUCCESS
;
1497 IN PKSFILTER Filter
)
1509 KsFilterGetChildPinCount(
1510 IN PKSFILTER Filter
,
1513 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1515 if (PinId
>= This
->PinDescriptorCount
)
1517 /* index is out of bounds */
1520 /* return pin instance count */
1521 return This
->PinInstanceCount
[PinId
];
1530 KsFilterGetFirstChildPin(
1531 IN PKSFILTER Filter
,
1534 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1536 if (PinId
>= This
->PinDescriptorCount
)
1538 /* index is out of bounds */
1542 /* return first pin index */
1543 return This
->FirstPin
[PinId
];
1552 KsFilterRegisterPowerCallbacks(
1553 IN PKSFILTER Filter
,
1554 IN PFNKSFILTERPOWER Sleep OPTIONAL
,
1555 IN PFNKSFILTERPOWER Wake OPTIONAL
)
1557 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1559 This
->Sleep
= Sleep
;
1572 PIO_STACK_LOCATION IoStack
;
1573 PKSIOBJECT_HEADER ObjectHeader
;
1575 DPRINT("KsGetFilterFromIrp\n");
1577 /* get current irp stack location */
1578 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1581 ASSERT(IoStack
->FileObject
);
1583 /* get object header */
1584 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1586 if (ObjectHeader
->Type
== KsObjectTypeFilter
)
1588 /* irp is targeted at the filter */
1589 return (PKSFILTER
)ObjectHeader
->ObjectType
;
1591 else if (ObjectHeader
->Type
== KsObjectTypePin
)
1593 /* irp is for a pin */
1594 return KsPinGetParentFilter((PKSPIN
)ObjectHeader
->ObjectType
);
1598 /* irp is unappropiate to retrieve a filter */