2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/filter.c
5 * PURPOSE: KS IKsFilter interface functions
6 * PROGRAMMER: Johannes Anderwald
14 KSBASIC_HEADER Header
;
17 IKsFilterVtbl
*lpVtbl
;
18 IKsControlVtbl
*lpVtblKsControl
;
19 IKsFilterFactory
* FilterFactory
;
22 PKSIOBJECT_HEADER ObjectHeader
;
24 KSPIN_DESCRIPTOR_EX
* PinDescriptorsEx
;
25 KSPIN_DESCRIPTOR
* PinDescriptors
;
26 ULONG PinDescriptorCount
;
27 PKSFILTERFACTORY Factory
;
28 PFILE_OBJECT FileObject
;
29 KMUTEX ProcessingMutex
;
32 PFNKSFILTERPOWER Sleep
;
33 PFNKSFILTERPOWER Wake
;
35 ULONG
*PinInstanceCount
;
37 KSPROCESSPIN_INDEXENTRY ProcessPinIndex
;
41 const GUID IID_IKsControl
= {0x28F54685L
, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
42 const GUID IID_IKsFilter
= {0x3ef6ee44L
, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}};
43 const GUID KSPROPSETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
44 const GUID KSPROPSETID_Pin
= {0x8C134960L
, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
47 DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet
, KspTopologyPropertyHandler
);
48 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet
, KspPinPropertyHandler
, KspPinPropertyHandler
, KspPinPropertyHandler
);
50 KSPROPERTY_SET FilterPropertySet
[] =
53 &KSPROPSETID_Topology
,
54 sizeof(IKsFilterTopologySet
) / sizeof(KSPROPERTY_ITEM
),
55 (const KSPROPERTY_ITEM
*)&IKsFilterTopologySet
,
61 sizeof(IKsFilterPinSet
) / sizeof(KSPROPERTY_ITEM
),
62 (const KSPROPERTY_ITEM
*)&IKsFilterPinSet
,
70 IKsControl_fnQueryInterface(
75 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
77 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
79 *Output
= &This
->lpVtbl
;
80 _InterlockedIncrement(&This
->ref
);
81 return STATUS_SUCCESS
;
83 return STATUS_UNSUCCESSFUL
;
91 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
93 return InterlockedIncrement(&This
->ref
);
101 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
103 InterlockedDecrement(&This
->ref
);
105 /* Return new reference count */
111 IKsControl_fnKsProperty(
113 IN PKSPROPERTY Property
,
114 IN ULONG PropertyLength
,
115 IN OUT PVOID PropertyData
,
117 OUT ULONG
* BytesReturned
)
119 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
121 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, Property
, PropertyLength
, PropertyData
, DataLength
, BytesReturned
);
127 IKsControl_fnKsMethod(
130 IN ULONG MethodLength
,
131 IN OUT PVOID MethodData
,
133 OUT ULONG
* BytesReturned
)
135 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
137 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_METHOD
, Method
, MethodLength
, MethodData
, DataLength
, BytesReturned
);
143 IKsControl_fnKsEvent(
145 IN PKSEVENT Event OPTIONAL
,
146 IN ULONG EventLength
,
147 IN OUT PVOID EventData
,
149 OUT ULONG
* BytesReturned
)
151 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtblKsControl
);
155 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_ENABLE_EVENT
, Event
, EventLength
, EventData
, DataLength
, BytesReturned
);
159 return KsSynchronousIoControlDevice(This
->FileObject
, KernelMode
, IOCTL_KS_DISABLE_EVENT
, EventData
, DataLength
, NULL
, 0, BytesReturned
);
164 static IKsControlVtbl vt_IKsControl
=
166 IKsControl_fnQueryInterface
,
168 IKsControl_fnRelease
,
169 IKsControl_fnKsProperty
,
170 IKsControl_fnKsMethod
,
177 IKsFilter_fnQueryInterface(
182 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
184 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
) ||
185 IsEqualGUIDAligned(refiid
, &IID_IKsFilter
))
187 *Output
= &This
->lpVtbl
;
188 _InterlockedIncrement(&This
->ref
);
189 return STATUS_SUCCESS
;
191 else if (IsEqualGUIDAligned(refiid
, &IID_IKsControl
))
193 *Output
= &This
->lpVtblKsControl
;
194 _InterlockedIncrement(&This
->ref
);
195 return STATUS_SUCCESS
;
198 return STATUS_UNSUCCESSFUL
;
206 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
208 return InterlockedIncrement(&This
->ref
);
216 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
218 InterlockedDecrement(&This
->ref
);
225 /* Return new reference count */
232 IKsFilter_fnGetStruct(
235 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
237 return &This
->Filter
;
242 IKsFilter_fnDoAllNecessaryPinsExist(
251 IKsFilter_fnCreateNode(
255 IN PLIST_ENTRY ListEntry
)
258 return STATUS_NOT_IMPLEMENTED
;
263 IKsFilter_fnBindProcessPinsToPipeSection(
265 IN
struct KSPROCESSPIPESECTION
*Section
,
269 OUT PKSGATE
*OutGate
)
272 return STATUS_NOT_IMPLEMENTED
;
277 IKsFilter_fnUnbindProcessPinsFromPipeSection(
279 IN
struct KSPROCESSPIPESECTION
*Section
)
282 return STATUS_NOT_IMPLEMENTED
;
287 IKsFilter_fnAddProcessPin(
289 IN PKSPROCESSPIN ProcessPin
)
292 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
294 /* first acquire processing mutex */
295 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
297 /* edit process pin descriptor */
298 Status
= _KsEdit(This
->Filter
.Bag
,
299 (PVOID
*)&This
->ProcessPinIndex
.Pins
,
300 (This
->ProcessPinIndex
.Count
+ 1) * sizeof(PKSPROCESSPIN
),
301 (This
->ProcessPinIndex
.Count
) * sizeof(PKSPROCESSPIN
),
304 if (NT_SUCCESS(Status
))
306 /* add new process pin */
307 This
->ProcessPinIndex
.Pins
[This
->ProcessPinIndex
.Count
] = ProcessPin
;
308 This
->ProcessPinIndex
.Count
++;
311 /* release process mutex */
312 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
319 IKsFilter_fnRemoveProcessPin(
321 IN PKSPROCESSPIN ProcessPin
)
324 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(iface
, IKsFilterImpl
, lpVtbl
);
326 /* first acquire processing mutex */
327 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
329 /* iterate through process pin index array and search for the process pin to be removed */
330 for(Index
= 0; Index
< This
->ProcessPinIndex
.Count
; Index
++)
332 if (This
->ProcessPinIndex
.Pins
[Index
] == ProcessPin
)
334 /* found process pin */
335 if (Index
+ 1 < This
->ProcessPinIndex
.Count
)
338 RtlMoveMemory(&This
->ProcessPinIndex
.Pins
[Index
], &This
->ProcessPinIndex
.Pins
[Index
+1], This
->ProcessPinIndex
.Count
- Index
- 1);
340 /* decrement process pin count */
341 This
->ProcessPinIndex
.Count
--;
345 /* release process mutex */
346 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
349 return STATUS_SUCCESS
;
354 IKsFilter_fnReprepareProcessPipeSection(
356 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
365 IKsFilter_fnDeliverResetState(
367 IN
struct KSPROCESSPIPESECTION
*PipeSection
,
368 IN KSRESET ResetState
)
375 IKsFilter_fnIsFrameHolding(
384 IKsFilter_fnRegisterForCopyCallbacks(
392 PKSPROCESSPIN_INDEXENTRY
394 IKsFilter_fnGetProcessDispatch(
401 static IKsFilterVtbl vt_IKsFilter
=
403 IKsFilter_fnQueryInterface
,
406 IKsFilter_fnGetStruct
,
407 IKsFilter_fnDoAllNecessaryPinsExist
,
408 IKsFilter_fnCreateNode
,
409 IKsFilter_fnBindProcessPinsToPipeSection
,
410 IKsFilter_fnUnbindProcessPinsFromPipeSection
,
411 IKsFilter_fnAddProcessPin
,
412 IKsFilter_fnRemoveProcessPin
,
413 IKsFilter_fnReprepareProcessPipeSection
,
414 IKsFilter_fnDeliverResetState
,
415 IKsFilter_fnIsFrameHolding
,
416 IKsFilter_fnRegisterForCopyCallbacks
,
417 IKsFilter_fnGetProcessDispatch
421 IKsFilter_GetFilterFromIrp(
423 OUT IKsFilter
**Filter
)
425 PIO_STACK_LOCATION IoStack
;
426 PKSIOBJECT_HEADER ObjectHeader
;
429 /* get current irp stack */
430 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
433 ASSERT(IoStack
->FileObject
!= NULL
);
435 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
437 /* sanity is important */
438 ASSERT(ObjectHeader
!= NULL
);
439 ASSERT(ObjectHeader
->Type
== KsObjectTypeFilter
);
440 ASSERT(ObjectHeader
->Unknown
!= NULL
);
442 /* get our private interface */
443 Status
= ObjectHeader
->Unknown
->lpVtbl
->QueryInterface(ObjectHeader
->Unknown
, &IID_IKsFilter
, (PVOID
*)Filter
);
445 if (!NT_SUCCESS(Status
))
447 /* something is wrong here */
448 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader
->Unknown
);
449 Irp
->IoStatus
.Status
= Status
;
451 /* complete and forget irp */
452 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
461 IKsFilter_DispatchClose(
462 IN PDEVICE_OBJECT DeviceObject
,
466 IKsFilterImpl
* This
;
469 /* obtain filter from object header */
470 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
471 if (!NT_SUCCESS(Status
))
474 /* get our real implementation */
475 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
477 /* does the driver support notifications */
478 if (This
->Factory
->FilterDescriptor
&& This
->Factory
->FilterDescriptor
->Dispatch
&& This
->Factory
->FilterDescriptor
->Dispatch
->Close
)
480 /* call driver's filter close function */
481 Status
= This
->Factory
->FilterDescriptor
->Dispatch
->Close(&This
->Filter
, Irp
);
484 if (NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
486 /* save the result */
487 Irp
->IoStatus
.Status
= Status
;
489 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
491 /* FIXME remove our instance from the filter factory */
494 /* free object header */
495 KsFreeObjectHeader(This
->ObjectHeader
);
499 /* complete and forget */
500 Irp
->IoStatus
.Status
= Status
;
502 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
510 KspHandlePropertyInstances(
511 IN PIO_STATUS_BLOCK IoStatus
,
512 IN PKSIDENTIFIER Request
,
514 IN IKsFilterImpl
* This
,
517 KSPIN_CINSTANCES
* Instances
;
518 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
520 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
522 /* no filter / pin descriptor */
523 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
524 return STATUS_NOT_IMPLEMENTED
;
527 /* ignore custom structs for now */
528 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
529 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
531 Instances
= (KSPIN_CINSTANCES
*)Data
;
532 /* max instance count */
533 Instances
->PossibleCount
= This
->PinDescriptorsEx
[Pin
->PinId
].InstancesPossible
;
534 /* current instance count */
535 Instances
->CurrentCount
= This
->PinInstanceCount
[Pin
->PinId
];
537 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
538 IoStatus
->Status
= STATUS_SUCCESS
;
539 return STATUS_SUCCESS
;
543 KspHandleNecessaryPropertyInstances(
544 IN PIO_STATUS_BLOCK IoStatus
,
545 IN PKSIDENTIFIER Request
,
547 IN IKsFilterImpl
* This
)
550 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
552 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
554 /* no filter / pin descriptor */
555 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
556 return STATUS_NOT_IMPLEMENTED
;
559 /* ignore custom structs for now */
560 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
561 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
563 Result
= (PULONG
)Data
;
564 *Result
= This
->PinDescriptorsEx
[Pin
->PinId
].InstancesNecessary
;
566 IoStatus
->Information
= sizeof(ULONG
);
567 IoStatus
->Status
= STATUS_SUCCESS
;
568 return STATUS_SUCCESS
;
572 KspHandleDataIntersection(
574 IN PIO_STATUS_BLOCK IoStatus
,
575 IN PKSIDENTIFIER Request
,
578 IN IKsFilterImpl
* This
)
580 PKSMULTIPLE_ITEM MultipleItem
;
581 PKSDATARANGE DataRange
;
582 NTSTATUS Status
= STATUS_NO_MATCH
;
584 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
586 /* Access parameters */
587 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
588 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
590 if (!This
->Factory
->FilterDescriptor
|| !This
->PinDescriptorCount
)
592 /* no filter / pin descriptor */
593 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
594 return STATUS_NOT_IMPLEMENTED
;
597 /* ignore custom structs for now */
598 ASSERT(This
->Factory
->FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
599 ASSERT(This
->PinDescriptorCount
> Pin
->PinId
);
601 if (This
->PinDescriptorsEx
[Pin
->PinId
].IntersectHandler
== NULL
||
602 This
->PinDescriptors
[Pin
->PinId
].DataRanges
== NULL
||
603 This
->PinDescriptors
[Pin
->PinId
].DataRangesCount
== 0)
605 /* no driver supported intersect handler / no provided data ranges */
606 IoStatus
->Status
= STATUS_NOT_IMPLEMENTED
;
607 return STATUS_NOT_IMPLEMENTED
;
610 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
612 /* Call miniport's properitary handler */
613 Status
= This
->PinDescriptorsEx
[Pin
->PinId
].IntersectHandler(NULL
, /* context */
617 (PKSDATAFORMAT
)This
->Factory
->FilterDescriptor
->PinDescriptors
[Pin
->PinId
].PinDescriptor
.DataRanges
,
622 if (Status
== STATUS_SUCCESS
)
624 IoStatus
->Information
= Length
;
627 DataRange
= UlongToPtr(PtrToUlong(DataRange
) + DataRange
->FormatSize
);
630 IoStatus
->Status
= Status
;
636 KspPinPropertyHandler(
638 IN PKSIDENTIFIER Request
,
641 PIO_STACK_LOCATION IoStack
;
642 IKsFilterImpl
* This
;
643 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
645 /* get filter implementation */
646 This
= (IKsFilterImpl
*)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
648 /* get current stack location */
649 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
653 case KSPROPERTY_PIN_CTYPES
:
654 case KSPROPERTY_PIN_DATAFLOW
:
655 case KSPROPERTY_PIN_DATARANGES
:
656 case KSPROPERTY_PIN_INTERFACES
:
657 case KSPROPERTY_PIN_MEDIUMS
:
658 case KSPROPERTY_PIN_COMMUNICATION
:
659 case KSPROPERTY_PIN_CATEGORY
:
660 case KSPROPERTY_PIN_NAME
:
661 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
662 Status
= KsPinPropertyHandler(Irp
, Request
, Data
, This
->PinDescriptorCount
, This
->PinDescriptors
);
664 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
665 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, TRUE
);
667 case KSPROPERTY_PIN_CINSTANCES
:
668 Status
= KspHandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
, FALSE
);
670 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
671 Status
= KspHandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, This
);
674 case KSPROPERTY_PIN_DATAINTERSECTION
:
675 Status
= KspHandleDataIntersection(Irp
, &Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, This
);
677 case KSPROPERTY_PIN_PHYSICALCONNECTION
:
678 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
680 Status
= STATUS_NOT_IMPLEMENTED
;
684 Status
= STATUS_UNSUCCESSFUL
;
686 DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This
->PinDescriptorCount
, Request
->Id
, Status
);
694 IKsFilter_DispatchDeviceIoControl(
695 IN PDEVICE_OBJECT DeviceObject
,
698 PIO_STACK_LOCATION IoStack
;
700 IKsFilterImpl
* This
;
702 PKSFILTER FilterInstance
;
704 /* obtain filter from object header */
705 Status
= IKsFilter_GetFilterFromIrp(Irp
, &Filter
);
706 if (!NT_SUCCESS(Status
))
709 /* get our real implementation */
710 This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, lpVtbl
);
712 /* current irp stack */
713 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
715 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
719 /* release filter interface */
720 Filter
->lpVtbl
->Release(Filter
);
722 /* complete and forget irp */
723 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
724 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
725 return STATUS_NOT_IMPLEMENTED
;
728 /* call property handler supported by ks */
729 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (KSPROPERTY_ITEM
*)This
;
730 Status
= KspPropertyHandler(Irp
, 2, FilterPropertySet
, NULL
, sizeof(KSPROPERTY_ITEM
));
732 if (Status
== STATUS_NOT_FOUND
)
734 /* get filter instance */
735 FilterInstance
= Filter
->lpVtbl
->GetStruct(Filter
);
737 /* check if the driver supports property sets */
738 if (FilterInstance
->Descriptor
->AutomationTable
&& FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
)
740 /* call driver's filter property handler */
741 Status
= KspPropertyHandler(Irp
,
742 FilterInstance
->Descriptor
->AutomationTable
->PropertySetsCount
,
743 FilterInstance
->Descriptor
->AutomationTable
->PropertySets
,
745 FilterInstance
->Descriptor
->AutomationTable
->PropertyItemSize
);
749 Irp
->IoStatus
.Status
= Status
;
750 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
756 static KSDISPATCH_TABLE DispatchTable
=
758 IKsFilter_DispatchDeviceIoControl
,
759 KsDispatchInvalidDeviceRequest
,
760 KsDispatchInvalidDeviceRequest
,
761 KsDispatchInvalidDeviceRequest
,
762 IKsFilter_DispatchClose
,
763 KsDispatchQuerySecurity
,
764 KsDispatchSetSecurity
,
765 KsDispatchFastIoDeviceControlFailure
,
766 KsDispatchFastReadFailure
,
767 KsDispatchFastReadFailure
,
772 IKsFilter_CreateDescriptors(
773 IKsFilterImpl
* This
,
774 KSFILTER_DESCRIPTOR
* FilterDescriptor
)
779 /* initialize pin descriptors */
780 This
->FirstPin
= NULL
;
781 This
->PinInstanceCount
= NULL
;
782 This
->PinDescriptors
= NULL
;
783 This
->PinDescriptorsEx
= NULL
;
784 This
->PinDescriptorCount
= 0;
786 /* initialize topology descriptor */
787 This
->Topology
.CategoriesCount
= FilterDescriptor
->CategoriesCount
;
788 This
->Topology
.Categories
= FilterDescriptor
->Categories
;
789 This
->Topology
.TopologyNodesCount
= FilterDescriptor
->NodeDescriptorsCount
;
790 This
->Topology
.TopologyConnectionsCount
= FilterDescriptor
->ConnectionsCount
;
791 This
->Topology
.TopologyConnections
= FilterDescriptor
->Connections
;
793 /* are there any templates */
794 if (FilterDescriptor
->PinDescriptorsCount
)
797 ASSERT(FilterDescriptor
->PinDescriptors
);
799 /* FIXME handle variable sized pin descriptors */
800 ASSERT(FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
802 /* store pin descriptors ex */
803 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptorsEx
, sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
,
804 sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
, 0);
806 if (!NT_SUCCESS(Status
))
808 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
812 /* store pin descriptors */
813 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptors
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescriptor
->PinDescriptorsCount
,
814 sizeof(KSPIN_DESCRIPTOR
) * FilterDescriptor
->PinDescriptorsCount
, 0);
816 if (!NT_SUCCESS(Status
))
818 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
822 /* store pin instance count ex */
823 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
,
824 sizeof(ULONG
) * FilterDescriptor
->PinDescriptorsCount
, 0);
826 if (!NT_SUCCESS(Status
))
828 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
832 /* store instantiated pin arrays */
833 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->FirstPin
, sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
,
834 sizeof(PKSPIN
) * FilterDescriptor
->PinDescriptorsCount
, 0);
836 if (!NT_SUCCESS(Status
))
838 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status
);
844 /* add new pin factory */
845 RtlMoveMemory(This
->PinDescriptorsEx
, FilterDescriptor
->PinDescriptors
, sizeof(KSPIN_DESCRIPTOR_EX
) * FilterDescriptor
->PinDescriptorsCount
);
847 for(Index
= 0; Index
< FilterDescriptor
->PinDescriptorsCount
; Index
++)
849 RtlMoveMemory(&This
->PinDescriptors
[Index
], &FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
852 /* store new pin descriptor count */
853 This
->PinDescriptorCount
= FilterDescriptor
->PinDescriptorsCount
;
856 if (FilterDescriptor
->NodeDescriptorsCount
)
859 ASSERT(FilterDescriptor
->NodeDescriptors
);
861 /* FIXME handle variable sized node descriptors */
862 ASSERT(FilterDescriptor
->NodeDescriptorSize
== sizeof(KSNODE_DESCRIPTOR
));
864 This
->Topology
.TopologyNodes
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
865 /* allocate topology node types array */
866 if (!This
->Topology
.TopologyNodes
)
868 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
869 return STATUS_INSUFFICIENT_RESOURCES
;
872 This
->Topology
.TopologyNodesNames
= AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescriptor
->NodeDescriptorsCount
);
873 /* allocate topology names array */
874 if (!This
->Topology
.TopologyNodesNames
)
876 FreeItem((PVOID
)This
->Topology
.TopologyNodes
);
877 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
878 return STATUS_INSUFFICIENT_RESOURCES
;
881 DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor
->NodeDescriptorsCount
);
882 for(Index
= 0; Index
< FilterDescriptor
->NodeDescriptorsCount
; Index
++)
884 DPRINT("Index %lu Type %p Name %p\n", Index
, FilterDescriptor
->NodeDescriptors
[Index
].Type
, FilterDescriptor
->NodeDescriptors
[Index
].Name
);
886 /* copy topology type */
887 if (FilterDescriptor
->NodeDescriptors
[Index
].Type
)
888 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodes
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Type
, sizeof(GUID
));
890 /* copy topology name */
891 if (FilterDescriptor
->NodeDescriptors
[Index
].Name
)
892 RtlMoveMemory((PVOID
)&This
->Topology
.TopologyNodesNames
[Index
], FilterDescriptor
->NodeDescriptors
[Index
].Name
, sizeof(GUID
));
896 return STATUS_SUCCESS
;
900 IKsFilter_CopyFilterDescriptor(
901 IKsFilterImpl
* This
,
902 const KSFILTER_DESCRIPTOR
* FilterDescriptor
)
906 This
->Filter
.Descriptor
= AllocateItem(NonPagedPool
, sizeof(KSFILTER_DESCRIPTOR
));
907 if (!This
->Filter
.Descriptor
)
908 return STATUS_INSUFFICIENT_RESOURCES
;
910 Status
= KsAddItemToObjectBag(This
->Filter
.Bag
, (PVOID
)This
->Filter
.Descriptor
, NULL
);
911 if (!NT_SUCCESS(Status
))
913 FreeItem((PVOID
)This
->Filter
.Descriptor
);
914 This
->Filter
.Descriptor
= NULL
;
915 return STATUS_INSUFFICIENT_RESOURCES
;
918 /* copy filter descriptor fields */
919 RtlMoveMemory((PVOID
)This
->Filter
.Descriptor
, FilterDescriptor
, sizeof(KSFILTER_DESCRIPTOR
));
930 PKSPIN NextPin
, CurPin
;
931 PKSBASIC_HEADER BasicHeader
;
932 IKsFilterImpl
* This
= (IKsFilterImpl
*)Filter
;
935 ASSERT(Pin
->Id
< This
->PinDescriptorCount
);
937 if (This
->FirstPin
[Pin
->Id
] == NULL
)
939 /* welcome first pin */
940 This
->FirstPin
[Pin
->Id
] = Pin
;
941 return STATUS_SUCCESS
;
945 CurPin
= This
->FirstPin
[Pin
->Id
];
949 /* get next instantiated pin */
950 NextPin
= KsPinGetNextSiblingPin(CurPin
);
956 }while(NextPin
!= NULL
);
958 /* get basic header */
959 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)CurPin
- sizeof(KSBASIC_HEADER
));
962 BasicHeader
->Next
.Pin
= Pin
;
964 return STATUS_SUCCESS
;
970 IKsFilter_DispatchCreatePin(
971 IN PDEVICE_OBJECT DeviceObject
,
974 IKsFilterImpl
* This
;
975 PKSOBJECT_CREATE_ITEM CreateItem
;
976 PKSPIN_CONNECT Connect
;
979 DPRINT("IKsFilter_DispatchCreatePin\n");
981 /* get the create item */
982 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
984 /* get the filter object */
985 This
= (IKsFilterImpl
*)CreateItem
->Context
;
988 ASSERT(This
->Header
.Type
== KsObjectTypeFilter
);
990 /* acquire control mutex */
991 KeWaitForSingleObject(&This
->Header
.ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
993 /* now validate the connect request */
994 Status
= KsValidateConnectRequest(Irp
, This
->PinDescriptorCount
, This
->PinDescriptors
, &Connect
);
996 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status
);
998 if (NT_SUCCESS(Status
))
1001 ASSERT(Connect
->PinId
< This
->PinDescriptorCount
);
1003 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect
->PinId
,
1004 This
->PinInstanceCount
[Connect
->PinId
],
1005 This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
);
1007 if (This
->PinInstanceCount
[Connect
->PinId
] < This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
)
1009 /* create the pin */
1010 Status
= KspCreatePin(DeviceObject
, Irp
, This
->Header
.KsDevice
, This
->FilterFactory
, (IKsFilter
*)&This
->lpVtbl
, Connect
, &This
->PinDescriptorsEx
[Connect
->PinId
]);
1012 DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status
);
1014 if (NT_SUCCESS(Status
))
1016 /* successfully created pin, increment pin instance count */
1017 This
->PinInstanceCount
[Connect
->PinId
]++;
1022 /* maximum instance count reached, bye-bye */
1023 Status
= STATUS_UNSUCCESSFUL
;
1024 DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This
->PinDescriptorsEx
[Connect
->PinId
].InstancesPossible
, This
->PinInstanceCount
[Connect
->PinId
]);
1028 /* release control mutex */
1029 KeReleaseMutex(&This
->Header
.ControlMutex
, FALSE
);
1031 if (Status
!= STATUS_PENDING
)
1033 /* complete request */
1034 Irp
->IoStatus
.Status
= Status
;
1035 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1039 DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status
);
1045 IKsFilter_DispatchCreateNode(
1046 IN PDEVICE_OBJECT DeviceObject
,
1050 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1051 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1052 return STATUS_UNSUCCESSFUL
;
1057 IKsFilter_AttachFilterToFilterFactory(
1058 IKsFilterImpl
* This
,
1059 PKSFILTERFACTORY FilterFactory
)
1061 PKSBASIC_HEADER BasicHeader
;
1065 /* get filter factory basic header */
1066 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
1069 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
1071 if (BasicHeader
->FirstChild
.FilterFactory
== NULL
)
1073 /* welcome first instantiated filter */
1074 BasicHeader
->FirstChild
.Filter
= &This
->Filter
;
1078 /* set to first entry */
1079 Filter
= BasicHeader
->FirstChild
.Filter
;
1083 /* get basic header */
1084 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Filter
- sizeof(KSBASIC_HEADER
));
1086 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
);
1088 if (BasicHeader
->Next
.Filter
)
1090 /* iterate to next filter factory */
1091 Filter
= BasicHeader
->Next
.Filter
;
1095 /* found last entry */
1098 }while(FilterFactory
);
1100 /* attach filter factory */
1101 BasicHeader
->Next
.Filter
= &This
->Filter
;
1107 IN PDEVICE_OBJECT DeviceObject
,
1109 IN IKsFilterFactory
*iface
)
1111 IKsFilterImpl
* This
;
1112 IKsDevice
*KsDevice
;
1113 PKSFILTERFACTORY Factory
;
1114 PIO_STACK_LOCATION IoStack
;
1115 PDEVICE_EXTENSION DeviceExtension
;
1117 PKSOBJECT_CREATE_ITEM CreateItem
;
1119 /* get device extension */
1120 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1122 /* get the filter factory */
1123 Factory
= iface
->lpVtbl
->GetStruct(iface
);
1125 if (!Factory
|| !Factory
->FilterDescriptor
|| !Factory
->FilterDescriptor
->Dispatch
|| !Factory
->FilterDescriptor
->Dispatch
->Create
)
1127 /* Sorry it just will not work */
1128 return STATUS_UNSUCCESSFUL
;
1131 /* allocate filter instance */
1132 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterImpl
));
1135 DPRINT("KspCreateFilter OutOfMemory\n");
1136 return STATUS_INSUFFICIENT_RESOURCES
;
1139 /* initialize object bag */
1140 This
->Filter
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
1141 if (!This
->Filter
.Bag
)
1145 DPRINT("KspCreateFilter OutOfMemory\n");
1146 return STATUS_INSUFFICIENT_RESOURCES
;
1148 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
1149 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->Filter
.Bag
, NULL
);
1151 /* copy filter descriptor */
1152 Status
= IKsFilter_CopyFilterDescriptor(This
, Factory
->FilterDescriptor
);
1153 if (!NT_SUCCESS(Status
))
1155 /* not enough memory */
1156 FreeItem(This
->Filter
.Bag
);
1158 DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status
);
1159 return STATUS_INSUFFICIENT_RESOURCES
;
1162 /* get current irp stack */
1163 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1165 /* allocate create items */
1166 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
) * 2);
1170 FreeItem(This
->Filter
.Bag
);
1172 DPRINT("KspCreateFilter OutOfMemory\n");
1173 return STATUS_INSUFFICIENT_RESOURCES
;
1176 /* initialize pin create item */
1177 CreateItem
[0].Create
= IKsFilter_DispatchCreatePin
;
1178 CreateItem
[0].Context
= (PVOID
)This
;
1179 CreateItem
[0].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1180 RtlInitUnicodeString(&CreateItem
[0].ObjectClass
, KSSTRING_Pin
);
1181 /* initialize node create item */
1182 CreateItem
[1].Create
= IKsFilter_DispatchCreateNode
;
1183 CreateItem
[1].Context
= (PVOID
)This
;
1184 CreateItem
[1].Flags
= KSCREATE_ITEM_FREEONSTOP
;
1185 RtlInitUnicodeString(&CreateItem
[1].ObjectClass
, KSSTRING_TopologyNode
);
1188 /* initialize filter instance */
1190 This
->lpVtbl
= &vt_IKsFilter
;
1191 This
->lpVtblKsControl
= &vt_IKsControl
;
1193 This
->Filter
.Descriptor
= Factory
->FilterDescriptor
;
1194 This
->Factory
= Factory
;
1195 This
->FilterFactory
= iface
;
1196 This
->FileObject
= IoStack
->FileObject
;
1197 KeInitializeMutex(&This
->ProcessingMutex
, 0);
1198 /* initialize basic header */
1199 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
1200 This
->Header
.Parent
.KsFilterFactory
= iface
->lpVtbl
->GetStruct(iface
);
1201 This
->Header
.Type
= KsObjectTypeFilter
;
1202 KeInitializeMutex(&This
->Header
.ControlMutex
, 0);
1203 InitializeListHead(&This
->Header
.EventList
);
1204 KeInitializeSpinLock(&This
->Header
.EventListLock
);
1206 /* allocate the stream descriptors */
1207 Status
= IKsFilter_CreateDescriptors(This
, (PKSFILTER_DESCRIPTOR
)Factory
->FilterDescriptor
);
1208 if (!NT_SUCCESS(Status
))
1210 /* what can go wrong, goes wrong */
1212 FreeItem(CreateItem
);
1213 DPRINT("IKsFilter_CreateDescriptors failed with %lx\n", Status
);
1217 /* does the filter have a filter dispatch */
1218 if (Factory
->FilterDescriptor
->Dispatch
)
1220 /* does it have a create routine */
1221 if (Factory
->FilterDescriptor
->Dispatch
->Create
)
1223 /* now let driver initialize the filter instance */
1224 DPRINT("Before instantiating filter Filter %p This %p KSBASIC_HEADER %u\n", &This
->Filter
, This
, sizeof(KSBASIC_HEADER
));
1225 ASSERT(This
->Header
.KsDevice
);
1226 Status
= Factory
->FilterDescriptor
->Dispatch
->Create(&This
->Filter
, Irp
);
1228 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
1230 /* driver failed to initialize */
1231 DPRINT1("Driver: Status %x\n", Status
);
1233 /* free filter instance */
1235 FreeItem(CreateItem
);
1241 /* now allocate the object header */
1242 Status
= KsAllocateObjectHeader((PVOID
*)&This
->ObjectHeader
, 2, CreateItem
, Irp
, &DispatchTable
);
1243 if (!NT_SUCCESS(Status
))
1245 /* failed to allocate object header */
1246 DPRINT1("Failed to allocate object header %x\n", Status
);
1251 /* initialize object header extra fields */
1252 This
->ObjectHeader
->Type
= KsObjectTypeFilter
;
1253 This
->ObjectHeader
->Unknown
= (PUNKNOWN
)&This
->lpVtbl
;
1254 This
->ObjectHeader
->ObjectType
= (PVOID
)&This
->Filter
;
1256 /* attach filter to filter factory */
1257 IKsFilter_AttachFilterToFilterFactory(This
, This
->Header
.Parent
.KsFilterFactory
);
1259 /* completed initialization */
1260 DPRINT("KspCreateFilter done %lx\n", Status
);
1270 KsFilterAcquireProcessingMutex(
1271 IN PKSFILTER Filter
)
1273 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1275 KeWaitForSingleObject(&This
->ProcessingMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1284 KsFilterReleaseProcessingMutex(
1285 IN PKSFILTER Filter
)
1287 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1289 KeReleaseMutex(&This
->ProcessingMutex
, FALSE
);
1298 KsFilterAddTopologyConnections (
1299 IN PKSFILTER Filter
,
1300 IN ULONG NewConnectionsCount
,
1301 IN
const KSTOPOLOGY_CONNECTION
*const NewTopologyConnections
)
1304 KSTOPOLOGY_CONNECTION
* Connections
;
1305 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1307 Count
= This
->Filter
.Descriptor
->ConnectionsCount
+ NewConnectionsCount
;
1309 /* allocate array */
1310 Connections
= AllocateItem(NonPagedPool
, Count
* sizeof(KSTOPOLOGY_CONNECTION
));
1312 return STATUS_INSUFFICIENT_RESOURCES
;
1314 /* FIXME verify connections */
1316 if (This
->Filter
.Descriptor
->ConnectionsCount
)
1318 /* copy old connections */
1319 RtlMoveMemory(Connections
, This
->Filter
.Descriptor
->Connections
, sizeof(KSTOPOLOGY_CONNECTION
) * This
->Filter
.Descriptor
->ConnectionsCount
);
1322 /* add new connections */
1323 RtlMoveMemory((PVOID
)(Connections
+ This
->Filter
.Descriptor
->ConnectionsCount
), NewTopologyConnections
, NewConnectionsCount
);
1325 /* add the new connections */
1326 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->ConnectionsCount
, &Count
, sizeof(ULONG
)); /* brain-dead gcc hack */
1328 /* free old connections array */
1329 if (This
->Filter
.Descriptor
->ConnectionsCount
)
1331 FreeItem((PVOID
)This
->Filter
.Descriptor
->Connections
);
1334 /* brain-dead gcc hack */
1335 RtlMoveMemory((PVOID
)&This
->Filter
.Descriptor
->Connections
, Connections
, sizeof(KSTOPOLOGY_CONNECTION
*));
1337 return STATUS_SUCCESS
;
1346 KsFilterAttemptProcessing(
1347 IN PKSFILTER Filter
,
1348 IN BOOLEAN Asynchronous
)
1359 KsFilterCreateNode (
1360 IN PKSFILTER Filter
,
1361 IN
const KSNODE_DESCRIPTOR
*const NodeDescriptor
,
1365 return STATUS_NOT_IMPLEMENTED
;
1374 KsFilterCreatePinFactory (
1375 IN PKSFILTER Filter
,
1376 IN
const KSPIN_DESCRIPTOR_EX
*const InPinDescriptor
,
1381 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1383 DPRINT("KsFilterCreatePinFactory\n");
1385 /* calculate new count */
1386 Count
= This
->PinDescriptorCount
+ 1;
1389 ASSERT(This
->Filter
.Descriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
1391 /* allocate pin descriptors ex array */
1392 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptorsEx
, Count
* sizeof(KSPIN_DESCRIPTOR_EX
), This
->PinDescriptorCount
* sizeof(KSPIN_DESCRIPTOR_EX
), 0);
1393 if (!NT_SUCCESS(Status
))
1396 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1400 /* allocate pin descriptors array */
1401 Status
= _KsEdit(This
->Filter
.Bag
, (PVOID
*)&This
->PinDescriptors
, Count
* sizeof(KSPIN_DESCRIPTOR
), This
->PinDescriptorCount
* sizeof(KSPIN_DESCRIPTOR
), 0);
1402 if (!NT_SUCCESS(Status
))
1405 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1410 /* allocate pin instance count array */
1411 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->PinInstanceCount
, sizeof(ULONG
) * Count
, sizeof(ULONG
) * This
->PinDescriptorCount
, 0);
1412 if (!NT_SUCCESS(Status
))
1415 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1419 /* allocate first pin array */
1420 Status
= _KsEdit(This
->Filter
.Bag
,(PVOID
*)&This
->FirstPin
, sizeof(PKSPIN
) * Count
, sizeof(PKSPIN
) * This
->PinDescriptorCount
, 0);
1421 if (!NT_SUCCESS(Status
))
1424 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status
);
1428 /* add new pin factory */
1429 RtlMoveMemory(&This
->PinDescriptorsEx
[This
->PinDescriptorCount
], InPinDescriptor
, sizeof(KSPIN_DESCRIPTOR_EX
));
1430 RtlMoveMemory(&This
->PinDescriptors
[This
->PinDescriptorCount
], &InPinDescriptor
->PinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
1432 /* store new pin id */
1433 *PinID
= This
->PinDescriptorCount
;
1435 /* increment pin descriptor count */
1436 This
->PinDescriptorCount
++;
1439 DPRINT("KsFilterCreatePinFactory done\n");
1440 return STATUS_SUCCESS
;
1451 IN PKSFILTER Filter
)
1463 KsFilterGetChildPinCount(
1464 IN PKSFILTER Filter
,
1467 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1469 if (PinId
>= This
->PinDescriptorCount
)
1471 /* index is out of bounds */
1474 /* return pin instance count */
1475 return This
->PinInstanceCount
[PinId
];
1484 KsFilterGetFirstChildPin(
1485 IN PKSFILTER Filter
,
1488 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1490 if (PinId
>= This
->PinDescriptorCount
)
1492 /* index is out of bounds */
1496 /* return first pin index */
1497 return This
->FirstPin
[PinId
];
1506 KsFilterRegisterPowerCallbacks(
1507 IN PKSFILTER Filter
,
1508 IN PFNKSFILTERPOWER Sleep OPTIONAL
,
1509 IN PFNKSFILTERPOWER Wake OPTIONAL
)
1511 IKsFilterImpl
* This
= (IKsFilterImpl
*)CONTAINING_RECORD(Filter
, IKsFilterImpl
, Filter
);
1513 This
->Sleep
= Sleep
;
1526 PIO_STACK_LOCATION IoStack
;
1527 PKSIOBJECT_HEADER ObjectHeader
;
1529 /* get current irp stack location */
1530 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1533 ASSERT(IoStack
->FileObject
);
1535 /* get object header */
1536 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1538 if (ObjectHeader
->Type
== KsObjectTypeFilter
)
1540 /* irp is targeted at the filter */
1541 return (PKSFILTER
)ObjectHeader
->ObjectType
;
1543 else if (ObjectHeader
->Type
== KsObjectTypePin
)
1545 /* irp is for a pin */
1546 return KsPinGetParentFilter((PKSPIN
)ObjectHeader
->ObjectType
);
1550 /* irp is unappropiate to retrieve a filter */