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
16 KSBASIC_HEADER Header
;
19 IKsControlVtbl
*lpVtblKsControl
;
20 IKsFilterFactory
* FilterFactory
;
21 IKsProcessingObjectVtbl
* lpVtblKsProcessingObject
;
24 PKSIOBJECT_HEADER ObjectHeader
;
26 PKSFILTERFACTORY Factory
;
27 PFILE_OBJECT FileObject
;
29 KMUTEX ProcessingMutex
;
32 WORK_QUEUE_ITEM WorkItem
;
35 PFNKSFILTERPOWER Sleep
;
36 PFNKSFILTERPOWER Wake
;
38 ULONG
*PinInstanceCount
;
40 PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
44 const GUID IID_IKsControl
= {0x28F54685L
, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
45 const GUID IID_IKsFilter
= {0x3ef6ee44L
, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}};
46 const GUID KSPROPSETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
47 const GUID KSPROPSETID_Pin
= {0x8C134960L
, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
48 const GUID KSPROPSETID_General
= {0x1464EDA5L
, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
51 IKsFilter_RemoveFilterFromFilterFactory(
53 PKSFILTERFACTORY FilterFactory
);
55 NTSTATUS NTAPI
FilterTopologyPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
56 NTSTATUS NTAPI
FilterPinPropertyHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
57 NTSTATUS NTAPI
FilterGeneralComponentIdHandler(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
59 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet
, FilterTopologyPropertyHandler
);
60 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet
, FilterPinPropertyHandler
, FilterPinPropertyHandler
, FilterPinPropertyHandler
);
61 DEFINE_KSPROPERTY_GENEREAL_COMPONENTID(IKsFilterGeneralSet
, FilterGeneralComponentIdHandler
);
63 KSPROPERTY_SET FilterPropertySet
[] =
66 &KSPROPSETID_Topology
,
67 sizeof(IKsFilterTopologySet
) / sizeof(KSPROPERTY_ITEM
),
68 (const KSPROPERTY_ITEM
*)&IKsFilterTopologySet
,
74 sizeof(IKsFilterPinSet
) / sizeof(KSPROPERTY_ITEM
),
75 (const KSPROPERTY_ITEM
*)&IKsFilterPinSet
,
81 sizeof(IKsFilterGeneralSet
) / sizeof(KSPROPERTY_ITEM
),
82 (const KSPROPERTY_ITEM
*)&IKsFilterGeneralSet
,
90 IKsProcessingObject_fnQueryInterface(
91 IKsProcessingObject
* iface
,
95 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsProcessingObject
);
97 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
99 *Output
= &This
->Header
.OuterUnknown
;
100 _InterlockedIncrement(&This
->ref
);
101 return STATUS_SUCCESS
;
103 return STATUS_UNSUCCESSFUL
;
108 IKsProcessingObject_fnAddRef(
109 IKsProcessingObject
* iface
)
111 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsProcessingObject
);
113 return InterlockedIncrement(&This
->ref
);
118 IKsProcessingObject_fnRelease(
119 IKsProcessingObject
* iface
)
121 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsProcessingObject
);
123 InterlockedDecrement(&This
->ref
);
125 /* Return new reference count */
131 IKsProcessingObject_fnProcessingObjectWork(
132 IKsProcessingObject
* iface
)
135 LARGE_INTEGER TimeOut
;
136 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsProcessingObject
);
138 DPRINT1("processing object\n");
139 /* first check if running at passive level */
140 if (KeGetCurrentIrql() == PASSIVE_LEVEL
)
142 /* acquire processing mutex */
143 KeWaitForSingleObject(&This
->ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
147 /* dispatch level processing */
148 if (KeReadStateMutex(&This
->ControlMutex
) == 0)
150 /* some thread was faster */
151 DPRINT1("processing object too slow\n");
155 /* acquire processing mutex */
156 TimeOut
.QuadPart
= 0LL;
157 Status
= KeWaitForSingleObject(&This
->ControlMutex
, Executive
, KernelMode
, FALSE
, &TimeOut
);
159 if (Status
== STATUS_TIMEOUT
)
161 /* some thread was faster */
162 DPRINT1("processing object too slow\n");
170 /* check if the and-gate has been enabled again */
171 if (&This
->Gate
.Count
!= 0)
174 DPRINT1("processing object gate open\n");
178 DPRINT1("IKsProcessingObject_fnProcessingObjectWork not implemented\n");
183 /* release process mutex */
184 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
189 IKsProcessingObject_fnGetAndGate(
190 IKsProcessingObject
* iface
)
192 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsProcessingObject
);
194 /* return and gate */
200 IKsProcessingObject_fnProcess(
201 IKsProcessingObject
* iface
,
202 IN BOOLEAN Asynchronous
)
204 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsProcessingObject
);
206 /* should the action be asynchronous */
209 /* queue work item */
210 KsQueueWorkItem(This
->Worker
, &This
->WorkItem
);
211 DPRINT1("queueing\n");
216 /* does the filter require explicit deferred processing */
217 if ((This
->Filter
.Descriptor
->Flags
& (KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING
| KSFILTER_FLAG_CRITICAL_PROCESSING
| KSFILTER_FLAG_HYPERCRITICAL_PROCESSING
)) &&
218 KeGetCurrentIrql() > PASSIVE_LEVEL
)
220 /* queue work item */
221 KsQueueWorkItem(This
->Worker
, &This
->WorkItem
);
222 DPRINT1("queueing\n");
227 /* call worker routine directly */
228 iface
->lpVtbl
->ProcessingObjectWork(iface
);
233 IKsProcessingObject_fnReset(
234 IKsProcessingObject
* iface
)
236 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsProcessingObject
);
238 /* acquire processing mutex */
239 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
241 /* check if the filter supports dispatch routines */
242 if (This
->Filter
.Descriptor
->Dispatch
)
244 /* has the filter a reset routine */
245 if (This
->Filter
.Descriptor
->Dispatch
->Reset
)
248 This
->Filter
.Descriptor
->Dispatch
->Reset(&This
->Filter
);
252 /* release process mutex */
253 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
258 IKsProcessingObject_fnTriggerNotification(
259 IKsProcessingObject
* iface
)
264 static IKsProcessingObjectVtbl vt_IKsProcessingObject
=
266 IKsProcessingObject_fnQueryInterface
,
267 IKsProcessingObject_fnAddRef
,
268 IKsProcessingObject_fnRelease
,
269 IKsProcessingObject_fnProcessingObjectWork
,
270 IKsProcessingObject_fnGetAndGate
,
271 IKsProcessingObject_fnProcess
,
272 IKsProcessingObject_fnReset
,
273 IKsProcessingObject_fnTriggerNotification
277 //---------------------------------------------------------------------------------------------------------
280 IKsControl_fnQueryInterface(
285 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
287 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
289 *Output
= &This
->Header
.OuterUnknown
;
290 _InterlockedIncrement(&This
->ref
);
291 return STATUS_SUCCESS
;
293 return STATUS_UNSUCCESSFUL
;
301 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
303 return InterlockedIncrement(&This
->ref
);
308 IKsControl_fnRelease(
311 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
313 InterlockedDecrement(&This
->ref
);
315 /* Return new reference count */
321 IKsControl_fnKsProperty(
323 IN PKSPROPERTY Property
,
324 IN ULONG PropertyLength
,
325 IN OUT PVOID PropertyData
,
327 OUT ULONG
* BytesReturned
)
329 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
331 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, Property
, PropertyLength
, PropertyData
, DataLength
, BytesReturned
);
337 IKsControl_fnKsMethod(
340 IN ULONG MethodLength
,
341 IN OUT PVOID MethodData
,
343 OUT ULONG
* BytesReturned
)
345 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
347 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_METHOD
, Method
, MethodLength
, MethodData
, DataLength
, BytesReturned
);
353 IKsControl_fnKsEvent(
355 IN PKSEVENT Event OPTIONAL
,
356 IN ULONG EventLength
,
357 IN OUT PVOID EventData
,
359 OUT ULONG
* BytesReturned
)
361 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
365 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_ENABLE_EVENT
, Event
, EventLength
, EventData
, DataLength
, BytesReturned
);
369 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_DISABLE_EVENT
, EventData
, DataLength
, NULL
, 0, BytesReturned
);
374 static IKsControlVtbl vt_IKsControl
=
376 IKsControl_fnQueryInterface
,
378 IKsControl_fnRelease
,
379 IKsControl_fnKsProperty
,
380 IKsControl_fnKsMethod
,
387 IKsFilter_fnQueryInterface(
393 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
395 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
) ||
396 IsEqualGUIDAligned(refiid
, &IID_IKsFilter
))
398 *Output
= &This
->Header
.OuterUnknown
;
399 _InterlockedIncrement(&This
->ref
);
400 return STATUS_SUCCESS
;
402 else if (IsEqualGUIDAligned(refiid
, &IID_IKsControl
))
404 *Output
= &This
->lpVtblKsControl
;
405 _InterlockedIncrement(&This
->ref
);
406 return STATUS_SUCCESS
;
409 if (This
->Header
.ClientAggregate
)
411 /* using client aggregate */
412 Status
= This
->Header
.ClientAggregate
->lpVtbl
->QueryInterface(This
->Header
.ClientAggregate
, refiid
, Output
);
414 if (NT_SUCCESS(Status
))
416 /* client aggregate supports interface */
421 DPRINT("IKsFilter_fnQueryInterface no interface\n");
422 return STATUS_NOT_SUPPORTED
;
430 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
432 return InterlockedIncrement(&This
->ref
);
440 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
442 InterlockedDecrement(&This
->ref
);
449 /* Return new reference count */
456 IKsFilter_fnGetStruct(
459 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
461 return &This
->Filter
;
466 IKsFilter_fnDoAllNecessaryPinsExist(
475 IKsFilter_fnCreateNode(
479 IN PLIST_ENTRY ListEntry
)
482 return STATUS_NOT_IMPLEMENTED
;
487 IKsFilter_fnBindProcessPinsToPipeSection(
489 IN
struct KSPROCESSPIPESECTION
*Section
,
493 OUT PKSGATE
*OutGate
)
496 return STATUS_NOT_IMPLEMENTED
;
501 IKsFilter_fnUnbindProcessPinsFromPipeSection(
503 IN
struct KSPROCESSPIPESECTION
*Section
)
506 return STATUS_NOT_IMPLEMENTED
;
511 IKsFilter_fnAddProcessPin(
513 IN PKSPROCESSPIN ProcessPin
)
516 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
518 /* first acquire processing mutex */
519 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
522 ASSERT(This
->Filter
.Descriptor
->PinDescriptorsCount
> ProcessPin
->Pin
->Id
);
524 /* allocate new process pin array */
525 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
,
526 (This
->Filter
.Descriptor
->PinDescriptorsCount
+ 1) * sizeof(PVOID
),
527 This
->Filter
.Descriptor
->PinDescriptorsCount
* sizeof(PVOID
),
530 if (NT_SUCCESS(Status
))
532 /* store process pin */
533 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
[This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
] = ProcessPin
;
534 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
++;
537 /* release process mutex */
538 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
545 IKsFilter_fnRemoveProcessPin(
547 IN PKSPROCESSPIN ProcessPin
)
551 PKSPROCESSPIN
* Pins
;
553 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
555 /* first acquire processing mutex */
556 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
559 ASSERT(ProcessPin
->Pin
);
560 ASSERT(ProcessPin
->Pin
->Id
);
562 Count
= This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
;
563 Pins
= This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
;
565 /* search for current process pin */
566 for(Index
= 0; Index
< Count
; Index
++)
568 if (Pins
[Index
] == ProcessPin
)
570 RtlMoveMemory(&Pins
[Index
], &Pins
[Index
+ 1], (Count
- (Index
+ 1)) * sizeof(PVOID
));
576 /* decrement pin count */
577 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
--;
579 if (!This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Count
)
581 /* clear entry object bag will delete it */
582 This
->ProcessPinIndex
[ProcessPin
->Pin
->Id
].Pins
= NULL
;
585 /* release process mutex */
586 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
589 return STATUS_SUCCESS
;
594 IKsFilter_fnReprepareProcessPipeSection(
596 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
605 IKsFilter_fnDeliverResetState(
607 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
608 IN KSRESET ResetState
)
615 IKsFilter_fnIsFrameHolding(
624 IKsFilter_fnRegisterForCopyCallbacks(
632 PKSPROCESSPIN_INDEXENTRY
634 IKsFilter_fnGetProcessDispatch(
637 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, Header
.OuterUnknown
);
639 return This
->ProcessPinIndex
;
642 static IKsFilterVtbl vt_IKsFilter
=
644 IKsFilter_fnQueryInterface
,
647 IKsFilter_fnGetStruct
,
648 IKsFilter_fnDoAllNecessaryPinsExist
,
649 IKsFilter_fnCreateNode
,
650 IKsFilter_fnBindProcessPinsToPipeSection
,
651 IKsFilter_fnUnbindProcessPinsFromPipeSection
,
652 IKsFilter_fnAddProcessPin
,
653 IKsFilter_fnRemoveProcessPin
,
654 IKsFilter_fnReprepareProcessPipeSection
,
655 IKsFilter_fnDeliverResetState
,
656 IKsFilter_fnIsFrameHolding
,
657 IKsFilter_fnRegisterForCopyCallbacks
,
658 IKsFilter_fnGetProcessDispatch
662 IKsFilter_GetFilterFromIrp(
664 OUT IKsFilter
**Filter
)
666 PIO_STACK_LOCATION IoStack
;
667 PKSIOBJECT_HEADER ObjectHeader
;
670 /* get current irp stack */
671 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
674 ASSERT(IoStack
->FileObject
!= NULL
);
676 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
678 /* sanity is important */
679 ASSERT(ObjectHeader
!= NULL
);
680 ASSERT(ObjectHeader
->Type
== KsObjectTypeFilter
);
681 ASSERT(ObjectHeader
->Unknown
!= NULL
);
683 /* get our private interface */
684 Status
= ObjectHeader
->Unknown
->lpVtbl
->QueryInterface(ObjectHeader
->Unknown
, &IID_IKsFilter
, (PVOID
*)Filter
);
686 if (!NT_SUCCESS(Status
))
688 /* something is wrong here */
689 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader
->Unknown
);
690 Irp
->IoStatus
.Status
= Status
;
692 /* complete and forget irp */
693 CompleteRequest(Irp
, IO_NO_INCREMENT
);
702 IKsFilter_DispatchClose(
703 IN PDEVICE_OBJECT DeviceObject
,
707 IKsFilterImpl
* This
;
710 /* obtain filter from object header */
711 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
712 if (!NT_SUCCESS(Status
))
715 /* get our real implementation */
716 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Header
.OuterUnknown
);
718 /* does the driver support notifications */
719 if (This
->Filter
.Descriptor
&& This
->Filter
.Descriptor
->Dispatch
&& This
->Filter
.Descriptor
->Dispatch
->Close
)
721 /* call driver's filter close function */
722 Status
= This
->Filter
.Descriptor
->Dispatch
->Close(&This
->Filter
, Irp
);
725 if (NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
727 /* save the result */
728 Irp
->IoStatus
.Status
= Status
;
730 CompleteRequest(Irp
, IO_NO_INCREMENT
);
732 /* remove our instance from the filter factory */
733 IKsFilter_RemoveFilterFromFilterFactory(This
, This
->Factory
);
735 /* free object header */
736 KsFreeObjectHeader(This
->ObjectHeader
);
740 /* complete and forget */
741 Irp
->IoStatus
.Status
= Status
;
743 CompleteRequest(Irp
, IO_NO_INCREMENT
);
751 KspHandlePropertyInstances(
752 IN PIO_STATUS_BLOCK IoStatus
,
753 IN PKSIDENTIFIER Request
,
755 IN IKsFilterImpl
* This
,
758 KSPIN_CINSTANCES
* Instances
;
759 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
761 if (!This
->Filter
.Descriptor
|| !This
->Filter
.Descriptor
->PinDescriptorsCount
)
763 /* no filter / pin descriptor */
764 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
765 return STATUS_NOT_IMPLEMENTED
;
768 /* ignore custom structs for now */
769 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
770 ASSERT(This
->Filter
.Descriptor
->PinDescriptorsCount
> Pin
->PinId
);
772 Instances
= (KSPIN_CINSTANCES
*)Data
;
773 /* max instance count */
774 Instances
->PossibleCount
= This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].InstancesPossible
;
775 /* current instance count */
776 Instances
->CurrentCount
= This
->PinInstanceCount
[Pin
->PinId
];
778 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
779 IoStatus
->Status
= STATUS_SUCCESS
;
780 return STATUS_SUCCESS
;
784 KspHandleNecessaryPropertyInstances(
785 IN PIO_STATUS_BLOCK IoStatus
,
786 IN PKSIDENTIFIER Request
,
788 IN IKsFilterImpl
* This
)
791 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
793 if (!This
->Filter
.Descriptor
|| !This
->Filter
.Descriptor
->PinDescriptorsCount
)
795 /* no filter / pin descriptor */
796 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
797 return STATUS_NOT_IMPLEMENTED
;
800 /* ignore custom structs for now */
801 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
802 ASSERT(This
->Filter
.Descriptor
->PinDescriptorsCount
> Pin
->PinId
);
804 Result
= (PULONG
)Data
;
805 *Result
= This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].InstancesNecessary
;
807 IoStatus
->Information
= sizeof(ULONG
);
808 IoStatus
->Status
= STATUS_SUCCESS
;
809 return STATUS_SUCCESS
;
813 KspHandleDataIntersection(
815 IN PIO_STATUS_BLOCK IoStatus
,
816 IN PKSIDENTIFIER Request
,
819 IN IKsFilterImpl
* This
)
821 PKSMULTIPLE_ITEM MultipleItem
;
822 PKSDATARANGE DataRange
;
823 NTSTATUS Status
= STATUS_NO_MATCH
;
825 PIO_STACK_LOCATION IoStack
;
826 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
828 /* get stack location */
829 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
832 ASSERT(DataLength
== IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
834 /* Access parameters */
835 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
836 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
838 /* FIXME make sure its 64 bit aligned */
839 ASSERT(((ULONG_PTR
)DataRange
& 0x7) == 0);
841 if (!This
->Filter
.Descriptor
|| !This
->Filter
.Descriptor
->PinDescriptorsCount
)
843 /* no filter / pin descriptor */
844 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
845 return STATUS_NOT_IMPLEMENTED
;
848 /* ignore custom structs for now */
849 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
850 ASSERT(This
->Filter
.Descriptor
->PinDescriptorsCount
> Pin
->PinId
);
852 if (This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].IntersectHandler
== NULL
||
853 This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
== NULL
||
854 This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRangesCount
== 0)
856 /* no driver supported intersect handler / no provided data ranges */
857 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
858 return STATUS_NOT_IMPLEMENTED
;
861 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
863 UNICODE_STRING MajorFormat
, SubFormat
, Specifier
;
864 /* convert the guid to string */
865 RtlStringFromGUID(&DataRange
->MajorFormat
, &MajorFormat
);
866 RtlStringFromGUID(&DataRange
->SubFormat
, &SubFormat
);
867 RtlStringFromGUID(&DataRange
->Specifier
, &Specifier
);
869 DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index
, Pin
->PinId
, MajorFormat
.Buffer
, SubFormat
.Buffer
, Specifier
.Buffer
,
870 DataRange
->FormatSize
, DataRange
->SampleSize
, DataRange
->Alignment
, DataRange
->Flags
, DataRange
->Reserved
, DataLength
);
872 /* FIXME implement KsPinDataIntersectionEx */
873 /* Call miniport's proprietary handler */
874 Status
= This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].IntersectHandler(&This
->Filter
,
878 This
->Filter
.Descriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
[0], /* HACK */
882 DPRINT("KspHandleDataIntersection Status %lx\n", Status
);
884 if (Status
== STATUS_SUCCESS
|| Status
== STATUS_BUFFER_OVERFLOW
|| Status
== STATUS_BUFFER_TOO_SMALL
)
887 IoStatus
->Information
= Length
;
891 DataRange
= (PKSDATARANGE
)((PUCHAR
)DataRange
+ DataRange
->FormatSize
);
892 /* FIXME make sure its 64 bit aligned */
893 ASSERT(((ULONG_PTR
)DataRange
& 0x7) == 0);
895 IoStatus
->Status
= Status
;
901 FilterTopologyPropertyHandler(
903 IN PKSIDENTIFIER Request
,
906 IKsFilterImpl
* This
;
908 /* get filter implementation */
909 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
914 return KsTopologyPropertyHandler(Irp
, Request
, Data
, &This
->Topology
);
920 FilterGeneralComponentIdHandler(
922 IN PKSIDENTIFIER Request
,
925 PIO_STACK_LOCATION IoStack
;
926 IKsFilterImpl
* This
;
928 /* get filter implementation */
929 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
934 /* get current stack location */
935 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
936 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= sizeof(KSCOMPONENTID
));
938 if (This
->Filter
.Descriptor
->ComponentId
!= NULL
)
940 RtlMoveMemory(Data
, This
->Filter
.Descriptor
->ComponentId
, sizeof(KSCOMPONENTID
));
941 Irp
->IoStatus
.Information
= sizeof(KSCOMPONENTID
);
942 return STATUS_SUCCESS
;
947 return STATUS_NOT_FOUND
;
954 FilterPinPropertyHandler(
956 IN PKSIDENTIFIER Request
,
959 PIO_STACK_LOCATION IoStack
;
960 IKsFilterImpl
* This
;
961 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
963 /* get filter implementation */
964 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
969 /* get current stack location */
970 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
974 case KSPROPERTY_PIN_CTYPES
:
975 case KSPROPERTY_PIN_DATAFLOW
:
976 case KSPROPERTY_PIN_DATARANGES
:
977 case KSPROPERTY_PIN_INTERFACES
:
978 case KSPROPERTY_PIN_MEDIUMS
:
979 case KSPROPERTY_PIN_COMMUNICATION
:
980 case KSPROPERTY_PIN_CATEGORY
:
981 case KSPROPERTY_PIN_NAME
:
982 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
983 Status
= KspPinPropertyHandler(Irp
, Request
, Data
, This
->Filter
.Descriptor
->PinDescriptorsCount
, (const KSPIN_DESCRIPTOR
*)This
->Filter
.Descriptor
->PinDescriptors
, This
->Filter
.Descriptor
->PinDescriptorSize
);
985 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
986 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, TRUE
);
988 case KSPROPERTY_PIN_CINSTANCES
:
989 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, FALSE
);
991 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
992 Status
= KspHandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
);
995 case KSPROPERTY_PIN_DATAINTERSECTION
:
996 Status
= KspHandleDataIntersection(Irp
, &Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
);
1000 Status
= STATUS_NOT_FOUND
;
1002 DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This
->Filter
.Descriptor
->PinDescriptorsCount
, Request
->Id
, Status
);
1010 IKsFilter_DispatchDeviceIoControl(
1011 IN PDEVICE_OBJECT DeviceObject
,
1014 PIO_STACK_LOCATION IoStack
;
1016 IKsFilterImpl
* This
;
1018 PKSFILTER FilterInstance
;
1019 UNICODE_STRING GuidString
;
1020 PKSPROPERTY Property
;
1022 PKSP_NODE NodeProperty
;
1023 PKSNODE_DESCRIPTOR NodeDescriptor
;
1025 /* obtain filter from object header */
1026 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
1027 if (!NT_SUCCESS(Status
))
1030 /* get our real implementation */
1031 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Header
.OuterUnknown
);
1033 /* current irp stack */
1034 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1036 /* get property from input buffer */
1037 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1039 /* get filter instance */
1040 FilterInstance
= Filter
->lpVtbl
->GetStruct(Filter
);
1043 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSIDENTIFIER
));
1044 ASSERT(FilterInstance
);
1045 ASSERT(FilterInstance
->Descriptor
);
1046 ASSERT(FilterInstance
->Descriptor
->AutomationTable
);
1048 /* acquire control mutex */
1049 KeWaitForSingleObject(This
->Header
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1051 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_METHOD
)
1053 const KSMETHOD_SET
*MethodSet
= NULL
;
1054 ULONG MethodItemSize
= 0;
1056 /* check if the driver supports method sets */
1057 if (FilterInstance
->Descriptor
->AutomationTable
->MethodSetsCount
)
1059 SetCount
= FilterInstance
->Descriptor
->AutomationTable
->MethodSetsCount
;
1060 MethodSet
= FilterInstance
->Descriptor
->AutomationTable
->MethodSets
;
1061 MethodItemSize
= FilterInstance
->Descriptor
->AutomationTable
->MethodItemSize
;
1064 /* call method set handler */
1065 Status
= KspMethodHandlerWithAllocator(Irp
, SetCount
, MethodSet
, NULL
, MethodItemSize
);
1067 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
1069 const KSPROPERTY_SET
*PropertySet
= NULL
;
1070 ULONG PropertyItemSize
= 0;
1072 /* check if the driver supports method sets */
1073 if (Property
->Flags
& KSPROPERTY_TYPE_TOPOLOGY
)
1075 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSP_NODE
));
1076 NodeProperty
= (PKSP_NODE
)Property
;
1077 NodeDescriptor
= (PKSNODE_DESCRIPTOR
)((ULONG_PTR
)FilterInstance
->Descriptor
->NodeDescriptors
+ FilterInstance
->Descriptor
->NodeDescriptorSize
* NodeProperty
->NodeId
);
1078 if (NodeDescriptor
->AutomationTable
!= NULL
)
1080 SetCount
= NodeDescriptor
->AutomationTable
->PropertySetsCount
;
1081 PropertySet
= NodeDescriptor
->AutomationTable
->PropertySets
;
1082 PropertyItemSize
= 0;
1085 else if (FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
)
1087 SetCount
= FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
;
1088 PropertySet
= FilterInstance
->Descriptor
->AutomationTable
->PropertySets
;
1089 PropertyItemSize
= FilterInstance
->Descriptor
->AutomationTable
->PropertyItemSize
;
1090 // FIXME: handle variable sized property items
1091 ASSERT(PropertyItemSize
== sizeof(KSPROPERTY_ITEM
));
1092 PropertyItemSize
= 0;
1095 /* needed for our property handlers */
1096 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
1098 /* call property handler */
1099 Status
= KspPropertyHandler(Irp
, SetCount
, PropertySet
, NULL
, PropertyItemSize
);
1104 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
||
1105 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_DISABLE_EVENT
);
1107 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
)
1109 /* call enable event handlers */
1110 Status
= KspEnableEvent(Irp
,
1111 FilterInstance
->Descriptor
->AutomationTable
->EventSetsCount
,
1112 (PKSEVENT_SET
)FilterInstance
->Descriptor
->AutomationTable
->EventSets
,
1113 &This
->Header
.EventList
,
1115 (PVOID
)&This
->Header
.EventListLock
,
1117 FilterInstance
->Descriptor
->AutomationTable
->EventItemSize
);
1121 /* disable event handler */
1122 Status
= KsDisableEvent(Irp
, &This
->Header
.EventList
, KSEVENTS_SPINLOCK
, &This
->Header
.EventListLock
);
1126 RtlStringFromGUID(&Property
->Set
, &GuidString
);
1127 DPRINT("IKsFilter_DispatchDeviceIoControl property PinCount %x\n", FilterInstance
->Descriptor
->PinDescriptorsCount
);
1128 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
);
1129 RtlFreeUnicodeString(&GuidString
);
1131 /* release filter */
1132 Filter
->lpVtbl
->Release(Filter
);
1134 /* release control mutex */
1135 KeReleaseMutex(This
->Header
.ControlMutex
, FALSE
);
1137 if (Status
!= STATUS_PENDING
)
1139 Irp
->IoStatus
.Status
= Status
;
1140 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1147 static KSDISPATCH_TABLE DispatchTable
=
1149 IKsFilter_DispatchDeviceIoControl
,
1150 KsDispatchInvalidDeviceRequest
,
1151 KsDispatchInvalidDeviceRequest
,
1152 KsDispatchInvalidDeviceRequest
,
1153 IKsFilter_DispatchClose
,
1154 KsDispatchQuerySecurity
,
1155 KsDispatchSetSecurity
,
1156 KsDispatchFastIoDeviceControlFailure
,
1157 KsDispatchFastReadFailure
,
1158 KsDispatchFastReadFailure
,
1163 IKsFilter_CreateDescriptors(
1164 IKsFilterImpl
* This
,
1165 KSFILTER_DESCRIPTOR
* FilterDescriptor
)
1169 PKSNODE_DESCRIPTOR NodeDescriptor
;
1171 /* initialize pin descriptors */
1172 This
->FirstPin
= NULL
;
1173 This
->PinInstanceCount
= NULL
;
1174 This
->ProcessPinIndex
= NULL
;
1176 /* initialize topology descriptor */
1177 This
->Topology
.CategoriesCount
= FilterDescriptor
->CategoriesCount
;
1178 This
->Topology
.Categories
= FilterDescriptor
->Categories
;
1179 This
->Topology
.TopologyNodesCount
= FilterDescriptor
->NodeDescriptorsCount
;
1180 This
->Topology
.TopologyConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
1181 This
->Topology
.TopologyConnections
= FilterDescriptor
->Connections
;
1183 /* are there any templates */
1184 if (FilterDescriptor
->PinDescriptorsCount
)
1187 ASSERT(FilterDescriptor
->PinDescriptors
);
1189 /* FIXME handle variable sized pin descriptors */
1190 ASSERT(FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
1192 /* store pin descriptors ex */
1193 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->Filter
.Descriptor
->PinDescriptors
, FilterDescriptor
->PinDescriptorSize
* FilterDescriptor
->PinDescriptorsCount
,
1194 FilterDescriptor
->PinDescriptorSize
* FilterDescriptor
->PinDescriptorsCount
, 0);
1196 if (!NT_SUCCESS(Status
))
1198 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
1202 /* store pin instance count */
1203 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
,
1204 sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
, 0);
1206 if (!NT_SUCCESS(Status
))
1208 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
1212 /* store instantiated pin arrays */
1213 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->FirstPin
, sizeof(PVOID
) * FilterDescriptor
->PinDescriptorsCount
,
1214 sizeof(PVOID
) * FilterDescriptor
->PinDescriptorsCount
, 0);
1216 if (!NT_SUCCESS(Status
))
1218 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
1222 /* add new pin factory */
1223 RtlMoveMemory((PVOID
)This
->Filter
.Descriptor
->PinDescriptors
, FilterDescriptor
->PinDescriptors
, FilterDescriptor
->PinDescriptorSize
* FilterDescriptor
->PinDescriptorsCount
);
1225 /* allocate process pin index */
1226 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
, sizeof(KSPROCESSPIN_INDEXENTRY
) * FilterDescriptor
->PinDescriptorsCount
,
1227 sizeof(KSPROCESSPIN_INDEXENTRY
) * FilterDescriptor
->PinDescriptorsCount
, 0);
1229 if (!NT_SUCCESS(Status
))
1231 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
1238 if (FilterDescriptor
->ConnectionsCount
)
1240 /* modify connections array */
1241 Status
= _KsEdit(This
->Filter
.Bag
,
1242 (PVOID
*)&This
->Filter
.Descriptor
->Connections
,
1243 FilterDescriptor
->ConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
),
1244 FilterDescriptor
->ConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
),
1247 This
->Topology
.TopologyConnections
= This
->Filter
.Descriptor
->Connections
;
1248 This
->Topology
.TopologyConnectionsCount
= ((PKSFILTER_DESCRIPTOR
)This
->Filter
.Descriptor
)->ConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
1251 if (FilterDescriptor
->NodeDescriptorsCount
)
1254 ASSERT(FilterDescriptor
->NodeDescriptors
);
1257 ASSERT(FilterDescriptor
->NodeDescriptorSize
>= sizeof(KSNODE_DESCRIPTOR
));
1259 This
->Topology
.TopologyNodes
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
1260 /* allocate topology node types array */
1261 if (!This
->Topology
.TopologyNodes
)
1263 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
1264 return STATUS_INSUFFICIENT_RESOURCES
;
1267 This
->Topology
.TopologyNodesNames
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
1268 /* allocate topology names array */
1269 if (!This
->Topology
.TopologyNodesNames
)
1271 FreeItem((PVOID
)This
->Topology
.TopologyNodes
);
1272 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
1273 return STATUS_INSUFFICIENT_RESOURCES
;
1276 DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
1277 NodeDescriptor
= (PKSNODE_DESCRIPTOR
)FilterDescriptor
->NodeDescriptors
;
1278 for(Index
= 0; Index
< FilterDescriptor
->NodeDescriptorsCount
; Index
++)
1280 DPRINT("Index %lu Type %p Name %p\n", Index
, NodeDescriptor
->Type
, NodeDescriptor
->Name
);
1282 /* copy topology type */
1283 if (NodeDescriptor
->Type
)
1284 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodes
[Index
], NodeDescriptor
->Type
, sizeof(GUID
));
1286 /* copy topology name */
1287 if (NodeDescriptor
->Name
)
1288 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodesNames
[Index
], NodeDescriptor
->Name
, sizeof(GUID
));
1290 // next node descriptor
1291 NodeDescriptor
= (PKSNODE_DESCRIPTOR
)((ULONG_PTR
)NodeDescriptor
+ FilterDescriptor
->NodeDescriptorSize
);
1295 return STATUS_SUCCESS
;
1299 IKsFilter_CopyFilterDescriptor(
1300 IKsFilterImpl
* This
,
1301 const KSFILTER_DESCRIPTOR
* FilterDescriptor
)
1304 KSAUTOMATION_TABLE AutomationTable
;
1306 This
->Filter
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSFILTER_DESCRIPTOR
));
1307 if (!This
->Filter
.Descriptor
)
1308 return STATUS_INSUFFICIENT_RESOURCES
;
1310 Status
= KsAddItemToObjectBag(This
->Filter
.Bag
, (PVOID
)This
->Filter
.Descriptor
, NULL
);
1311 if (!NT_SUCCESS(Status
))
1313 FreeItem((PVOID
)This
->Filter
.Descriptor
);
1314 This
->Filter
.Descriptor
= NULL
;
1315 return STATUS_INSUFFICIENT_RESOURCES
;
1318 /* copy filter descriptor fields */
1319 RtlMoveMemory((PVOID
)This
->Filter
.Descriptor
, FilterDescriptor
, sizeof(KSFILTER_DESCRIPTOR
));
1321 /* zero automation table */
1322 RtlZeroMemory(&AutomationTable
, sizeof(KSAUTOMATION_TABLE
));
1324 /* setup filter property sets */
1325 AutomationTable
.PropertyItemSize
= sizeof(KSPROPERTY_ITEM
);
1326 AutomationTable
.PropertySetsCount
= 3;
1327 AutomationTable
.PropertySets
= FilterPropertySet
;
1329 /* merge filter automation table */
1330 Status
= KsMergeAutomationTables((PKSAUTOMATION_TABLE
*)&This
->Filter
.Descriptor
->AutomationTable
, (PKSAUTOMATION_TABLE
)FilterDescriptor
->AutomationTable
, &AutomationTable
, This
->Filter
.Bag
);
1341 PKSPIN NextPin
, CurPin
;
1342 PKSBASIC_HEADER BasicHeader
;
1343 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1346 ASSERT(Pin
->Id
< This
->Filter
.Descriptor
->PinDescriptorsCount
);
1348 if (This
->FirstPin
[Pin
->Id
] == NULL
)
1350 /* welcome first pin */
1351 This
->FirstPin
[Pin
->Id
] = Pin
;
1352 This
->PinInstanceCount
[Pin
->Id
]++;
1357 CurPin
= This
->FirstPin
[Pin
->Id
];
1361 /* get next instantiated pin */
1362 NextPin
= KsPinGetNextSiblingPin(CurPin
);
1368 }while(NextPin
!= NULL
);
1370 /* get basic header */
1371 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)CurPin
- sizeof(KSBASIC_HEADER
));
1374 BasicHeader
->Next
.Pin
= Pin
;
1378 IKsFilter_RemovePin(
1382 PKSPIN NextPin
, CurPin
, LastPin
;
1383 PKSBASIC_HEADER BasicHeader
;
1384 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1387 ASSERT(Pin
->Id
< This
->Filter
.Descriptor
->PinDescriptorsCount
);
1390 CurPin
= This
->FirstPin
[Pin
->Id
];
1395 /* get next instantiated pin */
1396 NextPin
= KsPinGetNextSiblingPin(CurPin
);
1402 /* get basic header of last pin */
1403 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)LastPin
- sizeof(KSBASIC_HEADER
));
1405 BasicHeader
->Next
.Pin
= NextPin
;
1409 /* erase last pin */
1410 This
->FirstPin
[Pin
->Id
] = NextPin
;
1412 /* decrement pin instance count */
1413 This
->PinInstanceCount
[Pin
->Id
]--;
1423 }while(NextPin
!= NULL
);
1432 IKsFilter_DispatchCreatePin(
1433 IN PDEVICE_OBJECT DeviceObject
,
1436 IKsFilterImpl
* This
;
1437 PKSOBJECT_CREATE_ITEM CreateItem
;
1438 PKSPIN_CONNECT Connect
;
1441 DPRINT("IKsFilter_DispatchCreatePin\n");
1443 /* get the create item */
1444 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
1446 /* get the filter object */
1447 This
= (IKsFilterImpl
*)CreateItem
->Context
;
1450 ASSERT(This
->Header
.Type
== KsObjectTypeFilter
);
1452 /* acquire control mutex */
1453 KeWaitForSingleObject(This
->Header
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1455 /* now validate the connect request */
1456 Status
= KspValidateConnectRequest(Irp
, This
->Filter
.Descriptor
->PinDescriptorsCount
, (PVOID
)This
->Filter
.Descriptor
->PinDescriptors
, This
->Filter
.Descriptor
->PinDescriptorSize
, &Connect
);
1458 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status
);
1460 if (NT_SUCCESS(Status
))
1463 ASSERT(Connect
->PinId
< This
->Filter
.Descriptor
->PinDescriptorsCount
);
1465 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect
->PinId
,
1466 This
->PinInstanceCount
[Connect
->PinId
],
1467 This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
].InstancesPossible
);
1469 if (This
->PinInstanceCount
[Connect
->PinId
] < This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
].InstancesPossible
)
1471 /* create the pin */
1472 Status
= KspCreatePin(DeviceObject
, Irp
, This
->Header
.KsDevice
, This
->FilterFactory
, (IKsFilter
*)&This
->Header
.OuterUnknown
, Connect
, (KSPIN_DESCRIPTOR_EX
*)&This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
]);
1474 DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status
);
1478 /* maximum instance count reached, bye-bye */
1479 Status
= STATUS_UNSUCCESSFUL
;
1480 DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
].InstancesPossible
, This
->PinInstanceCount
[Connect
->PinId
]);
1484 /* release control mutex */
1485 KeReleaseMutex(This
->Header
.ControlMutex
, FALSE
);
1487 if (Status
!= STATUS_PENDING
)
1489 /* complete request */
1490 Irp
->IoStatus
.Status
= Status
;
1491 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1495 DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status
);
1501 IKsFilter_DispatchCreateNode(
1502 IN PDEVICE_OBJECT DeviceObject
,
1506 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1507 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1508 return STATUS_UNSUCCESSFUL
;
1513 IKsFilter_AttachFilterToFilterFactory(
1514 IKsFilterImpl
* This
,
1515 PKSFILTERFACTORY FilterFactory
)
1517 PKSBASIC_HEADER BasicHeader
;
1521 /* get filter factory basic header */
1522 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1525 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1527 if (BasicHeader
->FirstChild
.FilterFactory
== NULL
)
1529 /* welcome first instantiated filter */
1530 BasicHeader
->FirstChild
.Filter
= &This
->Filter
;
1534 /* set to first entry */
1535 Filter
= BasicHeader
->FirstChild
.Filter
;
1539 /* get basic header */
1540 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1542 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1544 if (BasicHeader
->Next
.Filter
)
1546 /* iterate to next filter factory */
1547 Filter
= BasicHeader
->Next
.Filter
;
1551 /* found last entry */
1556 /* attach filter factory */
1557 BasicHeader
->Next
.Filter
= &This
->Filter
;
1561 IKsFilter_RemoveFilterFromFilterFactory(
1562 IKsFilterImpl
* This
,
1563 PKSFILTERFACTORY FilterFactory
)
1565 PKSBASIC_HEADER BasicHeader
;
1566 PKSFILTER Filter
, LastFilter
;
1568 /* get filter factory basic header */
1569 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1572 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1573 ASSERT(BasicHeader
->FirstChild
.Filter
!= NULL
);
1576 /* set to first entry */
1577 Filter
= BasicHeader
->FirstChild
.Filter
;
1582 if (Filter
== &This
->Filter
)
1586 /* get basic header */
1587 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)LastFilter
- sizeof(KSBASIC_HEADER
));
1588 /* remove filter instance */
1589 BasicHeader
->Next
.Filter
= This
->Header
.Next
.Filter
;
1594 /* remove filter instance */
1595 BasicHeader
->FirstChild
.Filter
= This
->Header
.Next
.Filter
;
1600 /* get basic header */
1601 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1603 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1605 LastFilter
= Filter
;
1606 if (BasicHeader
->Next
.Filter
)
1608 /* iterate to next filter factory */
1609 Filter
= BasicHeader
->Next
.Filter
;
1613 /* filter is not in list */
1622 IKsFilter_FilterCentricWorker(
1625 IKsProcessingObject
* Object
= (IKsProcessingObject
*)Ctx
;
1631 Object
->lpVtbl
->ProcessingObjectWork(Object
);
1637 IN PDEVICE_OBJECT DeviceObject
,
1639 IN IKsFilterFactory
*iface
)
1641 IKsFilterImpl
* This
;
1642 IKsDevice
*KsDevice
;
1643 PKSFILTERFACTORY Factory
;
1644 PIO_STACK_LOCATION IoStack
;
1645 PDEVICE_EXTENSION DeviceExtension
;
1647 PKSOBJECT_CREATE_ITEM CreateItem
;
1649 /* get device extension */
1650 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1652 /* get the filter factory */
1653 Factory
= iface
->lpVtbl
->GetStruct(iface
);
1655 if (!Factory
|| !Factory
->FilterDescriptor
)
1657 /* Sorry it just will not work */
1658 return STATUS_UNSUCCESSFUL
;
1661 if (Factory
->FilterDescriptor
->Flags
& KSFILTER_FLAG_DENY_USERMODE_ACCESS
)
1663 if (Irp
->RequestorMode
== UserMode
)
1665 /* filter not accessible from user mode */
1666 DPRINT1("Access denied\n");
1667 return STATUS_UNSUCCESSFUL
;
1671 /* allocate filter instance */
1672 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterImpl
));
1675 DPRINT1("KspCreateFilter OutOfMemory\n");
1676 return STATUS_INSUFFICIENT_RESOURCES
;
1679 /* initialize object bag */
1680 This
->Filter
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1681 if (!This
->Filter
.Bag
)
1685 DPRINT1("KspCreateFilter OutOfMemory\n");
1686 return STATUS_INSUFFICIENT_RESOURCES
;
1688 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->BasicHeader
.OuterUnknown
;
1689 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->Filter
.Bag
, NULL
);
1691 /* copy filter descriptor */
1692 Status
= IKsFilter_CopyFilterDescriptor(This
, Factory
->FilterDescriptor
);
1693 if (!NT_SUCCESS(Status
))
1695 /* not enough memory */
1696 FreeItem(This
->Filter
.Bag
);
1698 DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status
);
1699 return STATUS_INSUFFICIENT_RESOURCES
;
1702 /* get current irp stack */
1703 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1705 /* allocate create items */
1706 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 2);
1710 FreeItem(This
->Filter
.Bag
);
1712 DPRINT1("KspCreateFilter OutOfMemory\n");
1713 return STATUS_INSUFFICIENT_RESOURCES
;
1716 /* initialize pin create item */
1717 CreateItem
[0].Create
= IKsFilter_DispatchCreatePin
;
1718 CreateItem
[0].Context
= (PVOID
)This
;
1719 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1720 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Pin
);
1721 /* initialize node create item */
1722 CreateItem
[1].Create
= IKsFilter_DispatchCreateNode
;
1723 CreateItem
[1].Context
= (PVOID
)This
;
1724 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1725 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_TopologyNode
);
1728 /* initialize filter instance */
1730 This
->Header
.OuterUnknown
= (PUNKNOWN
)&vt_IKsFilter
;
1731 This
->lpVtblKsControl
= &vt_IKsControl
;
1732 This
->lpVtblKsProcessingObject
= &vt_IKsProcessingObject
;
1734 This
->Factory
= Factory
;
1735 This
->FilterFactory
= iface
;
1736 This
->FileObject
= IoStack
->FileObject
;
1737 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1739 /* initialize basic header */
1740 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
1741 This
->Header
.Parent
.KsFilterFactory
= iface
->lpVtbl
->GetStruct(iface
);
1742 This
->Header
.Type
= KsObjectTypeFilter
;
1743 This
->Header
.ControlMutex
= &This
->ControlMutex
;
1744 KeInitializeMutex(This
->Header
.ControlMutex
, 0);
1745 InitializeListHead(&This
->Header
.EventList
);
1746 KeInitializeSpinLock(&This
->Header
.EventListLock
);
1748 /* initialize and gate */
1749 KsGateInitializeAnd(&This
->Gate
, NULL
);
1751 /* FIXME initialize and gate based on pin flags */
1753 /* initialize work item */
1754 ExInitializeWorkItem(&This
->WorkItem
, IKsFilter_FilterCentricWorker
, (PVOID
)This
->lpVtblKsProcessingObject
);
1756 /* allocate counted work item */
1757 Status
= KsRegisterCountedWorker(HyperCriticalWorkQueue
, &This
->WorkItem
, &This
->Worker
);
1758 if (!NT_SUCCESS(Status
))
1760 /* what can go wrong, goes wrong */
1761 DPRINT1("KsRegisterCountedWorker failed with %lx\n", Status
);
1763 FreeItem(CreateItem
);
1767 /* allocate the stream descriptors */
1768 Status
= IKsFilter_CreateDescriptors(This
, (PKSFILTER_DESCRIPTOR
)Factory
->FilterDescriptor
);
1769 if (!NT_SUCCESS(Status
))
1771 /* what can go wrong, goes wrong */
1772 DPRINT1("IKsFilter_CreateDescriptors failed with %lx\n", Status
);
1773 KsUnregisterWorker(This
->Worker
);
1775 FreeItem(CreateItem
);
1781 /* does the filter have a filter dispatch */
1782 if (Factory
->FilterDescriptor
->Dispatch
)
1784 /* does it have a create routine */
1785 if (Factory
->FilterDescriptor
->Dispatch
->Create
)
1787 /* now let driver initialize the filter instance */
1789 ASSERT(This
->Header
.KsDevice
);
1790 ASSERT(This
->Header
.KsDevice
->Started
);
1791 Status
= Factory
->FilterDescriptor
->Dispatch
->Create(&This
->Filter
, Irp
);
1793 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
1795 /* driver failed to initialize */
1796 DPRINT1("Driver: Status %x\n", Status
);
1798 /* free filter instance */
1799 KsUnregisterWorker(This
->Worker
);
1801 FreeItem(CreateItem
);
1807 /* now allocate the object header */
1808 Status
= KsAllocateObjectHeader((PVOID
*)&This
->ObjectHeader
, 2, CreateItem
, Irp
, &DispatchTable
);
1809 if (!NT_SUCCESS(Status
))
1811 /* failed to allocate object header */
1812 DPRINT1("Failed to allocate object header %x\n", Status
);
1817 /* initialize object header extra fields */
1818 This
->ObjectHeader
->Type
= KsObjectTypeFilter
;
1819 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->Header
.OuterUnknown
;
1820 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Filter
;
1822 /* attach filter to filter factory */
1823 IKsFilter_AttachFilterToFilterFactory(This
, This
->Header
.Parent
.KsFilterFactory
);
1825 /* completed initialization */
1826 DPRINT1("KspCreateFilter done %lx KsDevice %p\n", Status
, This
->Header
.KsDevice
);
1836 KsFilterAcquireProcessingMutex(
1837 IN PKSFILTER Filter
)
1839 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1841 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1850 KsFilterReleaseProcessingMutex(
1851 IN PKSFILTER Filter
)
1853 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1855 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1865 KsFilterAddTopologyConnections (
1866 IN PKSFILTER Filter
,
1867 IN ULONG NewConnectionsCount
,
1868 IN
const KSTOPOLOGY_CONNECTION
*const NewTopologyConnections
)
1872 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1874 DPRINT("KsFilterAddTopologyConnections\n");
1876 ASSERT(This
->Filter
.Descriptor
);
1877 Count
= This
->Filter
.Descriptor
->ConnectionsCount
+ NewConnectionsCount
;
1880 /* modify connections array */
1881 Status
= _KsEdit(This
->Filter
.Bag
,
1882 (PVOID
*)&This
->Filter
.Descriptor
->Connections
,
1883 Count
* sizeof(KSTOPOLOGY_CONNECTION
),
1884 This
->Filter
.Descriptor
->ConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
),
1887 if (!NT_SUCCESS(Status
))
1890 DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status
);
1894 /* FIXME verify connections */
1896 /* copy new connections */
1897 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->Connections
[This
->Filter
.Descriptor
->ConnectionsCount
],
1898 NewTopologyConnections
,
1899 NewConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
));
1901 /* update topology */
1902 This
->Topology
.TopologyConnectionsCount
+= NewConnectionsCount
;
1903 ((PKSFILTER_DESCRIPTOR
)This
->Filter
.Descriptor
)->ConnectionsCount
+= NewConnectionsCount
;
1904 This
->Topology
.TopologyConnections
= This
->Filter
.Descriptor
->Connections
;
1915 KsFilterAttemptProcessing(
1916 IN PKSFILTER Filter
,
1917 IN BOOLEAN Asynchronous
)
1920 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1923 Gate
= This
->lpVtblKsProcessingObject
->GetAndGate((IKsProcessingObject
*)This
->lpVtblKsProcessingObject
);
1925 if (!KsGateCaptureThreshold(Gate
))
1927 /* filter control gate is closed */
1930 DPRINT1("processing\n");
1931 /* try initiate processing */
1932 This
->lpVtblKsProcessingObject
->Process((IKsProcessingObject
*)This
->lpVtblKsProcessingObject
, Asynchronous
);
1941 KsFilterCreateNode (
1942 IN PKSFILTER Filter
,
1943 IN
const KSNODE_DESCRIPTOR
*const NodeDescriptor
,
1947 return STATUS_NOT_IMPLEMENTED
;
1956 KsFilterCreatePinFactory (
1957 IN PKSFILTER Filter
,
1958 IN
const KSPIN_DESCRIPTOR_EX
*const InPinDescriptor
,
1963 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1965 DPRINT("KsFilterCreatePinFactory\n");
1967 /* calculate new count */
1968 Count
= This
->Filter
.Descriptor
->PinDescriptorsCount
+ 1;
1971 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
1973 /* modify pin descriptors ex array */
1974 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->Filter
.Descriptor
->PinDescriptors
, Count
* This
->Filter
.Descriptor
->PinDescriptorSize
, This
->Filter
.Descriptor
->PinDescriptorsCount
* This
->Filter
.Descriptor
->PinDescriptorSize
, 0);
1975 if (!NT_SUCCESS(Status
))
1978 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1982 /* modify pin instance count array */
1983 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * Count
, sizeof(ULONG
) * This
->Filter
.Descriptor
->PinDescriptorsCount
, 0);
1984 if (!NT_SUCCESS(Status
))
1987 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1991 /* modify first pin array */
1992 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->FirstPin
, sizeof(PVOID
) * Count
, sizeof(PVOID
) * This
->Filter
.Descriptor
->PinDescriptorsCount
, 0);
1993 if (!NT_SUCCESS(Status
))
1996 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
2000 /* add new pin factory */
2001 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->PinDescriptors
[This
->Filter
.Descriptor
->PinDescriptorsCount
], InPinDescriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
2003 /* allocate process pin index */
2004 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->ProcessPinIndex
, sizeof(KSPROCESSPIN_INDEXENTRY
) * Count
,
2005 sizeof(KSPROCESSPIN_INDEXENTRY
) * This
->Filter
.Descriptor
->PinDescriptorsCount
, 0);
2007 if (!NT_SUCCESS(Status
))
2009 DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status
);
2013 /* store new pin id */
2014 *PinID
= This
->Filter
.Descriptor
->PinDescriptorsCount
;
2016 /* increment pin descriptor count */
2017 ((PKSFILTER_DESCRIPTOR
)This
->Filter
.Descriptor
)->PinDescriptorsCount
++;
2020 DPRINT("KsFilterCreatePinFactory done\n");
2021 return STATUS_SUCCESS
;
2032 IN PKSFILTER Filter
)
2034 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
2036 /* return and-gate */
2046 KsFilterGetChildPinCount(
2047 IN PKSFILTER Filter
,
2050 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
2052 if (PinId
>= This
->Filter
.Descriptor
->PinDescriptorsCount
)
2054 /* index is out of bounds */
2057 /* return pin instance count */
2058 return This
->PinInstanceCount
[PinId
];
2067 KsFilterGetFirstChildPin(
2068 IN PKSFILTER Filter
,
2071 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
2073 if (PinId
>= This
->Filter
.Descriptor
->PinDescriptorsCount
)
2075 /* index is out of bounds */
2079 /* return first pin index */
2080 return This
->FirstPin
[PinId
];
2089 KsFilterRegisterPowerCallbacks(
2090 IN PKSFILTER Filter
,
2091 IN PFNKSFILTERPOWER Sleep OPTIONAL
,
2092 IN PFNKSFILTERPOWER Wake OPTIONAL
)
2094 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
2096 This
->Sleep
= Sleep
;
2109 PIO_STACK_LOCATION IoStack
;
2110 PKSIOBJECT_HEADER ObjectHeader
;
2112 DPRINT("KsGetFilterFromIrp\n");
2114 /* get current irp stack location */
2115 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2118 ASSERT(IoStack
->FileObject
);
2120 /* get object header */
2121 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
2123 if (ObjectHeader
->Type
== KsObjectTypeFilter
)
2125 /* irp is targeted at the filter */
2126 return (PKSFILTER
)ObjectHeader
->ObjectType
;
2128 else if (ObjectHeader
->Type
== KsObjectTypePin
)
2130 /* irp is for a pin */
2131 return KsPinGetParentFilter((PKSPIN
)ObjectHeader
->ObjectType
);
2135 /* irp is unappropiate to retrieve a filter */