2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/filter.c
5 * PURPOSE: KS IKsFilter interface functions
6 * PROGRAMMER: Johannes Anderwald
14 KSBASIC_HEADER Header
;
17 IKsFilterVtbl
*lpVtbl
;
18 IKsControlVtbl
*lpVtblKsControl
;
19 IKsFilterFactory
* FilterFactory
;
22 PKSIOBJECT_HEADER ObjectHeader
;
24 KSPIN_DESCRIPTOR
* PinDescriptors
;
25 ULONG PinDescriptorCount
;
26 PKSFILTERFACTORY Factory
;
27 PFILE_OBJECT FileObject
;
28 KMUTEX ProcessingMutex
;
31 PFNKSFILTERPOWER Sleep
;
32 PFNKSFILTERPOWER Wake
;
34 ULONG
*PinInstanceCount
;
36 KSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
40 const GUID IID_IKsControl
= {0x28F54685L
, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
41 const GUID IID_IKsFilter
= {0x3ef6ee44L
, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}};
42 const GUID KSPROPSETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
43 const GUID KSPROPSETID_Pin
= {0x8C134960L
, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
46 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet
, KspTopologyPropertyHandler
);
47 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet
, KspPinPropertyHandler
, KspPinPropertyHandler
, KspPinPropertyHandler
);
49 KSPROPERTY_SET FilterPropertySet
[] =
52 &KSPROPSETID_Topology
,
53 sizeof(IKsFilterTopologySet
) / sizeof(KSPROPERTY_ITEM
),
54 (const KSPROPERTY_ITEM
*)&IKsFilterTopologySet
,
60 sizeof(IKsFilterPinSet
) / sizeof(KSPROPERTY_ITEM
),
61 (const KSPROPERTY_ITEM
*)&IKsFilterPinSet
,
69 IKsControl_fnQueryInterface(
74 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
76 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
78 *Output
= &This
->lpVtbl
;
79 _InterlockedIncrement(&This
->ref
);
80 return STATUS_SUCCESS
;
82 return STATUS_UNSUCCESSFUL
;
90 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
92 return InterlockedIncrement(&This
->ref
);
100 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
102 InterlockedDecrement(&This
->ref
);
104 /* Return new reference count */
110 IKsControl_fnKsProperty(
112 IN PKSPROPERTY Property
,
113 IN ULONG PropertyLength
,
114 IN OUT PVOID PropertyData
,
116 OUT ULONG
* BytesReturned
)
118 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
120 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, Property
, PropertyLength
, PropertyData
, DataLength
, BytesReturned
);
126 IKsControl_fnKsMethod(
129 IN ULONG MethodLength
,
130 IN OUT PVOID MethodData
,
132 OUT ULONG
* BytesReturned
)
134 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
136 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_METHOD
, Method
, MethodLength
, MethodData
, DataLength
, BytesReturned
);
142 IKsControl_fnKsEvent(
144 IN PKSEVENT Event OPTIONAL
,
145 IN ULONG EventLength
,
146 IN OUT PVOID EventData
,
148 OUT ULONG
* BytesReturned
)
150 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
154 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_ENABLE_EVENT
, Event
, EventLength
, EventData
, DataLength
, BytesReturned
);
158 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_DISABLE_EVENT
, EventData
, DataLength
, NULL
, 0, BytesReturned
);
163 static IKsControlVtbl vt_IKsControl
=
165 IKsControl_fnQueryInterface
,
167 IKsControl_fnRelease
,
168 IKsControl_fnKsProperty
,
169 IKsControl_fnKsMethod
,
176 IKsFilter_fnQueryInterface(
181 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
183 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
) ||
184 IsEqualGUIDAligned(refiid
, &IID_IKsFilter
))
186 *Output
= &This
->lpVtbl
;
187 _InterlockedIncrement(&This
->ref
);
188 return STATUS_SUCCESS
;
190 else if (IsEqualGUIDAligned(refiid
, &IID_IKsControl
))
192 *Output
= &This
->lpVtblKsControl
;
193 _InterlockedIncrement(&This
->ref
);
194 return STATUS_SUCCESS
;
197 return STATUS_UNSUCCESSFUL
;
205 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
207 return InterlockedIncrement(&This
->ref
);
215 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
217 InterlockedDecrement(&This
->ref
);
224 /* Return new reference count */
231 IKsFilter_fnGetStruct(
234 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
236 return &This
->Filter
;
241 IKsFilter_fnDoAllNecessaryPinsExist(
250 IKsFilter_fnCreateNode(
254 IN PLIST_ENTRY ListEntry
)
257 return STATUS_NOT_IMPLEMENTED
;
262 IKsFilter_fnBindProcessPinsToPipeSection(
264 IN
struct KSPROCESSPIPESECTION
*Section
,
268 OUT PKSGATE
*OutGate
)
271 return STATUS_NOT_IMPLEMENTED
;
276 IKsFilter_fnUnbindProcessPinsFromPipeSection(
278 IN
struct KSPROCESSPIPESECTION
*Section
)
281 return STATUS_NOT_IMPLEMENTED
;
286 IKsFilter_fnAddProcessPin(
288 IN PKSPROCESSPIN ProcessPin
)
291 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
293 /* first acquire processing mutex */
294 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
296 /* allocate new pins array */
297 Pins
= AllocateItem(NonPagedPool
, sizeof(PKSPROCESSPIN
) * (This
->ProcessPinIndex
.Count
+ 1));
299 /* check if allocation succeeded */
302 if (This
->ProcessPinIndex
.Count
)
304 /* copy old pin index */
305 RtlMoveMemory(Pins
, This
->ProcessPinIndex
.Pins
, sizeof(PKSPROCESSPIN
) * This
->ProcessPinIndex
.Count
);
308 /* add new process pin */
309 Pins
[This
->ProcessPinIndex
.Count
] = ProcessPin
;
311 /* free old process pin */
312 FreeItem(This
->ProcessPinIndex
.Pins
);
314 /* store new process pin index */
315 This
->ProcessPinIndex
.Pins
= Pins
;
316 This
->ProcessPinIndex
.Count
++;
319 /* release process mutex */
320 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
323 return STATUS_SUCCESS
;
325 return STATUS_INSUFFICIENT_RESOURCES
;
331 IKsFilter_fnRemoveProcessPin(
333 IN PKSPROCESSPIN ProcessPin
)
336 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
338 /* first acquire processing mutex */
339 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
341 /* iterate through process pin index array and search for the process pin to be removed */
342 for(Index
= 0; Index
< This
->ProcessPinIndex
.Count
; Index
++)
344 if (This
->ProcessPinIndex
.Pins
[Index
] == ProcessPin
)
346 /* found process pin */
347 if (Index
+ 1 < This
->ProcessPinIndex
.Count
)
350 RtlMoveMemory(&This
->ProcessPinIndex
.Pins
[Index
], &This
->ProcessPinIndex
.Pins
[Index
+1], This
->ProcessPinIndex
.Count
- Index
- 1);
352 /* decrement process pin count */
353 This
->ProcessPinIndex
.Count
--;
357 /* release process mutex */
358 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
361 return STATUS_SUCCESS
;
366 IKsFilter_fnReprepareProcessPipeSection(
368 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
377 IKsFilter_fnDeliverResetState(
379 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
380 IN KSRESET ResetState
)
387 IKsFilter_fnIsFrameHolding(
396 IKsFilter_fnRegisterForCopyCallbacks(
404 PKSPROCESSPIN_INDEXENTRY
406 IKsFilter_fnGetProcessDispatch(
413 static IKsFilterVtbl vt_IKsFilter
=
415 IKsFilter_fnQueryInterface
,
418 IKsFilter_fnGetStruct
,
419 IKsFilter_fnDoAllNecessaryPinsExist
,
420 IKsFilter_fnCreateNode
,
421 IKsFilter_fnBindProcessPinsToPipeSection
,
422 IKsFilter_fnUnbindProcessPinsFromPipeSection
,
423 IKsFilter_fnAddProcessPin
,
424 IKsFilter_fnRemoveProcessPin
,
425 IKsFilter_fnReprepareProcessPipeSection
,
426 IKsFilter_fnDeliverResetState
,
427 IKsFilter_fnIsFrameHolding
,
428 IKsFilter_fnRegisterForCopyCallbacks
,
429 IKsFilter_fnGetProcessDispatch
433 IKsFilter_GetFilterFromIrp(
435 OUT IKsFilter
**Filter
)
437 PIO_STACK_LOCATION IoStack
;
438 PKSIOBJECT_HEADER ObjectHeader
;
441 /* get current irp stack */
442 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
445 ASSERT(IoStack
->FileObject
!= NULL
);
447 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
449 /* sanity is important */
450 ASSERT(ObjectHeader
!= NULL
);
451 ASSERT(ObjectHeader
->Type
== KsObjectTypeFilter
);
452 ASSERT(ObjectHeader
->Unknown
!= NULL
);
454 /* get our private interface */
455 Status
= ObjectHeader
->Unknown
->lpVtbl
->QueryInterface(ObjectHeader
->Unknown
, &IID_IKsFilter
, (PVOID
*)Filter
);
457 if (!NT_SUCCESS(Status
))
459 /* something is wrong here */
460 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader
->Unknown
);
461 Irp
->IoStatus
.Status
= Status
;
463 /* complete and forget irp */
464 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
473 IKsFilter_DispatchClose(
474 IN PDEVICE_OBJECT DeviceObject
,
478 IKsFilterImpl
* This
;
481 /* obtain filter from object header */
482 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
483 if (!NT_SUCCESS(Status
))
486 /* get our real implementation */
487 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
489 /* does the driver support notifications */
490 if (This
->Factory
->FilterDescriptor
&& This
->Factory
->FilterDescriptor
->Dispatch
&& This
->Factory
->FilterDescriptor
->Dispatch
->Close
)
492 /* call driver's filter close function */
493 Status
= This
->Factory
->FilterDescriptor
->Dispatch
->Close(&This
->Filter
, Irp
);
496 if (NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
498 /* save the result */
499 Irp
->IoStatus
.Status
= Status
;
501 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
503 /* FIXME remove our instance from the filter factory */
506 /* free object header */
507 KsFreeObjectHeader(This
->ObjectHeader
);
511 /* complete and forget */
512 Irp
->IoStatus
.Status
= Status
;
514 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
522 KspHandlePropertyInstances(
523 IN PIO_STATUS_BLOCK IoStatus
,
524 IN PKSIDENTIFIER Request
,
526 IN IKsFilterImpl
* This
,
529 KSPIN_CINSTANCES
* Instances
;
530 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
532 if (!This
->Factory
->FilterDescriptor
|| !This
->Factory
->FilterDescriptor
->PinDescriptorsCount
)
534 /* no filter / pin descriptor */
535 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
536 return STATUS_NOT_IMPLEMENTED
;
539 /* ignore custom structs for now */
540 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
541 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorsCount
> Pin
->PinId
);
543 Instances
= (KSPIN_CINSTANCES
*)Data
;
544 /* max instance count */
545 Instances
->PossibleCount
= This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].InstancesPossible
;
546 /* current instance count */
547 Instances
->CurrentCount
= This
->PinInstanceCount
[Pin
->PinId
];
549 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
550 IoStatus
->Status
= STATUS_SUCCESS
;
551 return STATUS_SUCCESS
;
555 KspHandleNecessaryPropertyInstances(
556 IN PIO_STATUS_BLOCK IoStatus
,
557 IN PKSIDENTIFIER Request
,
559 IN IKsFilterImpl
* This
)
562 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
564 if (!This
->Factory
->FilterDescriptor
|| !This
->Factory
->FilterDescriptor
->PinDescriptorsCount
)
566 /* no filter / pin descriptor */
567 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
568 return STATUS_NOT_IMPLEMENTED
;
571 /* ignore custom structs for now */
572 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
573 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorsCount
> Pin
->PinId
);
575 Result
= (PULONG
)Data
;
576 *Result
= This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].InstancesNecessary
;
578 IoStatus
->Information
= sizeof(ULONG
);
579 IoStatus
->Status
= STATUS_SUCCESS
;
580 return STATUS_SUCCESS
;
584 KspHandleDataIntersection(
586 IN PIO_STATUS_BLOCK IoStatus
,
587 IN PKSIDENTIFIER Request
,
590 IN IKsFilterImpl
* This
)
592 PKSMULTIPLE_ITEM MultipleItem
;
593 PKSDATARANGE DataRange
;
594 NTSTATUS Status
= STATUS_NO_MATCH
;
596 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
598 /* Access parameters */
599 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
600 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
602 if (!This
->Factory
->FilterDescriptor
|| !This
->Factory
->FilterDescriptor
->PinDescriptorsCount
)
604 /* no filter / pin descriptor */
605 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
606 return STATUS_NOT_IMPLEMENTED
;
609 /* ignore custom structs for now */
610 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
611 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorsCount
> Pin
->PinId
);
613 if (This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].IntersectHandler
== NULL
||
614 This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
== NULL
||
615 This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRangesCount
== 0)
617 /* no driver supported intersect handler / no provided data ranges */
618 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
619 return STATUS_NOT_IMPLEMENTED
;
622 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
624 /* Call miniport's properitary handler */
625 Status
= This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].IntersectHandler(NULL
, /* context */
629 (PKSDATAFORMAT
)This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
,
634 if (Status
== STATUS_SUCCESS
)
636 IoStatus
->Information
= Length
;
639 DataRange
= UlongToPtr(PtrToUlong(DataRange
) + DataRange
->FormatSize
);
642 IoStatus
->Status
= Status
;
648 KspPinPropertyHandler(
650 IN PKSIDENTIFIER Request
,
653 PIO_STACK_LOCATION IoStack
;
654 IKsFilterImpl
* This
;
655 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
657 /* get filter implementation */
658 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
660 /* get current stack location */
661 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
665 case KSPROPERTY_PIN_CTYPES
:
666 case KSPROPERTY_PIN_DATAFLOW
:
667 case KSPROPERTY_PIN_DATARANGES
:
668 case KSPROPERTY_PIN_INTERFACES
:
669 case KSPROPERTY_PIN_MEDIUMS
:
670 case KSPROPERTY_PIN_COMMUNICATION
:
671 case KSPROPERTY_PIN_CATEGORY
:
672 case KSPROPERTY_PIN_NAME
:
673 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
674 Status
= KsPinPropertyHandler(Irp
, Request
, Data
, This
->PinDescriptorCount
, This
->PinDescriptors
);
676 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
677 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, TRUE
);
679 case KSPROPERTY_PIN_CINSTANCES
:
680 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, FALSE
);
682 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
683 Status
= KspHandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
);
686 case KSPROPERTY_PIN_DATAINTERSECTION
:
687 Status
= KspHandleDataIntersection(Irp
, &Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
);
689 case KSPROPERTY_PIN_PHYSICALCONNECTION
:
690 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
692 Status
= STATUS_NOT_IMPLEMENTED
;
696 Status
= STATUS_UNSUCCESSFUL
;
704 IKsFilter_DispatchDeviceIoControl(
705 IN PDEVICE_OBJECT DeviceObject
,
708 PIO_STACK_LOCATION IoStack
;
710 IKsFilterImpl
* This
;
712 PKSFILTER FilterInstance
;
714 /* obtain filter from object header */
715 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
716 if (!NT_SUCCESS(Status
))
719 /* get our real implementation */
720 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
722 /* current irp stack */
723 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
725 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
729 /* release filter interface */
730 Filter
->lpVtbl
->Release(Filter
);
732 /* complete and forget irp */
733 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
734 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
735 return STATUS_NOT_IMPLEMENTED
;
738 /* call property handler supported by ks */
739 Status
= KspPropertyHandler(Irp
, 2, FilterPropertySet
, NULL
, sizeof(KSPROPERTY_ITEM
));
741 if (Status
== STATUS_NOT_FOUND
)
743 /* get filter instance */
744 FilterInstance
= Filter
->lpVtbl
->GetStruct(Filter
);
746 /* check if the driver supports property sets */
747 if (FilterInstance
->Descriptor
->AutomationTable
&& FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
)
749 /* call driver's filter property handler */
750 Status
= KspPropertyHandler(Irp
,
751 FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
,
752 FilterInstance
->Descriptor
->AutomationTable
->PropertySets
,
754 FilterInstance
->Descriptor
->AutomationTable
->PropertyItemSize
);
758 Irp
->IoStatus
.Status
= Status
;
759 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
765 static KSDISPATCH_TABLE DispatchTable
=
767 IKsFilter_DispatchDeviceIoControl
,
768 KsDispatchInvalidDeviceRequest
,
769 KsDispatchInvalidDeviceRequest
,
770 KsDispatchInvalidDeviceRequest
,
771 IKsFilter_DispatchClose
,
772 KsDispatchQuerySecurity
,
773 KsDispatchSetSecurity
,
774 KsDispatchFastIoDeviceControlFailure
,
775 KsDispatchFastReadFailure
,
776 KsDispatchFastReadFailure
,
781 IKsFilter_CreateDescriptors(
782 IKsFilterImpl
* This
,
783 KSFILTER_DESCRIPTOR
* FilterDescriptor
)
787 /* initialize pin descriptors */
788 if (FilterDescriptor
->PinDescriptorsCount
)
790 /* allocate pin instance count array */
791 This
->PinInstanceCount
= AllocateItem(NonPagedPool
, sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
);
792 if(!This
->PinDescriptors
)
794 return STATUS_INSUFFICIENT_RESOURCES
;
797 /* allocate first pin array */
798 This
->FirstPin
= AllocateItem(NonPagedPool
, sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
);
801 FreeItem(This
->PinDescriptors
);
802 return STATUS_INSUFFICIENT_RESOURCES
;
806 /* allocate pin descriptor array */
807 This
->PinDescriptors
= AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescriptor
->PinDescriptorsCount
);
808 if(!This
->PinDescriptors
)
810 FreeItem(This
->PinInstanceCount
);
811 return STATUS_INSUFFICIENT_RESOURCES
;
815 This
->PinDescriptorCount
= FilterDescriptor
->PinDescriptorsCount
;
816 /* now copy those pin descriptors over */
817 for(Index
= 0; Index
< FilterDescriptor
->PinDescriptorsCount
; Index
++)
819 /* copy one pin per time */
820 RtlMoveMemory(&This
->PinDescriptors
[Index
], &FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
824 /* initialize topology descriptor */
825 This
->Topology
.CategoriesCount
= FilterDescriptor
->CategoriesCount
;
826 This
->Topology
.Categories
= FilterDescriptor
->Categories
;
827 This
->Topology
.TopologyNodesCount
= FilterDescriptor
->NodeDescriptorsCount
;
828 This
->Topology
.TopologyConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
829 This
->Topology
.TopologyConnections
= FilterDescriptor
->Connections
;
831 if (This
->Topology
.TopologyNodesCount
> 0)
833 This
->Topology
.TopologyNodes
= AllocateItem(NonPagedPool
, sizeof(GUID
) * This
->Topology
.TopologyNodesCount
);
834 /* allocate topology node types array */
835 if (!This
->Topology
.TopologyNodes
)
836 return STATUS_INSUFFICIENT_RESOURCES
;
838 This
->Topology
.TopologyNodesNames
= AllocateItem(NonPagedPool
, sizeof(GUID
) * This
->Topology
.TopologyNodesCount
);
839 /* allocate topology names array */
840 if (!This
->Topology
.TopologyNodesNames
)
842 FreeItem((PVOID
)This
->Topology
.TopologyNodes
);
843 return STATUS_INSUFFICIENT_RESOURCES
;
846 for(Index
= 0; Index
< This
->Topology
.TopologyNodesCount
; Index
++)
848 /* copy topology type */
849 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodes
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Type
, sizeof(GUID
));
850 /* copy topology name */
851 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodesNames
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Name
, sizeof(GUID
));
856 return STATUS_SUCCESS
;
860 IKsFilter_CopyFilterDescriptor(
861 IKsFilterImpl
* This
,
862 const KSFILTER_DESCRIPTOR
* FilterDescriptor
)
864 This
->Filter
.Descriptor
= (const KSFILTER_DESCRIPTOR
*)AllocateItem(NonPagedPool
, sizeof(KSFILTER_DESCRIPTOR
));
865 if (!This
->Filter
.Descriptor
)
866 return STATUS_INSUFFICIENT_RESOURCES
;
868 /* copy all fields */
869 RtlMoveMemory((PVOID
)This
->Filter
.Descriptor
, FilterDescriptor
, sizeof(KSFILTER_DESCRIPTOR
));
872 /* perform deep copy of pin descriptors */
873 if (FilterDescriptor
->PinDescriptorsCount
)
875 KSPIN_DESCRIPTOR_EX
* PinDescriptors
= (KSPIN_DESCRIPTOR_EX
*)AllocateItem(NonPagedPool
, FilterDescriptor
->PinDescriptorSize
* FilterDescriptor
->PinDescriptorsCount
);
880 FreeItem((PVOID
)This
->Filter
.Descriptor
);
881 return STATUS_INSUFFICIENT_RESOURCES
;
883 RtlMoveMemory((PVOID
)PinDescriptors
, FilterDescriptor
->PinDescriptors
, FilterDescriptor
->PinDescriptorSize
* FilterDescriptor
->PinDescriptorsCount
);
885 /* brain-dead gcc hack */
886 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->PinDescriptors
, PinDescriptors
, sizeof(PKSPIN_DESCRIPTOR_EX
));
890 /* perform deep copy of node descriptors */
891 if (FilterDescriptor
->NodeDescriptorsCount
)
893 KSNODE_DESCRIPTOR
* NodeDescriptor
= AllocateItem(NonPagedPool
, FilterDescriptor
->NodeDescriptorsCount
* FilterDescriptor
->NodeDescriptorSize
);
896 if (This
->Filter
.Descriptor
->PinDescriptors
)
897 FreeItem((PVOID
)This
->Filter
.Descriptor
->PinDescriptors
);
898 FreeItem((PVOID
)This
->Filter
.Descriptor
);
899 return STATUS_INSUFFICIENT_RESOURCES
;
901 RtlMoveMemory((PVOID
)NodeDescriptor
, FilterDescriptor
->NodeDescriptors
, FilterDescriptor
->NodeDescriptorsCount
* FilterDescriptor
->NodeDescriptorSize
);
903 /* brain-dead gcc hack */
904 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->NodeDescriptors
, NodeDescriptor
, sizeof(PKSNODE_DESCRIPTOR
));
907 /* perform deep copy of connections descriptors */
908 if (FilterDescriptor
->NodeDescriptorsCount
)
910 KSTOPOLOGY_CONNECTION
* Connections
= AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY_CONNECTION
) * FilterDescriptor
->ConnectionsCount
);
913 if (This
->Filter
.Descriptor
->PinDescriptors
)
914 FreeItem((PVOID
)This
->Filter
.Descriptor
->PinDescriptors
);
916 if (This
->Filter
.Descriptor
->NodeDescriptors
)
917 FreeItem((PVOID
)This
->Filter
.Descriptor
->PinDescriptors
);
919 FreeItem((PVOID
)This
->Filter
.Descriptor
);
920 return STATUS_INSUFFICIENT_RESOURCES
;
923 RtlMoveMemory((PVOID
)Connections
, FilterDescriptor
->Connections
, sizeof(KSTOPOLOGY_CONNECTION
) * FilterDescriptor
->ConnectionsCount
);
925 /* brain-dead gcc hack */
926 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->Connections
, Connections
, sizeof(PKSTOPOLOGY_CONNECTION
));
929 return STATUS_SUCCESS
;
938 PKSPIN NextPin
, CurPin
;
939 PKSBASIC_HEADER BasicHeader
;
940 IKsFilterImpl
* This
= (IKsFilterImpl
*)Filter
;
943 ASSERT(Pin
->Id
< This
->PinDescriptorCount
);
945 if (This
->FirstPin
[Pin
->Id
] == NULL
)
947 /* welcome first pin */
948 This
->FirstPin
[Pin
->Id
] = Pin
;
949 return STATUS_SUCCESS
;
953 CurPin
= This
->FirstPin
[Pin
->Id
];
957 /* get next instantiated pin */
958 NextPin
= KsPinGetNextSiblingPin(CurPin
);
964 }while(NextPin
!= NULL
);
966 /* get basic header */
967 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)CurPin
- sizeof(KSBASIC_HEADER
));
970 BasicHeader
->Next
.Pin
= Pin
;
972 return STATUS_SUCCESS
;
978 IKsFilter_DispatchCreatePin(
979 IN PDEVICE_OBJECT DeviceObject
,
982 IKsFilterImpl
* This
;
983 PKSOBJECT_CREATE_ITEM CreateItem
;
984 PKSPIN_CONNECT Connect
;
987 /* get the create item */
988 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
990 /* get the filter object */
991 This
= (IKsFilterImpl
*)CreateItem
->Context
;
993 /* acquire control mutex */
994 KeWaitForSingleObject(&This
->Header
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
996 /* now validate the connect request */
997 Status
= KsValidateConnectRequest(Irp
, This
->PinDescriptorCount
, This
->PinDescriptors
, &Connect
);
999 if (NT_SUCCESS(Status
))
1001 if (This
->PinInstanceCount
[Connect
->PinId
] < This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
].InstancesPossible
)
1003 /* create the pin */
1004 Status
= KspCreatePin(DeviceObject
, Irp
, This
->Header
.KsDevice
, This
->FilterFactory
, (IKsFilter
*)&This
->lpVtbl
, Connect
, (KSPIN_DESCRIPTOR_EX
*)&This
->Filter
.Descriptor
->PinDescriptors
[Connect
->PinId
]);
1006 if (NT_SUCCESS(Status
))
1008 /* successfully created pin, increment pin instance count */
1009 This
->PinInstanceCount
[Connect
->PinId
]++;
1014 /* maximum instance count reached, bye-bye */
1015 Status
= STATUS_UNSUCCESSFUL
;
1019 /* release control mutex */
1020 KeReleaseMutex(&This
->Header
.ControlMutex
, FALSE
);
1022 if (Status
!= STATUS_PENDING
)
1024 /* complete request */
1025 Irp
->IoStatus
.Status
= Status
;
1026 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1034 IKsFilter_DispatchCreateNode(
1035 IN PDEVICE_OBJECT DeviceObject
,
1039 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1040 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1041 return STATUS_UNSUCCESSFUL
;
1046 IKsFilter_AttachFilterToFilterFactory(
1047 IKsFilterImpl
* This
,
1048 PKSFILTERFACTORY FilterFactory
)
1050 PKSBASIC_HEADER BasicHeader
;
1054 /* get filter factory basic header */
1055 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1058 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1060 if (BasicHeader
->FirstChild
.FilterFactory
== NULL
)
1062 /* welcome first instantiated filter */
1063 BasicHeader
->FirstChild
.Filter
= &This
->Filter
;
1067 /* set to first entry */
1068 Filter
= BasicHeader
->FirstChild
.Filter
;
1072 /* get basic header */
1073 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1075 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1077 if (BasicHeader
->Next
.Filter
)
1079 /* iterate to next filter factory */
1080 Filter
= BasicHeader
->Next
.Filter
;
1084 /* found last entry */
1087 }while(FilterFactory
);
1089 /* attach filter factory */
1090 BasicHeader
->Next
.Filter
= &This
->Filter
;
1096 IN PDEVICE_OBJECT DeviceObject
,
1098 IN IKsFilterFactory
*iface
)
1100 IKsFilterImpl
* This
;
1101 IKsDevice
*KsDevice
;
1102 PKSFILTERFACTORY Factory
;
1103 PIO_STACK_LOCATION IoStack
;
1104 PDEVICE_EXTENSION DeviceExtension
;
1106 PKSOBJECT_CREATE_ITEM CreateItem
;
1108 /* get device extension */
1109 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1111 /* get the filter factory */
1112 Factory
= iface
->lpVtbl
->GetStruct(iface
);
1114 if (!Factory
|| !Factory
->FilterDescriptor
|| !Factory
->FilterDescriptor
->Dispatch
|| !Factory
->FilterDescriptor
->Dispatch
->Create
)
1116 /* Sorry it just will not work */
1117 return STATUS_UNSUCCESSFUL
;
1120 /* allocate filter instance */
1121 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterFactory
));
1123 return STATUS_INSUFFICIENT_RESOURCES
;
1125 /* copy filter descriptor */
1126 Status
= IKsFilter_CopyFilterDescriptor(This
, Factory
->FilterDescriptor
);
1127 if (!NT_SUCCESS(Status
))
1129 /* not enough memory */
1131 return STATUS_INSUFFICIENT_RESOURCES
;
1134 /* get current irp stack */
1135 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1137 /* initialize object bag */
1138 This
->Filter
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1139 if (!This
->Filter
.Bag
)
1143 return STATUS_INSUFFICIENT_RESOURCES
;
1146 /* allocate create items */
1147 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 2);
1152 return STATUS_INSUFFICIENT_RESOURCES
;
1155 /* initialize pin create item */
1156 CreateItem
[0].Create
= IKsFilter_DispatchCreatePin
;
1157 CreateItem
[0].Context
= (PVOID
)This
;
1158 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1159 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Pin
);
1160 /* initialize node create item */
1161 CreateItem
[1].Create
= IKsFilter_DispatchCreateNode
;
1162 CreateItem
[1].Context
= (PVOID
)This
;
1163 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1164 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_TopologyNode
);
1167 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
1168 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->Filter
.Bag
, NULL
);
1170 /* initialize filter instance */
1172 This
->lpVtbl
= &vt_IKsFilter
;
1173 This
->lpVtblKsControl
= &vt_IKsControl
;
1175 This
->Filter
.Descriptor
= Factory
->FilterDescriptor
;
1176 This
->Factory
= Factory
;
1177 This
->FilterFactory
= iface
;
1178 This
->FileObject
= IoStack
->FileObject
;
1179 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1180 /* initialize basic header */
1181 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
1182 This
->Header
.Parent
.KsFilterFactory
= iface
->lpVtbl
->GetStruct(iface
);
1183 This
->Header
.Type
= KsObjectTypeFilter
;
1184 KeInitializeMutex(&This
->Header
.ControlMutex
, 0);
1185 InitializeListHead(&This
->Header
.EventList
);
1186 KeInitializeSpinLock(&This
->Header
.EventListLock
);
1188 /* allocate the stream descriptors */
1189 Status
= IKsFilter_CreateDescriptors(This
, (PKSFILTER_DESCRIPTOR
)Factory
->FilterDescriptor
);
1190 if (!NT_SUCCESS(Status
))
1192 /* what can go wrong, goes wrong */
1194 FreeItem(CreateItem
);
1198 /* does the filter have a filter dispatch */
1199 if (Factory
->FilterDescriptor
->Dispatch
)
1201 /* does it have a create routine */
1202 if (Factory
->FilterDescriptor
->Dispatch
->Create
)
1204 /* now let driver initialize the filter instance */
1205 Status
= Factory
->FilterDescriptor
->Dispatch
->Create(&This
->Filter
, Irp
);
1207 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
1209 /* driver failed to initialize */
1210 DPRINT1("Driver: Status %x\n", Status
);
1212 /* free filter instance */
1214 FreeItem(CreateItem
);
1220 /* now allocate the object header */
1221 Status
= KsAllocateObjectHeader((PVOID
*)&This
->ObjectHeader
, 2, CreateItem
, Irp
, &DispatchTable
);
1222 if (!NT_SUCCESS(Status
))
1224 /* failed to allocate object header */
1225 DPRINT1("Failed to allocate object header %x\n", Status
);
1230 /* initialize object header extra fields */
1231 This
->ObjectHeader
->Type
= KsObjectTypeFilter
;
1232 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
1233 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Filter
;
1235 /* attach filter to filter factory */
1236 IKsFilter_AttachFilterToFilterFactory(This
, This
->Header
.Parent
.KsFilterFactory
);
1238 /* completed initialization */
1248 KsFilterAcquireProcessingMutex(
1249 IN PKSFILTER Filter
)
1251 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1253 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1262 KsFilterReleaseProcessingMutex(
1263 IN PKSFILTER Filter
)
1265 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1267 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1276 KsFilterAddTopologyConnections (
1277 IN PKSFILTER Filter
,
1278 IN ULONG NewConnectionsCount
,
1279 IN
const KSTOPOLOGY_CONNECTION
*const NewTopologyConnections
)
1282 KSTOPOLOGY_CONNECTION
* Connections
;
1283 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1285 Count
= This
->Filter
.Descriptor
->ConnectionsCount
+ NewConnectionsCount
;
1287 /* allocate array */
1288 Connections
= AllocateItem(NonPagedPool
, Count
* sizeof(KSTOPOLOGY_CONNECTION
));
1290 return STATUS_INSUFFICIENT_RESOURCES
;
1292 /* FIXME verify connections */
1294 if (This
->Filter
.Descriptor
->ConnectionsCount
)
1296 /* copy old connections */
1297 RtlMoveMemory(Connections
, This
->Filter
.Descriptor
->Connections
, sizeof(KSTOPOLOGY_CONNECTION
) * This
->Filter
.Descriptor
->ConnectionsCount
);
1300 /* add new connections */
1301 RtlMoveMemory((PVOID
)(Connections
+ This
->Filter
.Descriptor
->ConnectionsCount
), NewTopologyConnections
, NewConnectionsCount
);
1303 /* add the new connections */
1304 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->ConnectionsCount
, &Count
, sizeof(ULONG
)); /* brain-dead gcc hack */
1306 /* free old connections array */
1307 if (This
->Filter
.Descriptor
->ConnectionsCount
)
1309 FreeItem((PVOID
)This
->Filter
.Descriptor
->Connections
);
1312 /* brain-dead gcc hack */
1313 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->Connections
, Connections
, sizeof(KSTOPOLOGY_CONNECTION
*));
1315 return STATUS_SUCCESS
;
1324 KsFilterAttemptProcessing(
1325 IN PKSFILTER Filter
,
1326 IN BOOLEAN Asynchronous
)
1337 KsFilterCreateNode (
1338 IN PKSFILTER Filter
,
1339 IN
const KSNODE_DESCRIPTOR
*const NodeDescriptor
,
1343 return STATUS_NOT_IMPLEMENTED
;
1352 KsFilterCreatePinFactory (
1353 IN PKSFILTER Filter
,
1354 IN
const KSPIN_DESCRIPTOR_EX
*const InPinDescriptor
,
1358 ULONG
*PinInstanceCount
;
1359 KSPIN_DESCRIPTOR_EX
* PinDescriptorsEx
;
1360 KSPIN_DESCRIPTOR
* PinDescriptors
;
1362 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1364 /* calculate existing count */
1365 Count
= This
->PinDescriptorCount
+ 1;
1367 /* allocate pin descriptors array */
1368 PinDescriptorsEx
= AllocateItem(NonPagedPool
, max(This
->Filter
.Descriptor
->PinDescriptorSize
, sizeof(KSPIN_DESCRIPTOR_EX
)) * Count
);
1369 if (!PinDescriptorsEx
)
1370 return STATUS_INSUFFICIENT_RESOURCES
;
1372 /* allocate pin instance count array */
1373 PinInstanceCount
= AllocateItem(NonPagedPool
, sizeof(ULONG
) * Count
);
1374 if (!PinInstanceCount
)
1376 /* not enough memory */
1377 FreeItem(PinDescriptorsEx
);
1378 return STATUS_INSUFFICIENT_RESOURCES
;
1381 /* allocate pin descriptor array for pin property handling */
1382 PinDescriptors
= AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR
) * Count
);
1383 if (!PinDescriptors
)
1385 /* not enough memory */
1386 FreeItem(PinDescriptorsEx
);
1387 FreeItem(PinInstanceCount
);
1388 return STATUS_INSUFFICIENT_RESOURCES
;
1391 /* allocate first pin array */
1392 FirstPin
= AllocateItem(NonPagedPool
, sizeof(PKSPIN
) * Count
);
1395 /* not enough memory */
1396 FreeItem(PinDescriptorsEx
);
1397 FreeItem(PinInstanceCount
);
1398 FreeItem(PinDescriptors
);
1399 return STATUS_INSUFFICIENT_RESOURCES
;
1402 /* now copy all fields */
1405 /* copy old descriptors */
1406 RtlMoveMemory(PinDescriptorsEx
, This
->Filter
.Descriptor
->PinDescriptors
, max(This
->Filter
.Descriptor
->PinDescriptorSize
, sizeof(KSPIN_DESCRIPTOR_EX
)) * This
->PinDescriptorCount
);
1407 RtlMoveMemory(PinInstanceCount
, This
->PinInstanceCount
, This
->PinDescriptorCount
* sizeof(ULONG
));
1408 RtlMoveMemory(PinDescriptors
, This
->PinDescriptors
, sizeof(KSPIN_DESCRIPTOR
) * This
->PinDescriptorCount
);
1409 RtlMoveMemory(FirstPin
, This
->FirstPin
, sizeof(PKSPIN
) * This
->PinDescriptorCount
);
1411 /* now free old descriptors */
1412 FreeItem(This
->PinInstanceCount
);
1413 FreeItem((PVOID
)This
->Filter
.Descriptor
->PinDescriptors
);
1414 FreeItem(This
->PinDescriptors
);
1415 FreeItem(This
->FirstPin
);
1418 /* add new pin factory */
1419 RtlMoveMemory((PVOID
)((ULONG_PTR
)PinDescriptorsEx
+ max(This
->Filter
.Descriptor
->PinDescriptorSize
, sizeof(KSPIN_DESCRIPTOR_EX
)) * This
->PinDescriptorCount
), InPinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
1420 RtlMoveMemory((PVOID
)(PinDescriptors
+ This
->PinDescriptorCount
), &InPinDescriptor
->PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
1422 /* replace old descriptor by using a gcc-compliant hack */
1423 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->PinDescriptors
, PinDescriptorsEx
, sizeof(KSPIN_DESCRIPTOR_EX
*));
1424 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->PinDescriptorsCount
, &Count
, sizeof(ULONG
));
1426 This
->PinDescriptors
= PinDescriptors
;
1427 This
->PinInstanceCount
= PinInstanceCount
;
1428 This
->FirstPin
= FirstPin
;
1430 /* store new pin id */
1431 *PinID
= This
->PinDescriptorCount
;
1433 /* increment pin descriptor count */
1434 This
->PinDescriptorCount
++;
1436 return STATUS_SUCCESS
;
1447 IN PKSFILTER Filter
)
1459 KsFilterGetChildPinCount(
1460 IN PKSFILTER Filter
,
1463 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1465 if (PinId
>= This
->PinDescriptorCount
)
1467 /* index is out of bounds */
1470 /* return pin instance count */
1471 return This
->PinInstanceCount
[PinId
];
1480 KsFilterGetFirstChildPin(
1481 IN PKSFILTER Filter
,
1484 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1486 if (PinId
>= This
->PinDescriptorCount
)
1488 /* index is out of bounds */
1492 /* return first pin index */
1493 return This
->FirstPin
[PinId
];
1502 KsFilterRegisterPowerCallbacks(
1503 IN PKSFILTER Filter
,
1504 IN PFNKSFILTERPOWER Sleep OPTIONAL
,
1505 IN PFNKSFILTERPOWER Wake OPTIONAL
)
1507 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1509 This
->Sleep
= Sleep
;
1522 PIO_STACK_LOCATION IoStack
;
1523 PKSIOBJECT_HEADER ObjectHeader
;
1525 /* get current irp stack location */
1526 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1529 ASSERT(IoStack
->FileObject
);
1531 /* get object header */
1532 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1534 if (ObjectHeader
->Type
== KsObjectTypeFilter
)
1536 /* irp is targeted at the filter */
1537 return (PKSFILTER
)ObjectHeader
->ObjectType
;
1539 else if (ObjectHeader
->Type
== KsObjectTypePin
)
1541 /* irp is for a pin */
1542 return KsPinGetParentFilter((PKSPIN
)ObjectHeader
->ObjectType
);
1546 /* irp is unappropiate to retrieve a filter */