ReactOS 0.4.15-dev-7085-g12a5971
filter.c
Go to the documentation of this file.
1/*
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
7 */
8
9#include "precomp.h"
10
11#define NDEBUG
12#include <debug.h>
13
14typedef struct
15{
17 KSFILTER Filter;
18
19 IKsControlVtbl *lpVtblKsControl;
20 IKsFilterFactory * FilterFactory;
21 IKsProcessingObjectVtbl * lpVtblKsProcessingObject;
23
26 PKSFILTERFACTORY Factory;
30
31 PKSWORKER Worker;
33 KSGATE Gate;
34
35 PFNKSFILTERPOWER Sleep;
36 PFNKSFILTERPOWER Wake;
37
39 PKSPIN * FirstPin;
41
43
44const GUID IID_IKsControl = {0x28F54685L, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
45const GUID IID_IKsFilter = {0x3ef6ee44L, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}};
46const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
47const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
48const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
49
50VOID
53 PKSFILTERFACTORY FilterFactory);
54
58
62
63KSPROPERTY_SET FilterPropertySet[] =
64{
65 {
67 sizeof(IKsFilterTopologySet) / sizeof(KSPROPERTY_ITEM),
68 (const KSPROPERTY_ITEM*)&IKsFilterTopologySet,
69 0,
70 NULL
71 },
72 {
74 sizeof(IKsFilterPinSet) / sizeof(KSPROPERTY_ITEM),
75 (const KSPROPERTY_ITEM*)&IKsFilterPinSet,
76 0,
77 NULL
78 },
79 {
81 sizeof(IKsFilterGeneralSet) / sizeof(KSPROPERTY_ITEM),
82 (const KSPROPERTY_ITEM*)&IKsFilterGeneralSet,
83 0,
84 NULL
85 }
86};
87
91 IKsProcessingObject * iface,
92 IN REFIID refiid,
94{
95 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
96
97 if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
98 {
99 *Output = &This->Header.OuterUnknown;
101 return STATUS_SUCCESS;
102 }
103 return STATUS_UNSUCCESSFUL;
104}
105
106ULONG
107NTAPI
109 IKsProcessingObject * iface)
110{
111 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
112
113 return InterlockedIncrement(&This->ref);
114}
115
116ULONG
117NTAPI
119 IKsProcessingObject * iface)
120{
121 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
122
124
125 /* Return new reference count */
126 return This->ref;
127}
128
129VOID
130NTAPI
132 IKsProcessingObject * iface)
133{
135 LARGE_INTEGER TimeOut;
136 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
137
138 DPRINT1("processing object\n");
139 /* first check if running at passive level */
141 {
142 /* acquire processing mutex */
144 }
145 else
146 {
147 /* dispatch level processing */
148 if (KeReadStateMutex(&This->ControlMutex) == 0)
149 {
150 /* some thread was faster */
151 DPRINT1("processing object too slow\n");
152 return;
153 }
154
155 /* acquire processing mutex */
156 TimeOut.QuadPart = 0LL;
157 Status = KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, &TimeOut);
158
159 if (Status == STATUS_TIMEOUT)
160 {
161 /* some thread was faster */
162 DPRINT1("processing object too slow\n");
163 return;
164 }
165 }
166
167 do
168 {
169
170 /* check if the and-gate has been enabled again */
171 if (&This->Gate.Count != 0)
172 {
173 /* gate is open */
174 DPRINT1("processing object gate open\n");
175 break;
176 }
177
178 DPRINT1("IKsProcessingObject_fnProcessingObjectWork not implemented\n");
179 ASSERT(0);
180
181 }while(TRUE);
182
183 /* release process mutex */
184 KeReleaseMutex(&This->ProcessingMutex, FALSE);
185}
186
187PKSGATE
188NTAPI
190 IKsProcessingObject * iface)
191{
192 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
193
194 /* return and gate */
195 return &This->Gate;
196}
197
198VOID
199NTAPI
201 IKsProcessingObject * iface,
203{
204 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
205
206 /* should the action be asynchronous */
207 if (Asynchronous)
208 {
209 /* queue work item */
210 KsQueueWorkItem(This->Worker, &This->WorkItem);
211DPRINT1("queueing\n");
212 /* done */
213 return;
214 }
215
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)) &&
219 {
220 /* queue work item */
221 KsQueueWorkItem(This->Worker, &This->WorkItem);
222DPRINT1("queueing\n");
223 /* done */
224 return;
225 }
226DPRINT1("invoke\n");
227 /* call worker routine directly */
228 iface->lpVtbl->ProcessingObjectWork(iface);
229}
230
231VOID
232NTAPI
234 IKsProcessingObject * iface)
235{
236 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
237
238 /* acquire processing mutex */
240
241 /* check if the filter supports dispatch routines */
242 if (This->Filter.Descriptor->Dispatch)
243 {
244 /* has the filter a reset routine */
245 if (This->Filter.Descriptor->Dispatch->Reset)
246 {
247 /* reset filter */
248 This->Filter.Descriptor->Dispatch->Reset(&This->Filter);
249 }
250 }
251
252 /* release process mutex */
253 KeReleaseMutex(&This->ProcessingMutex, FALSE);
254}
255
256VOID
257NTAPI
259 IKsProcessingObject * iface)
260{
261
262}
263
264static IKsProcessingObjectVtbl vt_IKsProcessingObject =
265{
274};
275
276
277//---------------------------------------------------------------------------------------------------------
279NTAPI
281 IKsControl * iface,
282 IN REFIID refiid,
284{
285 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
286
287 if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
288 {
289 *Output = &This->Header.OuterUnknown;
291 return STATUS_SUCCESS;
292 }
293 return STATUS_UNSUCCESSFUL;
294}
295
296ULONG
297NTAPI
299 IKsControl * iface)
300{
301 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
302
303 return InterlockedIncrement(&This->ref);
304}
305
306ULONG
307NTAPI
309 IKsControl * iface)
310{
311 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
312
314
315 /* Return new reference count */
316 return This->ref;
317}
318
320NTAPI
322 IKsControl * iface,
324 IN ULONG PropertyLength,
328{
329 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
330
332}
333
334
336NTAPI
338 IKsControl * iface,
339 IN PKSMETHOD Method,
340 IN ULONG MethodLength,
341 IN OUT PVOID MethodData,
344{
345 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
346
347 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_METHOD, Method, MethodLength, MethodData, DataLength, BytesReturned);
348}
349
350
352NTAPI
354 IKsControl * iface,
356 IN ULONG EventLength,
357 IN OUT PVOID EventData,
360{
361 IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl);
362
363 if (Event)
364 {
365 return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_ENABLE_EVENT, Event, EventLength, EventData, DataLength, BytesReturned);
366 }
367 else
368 {
370 }
371
372}
373
374static IKsControlVtbl vt_IKsControl =
375{
382};
383
384
386NTAPI
388 IKsFilter * iface,
389 IN REFIID refiid,
391{
394
395 if (IsEqualGUIDAligned(refiid, &IID_IUnknown) ||
397 {
398 *Output = &This->Header.OuterUnknown;
400 return STATUS_SUCCESS;
401 }
402 else if (IsEqualGUIDAligned(refiid, &IID_IKsControl))
403 {
404 *Output = &This->lpVtblKsControl;
406 return STATUS_SUCCESS;
407 }
408
409 if (This->Header.ClientAggregate)
410 {
411 /* using client aggregate */
412 Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output);
413
414 if (NT_SUCCESS(Status))
415 {
416 /* client aggregate supports interface */
417 return Status;
418 }
419 }
420
421 DPRINT("IKsFilter_fnQueryInterface no interface\n");
423}
424
425ULONG
426NTAPI
428 IKsFilter * iface)
429{
431
432 return InterlockedIncrement(&This->ref);
433}
434
435ULONG
436NTAPI
438 IKsFilter * iface)
439{
441
443
444 if (This->ref == 0)
445 {
446 FreeItem(This);
447 return 0;
448 }
449 /* Return new reference count */
450 return This->ref;
451
452}
453
454PKSFILTER
455NTAPI
457 IKsFilter * iface)
458{
460
461 return &This->Filter;
462}
463
464BOOL
465NTAPI
467 IKsFilter * iface)
468{
470 return FALSE;
471}
472
474NTAPI
476 IKsFilter * iface,
477 IN PIRP Irp,
478 IN IKsPin * Pin,
479 IN PLIST_ENTRY ListEntry)
480{
483}
484
486NTAPI
488 IKsFilter * iface,
489 IN struct KSPROCESSPIPESECTION *Section,
491 IN PKSPIN KsPin,
492 OUT IKsPin **Pin,
493 OUT PKSGATE *OutGate)
494{
497}
498
500NTAPI
502 IKsFilter * iface,
503 IN struct KSPROCESSPIPESECTION *Section)
504{
507}
508
510NTAPI
512 IKsFilter * iface,
513 IN PKSPROCESSPIN ProcessPin)
514{
517
518 /* first acquire processing mutex */
520
521 /* sanity check */
522 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id);
523
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),
528 0);
529
530 if (NT_SUCCESS(Status))
531 {
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++;
535 }
536
537 /* release process mutex */
538 KeReleaseMutex(&This->ProcessingMutex, FALSE);
539
540 return Status;
541}
542
544NTAPI
546 IKsFilter * iface,
547 IN PKSPROCESSPIN ProcessPin)
548{
549 ULONG Index;
550 ULONG Count;
551 PKSPROCESSPIN * Pins;
552
554
555 /* first acquire processing mutex */
557
558 /* sanity check */
559 ASSERT(ProcessPin->Pin);
560 ASSERT(ProcessPin->Pin->Id);
561
562 Count = This->ProcessPinIndex[ProcessPin->Pin->Id].Count;
563 Pins = This->ProcessPinIndex[ProcessPin->Pin->Id].Pins;
564
565 /* search for current process pin */
566 for(Index = 0; Index < Count; Index++)
567 {
568 if (Pins[Index] == ProcessPin)
569 {
570 RtlMoveMemory(&Pins[Index], &Pins[Index + 1], (Count - (Index + 1)) * sizeof(PVOID));
571 break;
572 }
573
574 }
575
576 /* decrement pin count */
577 This->ProcessPinIndex[ProcessPin->Pin->Id].Count--;
578
579 if (!This->ProcessPinIndex[ProcessPin->Pin->Id].Count)
580 {
581 /* clear entry object bag will delete it */
582 This->ProcessPinIndex[ProcessPin->Pin->Id].Pins = NULL;
583 }
584
585 /* release process mutex */
586 KeReleaseMutex(&This->ProcessingMutex, FALSE);
587
588 /* done */
589 return STATUS_SUCCESS;
590}
591
592BOOL
593NTAPI
595 IKsFilter * iface,
596 IN struct KSPROCESSPIPESECTION *PipeSection,
597 IN PULONG Data)
598{
600 return FALSE;
601}
602
603VOID
604NTAPI
606 IKsFilter * iface,
607 IN struct KSPROCESSPIPESECTION *PipeSection,
609{
611}
612
613BOOL
614NTAPI
616 IKsFilter * iface)
617{
619 return FALSE;
620}
621
622VOID
623NTAPI
625 IKsFilter * iface,
626 IKsQueue *Queue,
628{
630}
631
633NTAPI
635 IKsFilter * iface)
636{
638
639 return This->ProcessPinIndex;
640}
641
642static IKsFilterVtbl vt_IKsFilter =
643{
659};
660
663 IN PIRP Irp,
664 OUT IKsFilter **Filter)
665{
666 PIO_STACK_LOCATION IoStack;
667 PKSIOBJECT_HEADER ObjectHeader;
669
670 /* get current irp stack */
672
673 /* sanity check */
674 ASSERT(IoStack->FileObject != NULL);
675
676 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
677
678 /* sanity is important */
679 ASSERT(ObjectHeader != NULL);
680 ASSERT(ObjectHeader->Type == KsObjectTypeFilter);
681 ASSERT(ObjectHeader->Unknown != NULL);
682
683 /* get our private interface */
684 Status = ObjectHeader->Unknown->lpVtbl->QueryInterface(ObjectHeader->Unknown, &IID_IKsFilter, (PVOID*)Filter);
685
686 if (!NT_SUCCESS(Status))
687 {
688 /* something is wrong here */
689 DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader->Unknown);
690 Irp->IoStatus.Status = Status;
691
692 /* complete and forget irp */
694 return Status;
695 }
696 return Status;
697}
698
699
701NTAPI
704 IN PIRP Irp)
705{
706 IKsFilter * Filter;
709
710 /* obtain filter from object header */
712 if (!NT_SUCCESS(Status))
713 return Status;
714
715 /* get our real implementation */
717
718 /* does the driver support notifications */
719 if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close)
720 {
721 /* call driver's filter close function */
722 Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp);
723 }
724
726 {
727 /* save the result */
728 Irp->IoStatus.Status = Status;
729 /* complete irp */
731
732 /* remove our instance from the filter factory */
734
735 /* free object header */
736 KsFreeObjectHeader(This->ObjectHeader);
737 }
738 else
739 {
740 /* complete and forget */
741 Irp->IoStatus.Status = Status;
742 /* complete irp */
744 }
745
746 /* done */
747 return Status;
748}
749
756 IN BOOL Global)
757{
758 KSPIN_CINSTANCES * Instances;
760
761 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
762 {
763 /* no filter / pin descriptor */
766 }
767
768 /* ignore custom structs for now */
769 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
770 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
771
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];
777
778 IoStatus->Information = sizeof(KSPIN_CINSTANCES);
779 IoStatus->Status = STATUS_SUCCESS;
780 return STATUS_SUCCESS;
781}
782
789{
792
793 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
794 {
795 /* no filter / pin descriptor */
798 }
799
800 /* ignore custom structs for now */
801 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
802 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
803
804 Result = (PULONG)Data;
805 *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary;
806
807 IoStatus->Information = sizeof(ULONG);
808 IoStatus->Status = STATUS_SUCCESS;
809 return STATUS_SUCCESS;
810}
811
814 IN PIRP Irp,
820{
821 PKSMULTIPLE_ITEM MultipleItem;
822 PKSDATARANGE DataRange;
825 PIO_STACK_LOCATION IoStack;
827
828 /* get stack location */
830
831 /* sanity check */
832 ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength);
833
834 /* Access parameters */
835 MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
836 DataRange = (PKSDATARANGE)(MultipleItem + 1);
837
838 /* FIXME make sure its 64 bit aligned */
839 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
840
841 if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount)
842 {
843 /* no filter / pin descriptor */
846 }
847
848 /* ignore custom structs for now */
849 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
850 ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId);
851
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)
855 {
856 /* no driver supported intersect handler / no provided data ranges */
859 }
860
861 for(Index = 0; Index < MultipleItem->Count; Index++)
862 {
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);
868
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);
871
872 /* FIXME implement KsPinDataIntersectionEx */
873 /* Call miniport's proprietary handler */
874 Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter,
875 Irp,
876 Pin,
877 DataRange,
878 This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
880 Data,
881 &Length);
882 DPRINT("KspHandleDataIntersection Status %lx\n", Status);
883
885 {
886 ASSERT(Length);
887 IoStatus->Information = Length;
888 break;
889 }
890
891 DataRange = (PKSDATARANGE)((PUCHAR)DataRange + DataRange->FormatSize);
892 /* FIXME make sure its 64 bit aligned */
893 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
894 }
895 IoStatus->Status = Status;
896 return Status;
897}
898
900NTAPI
902 IN PIRP Irp,
905{
907
908 /* get filter implementation */
909 This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
910
911 /* sanity check */
912 ASSERT(This);
913
914 return KsTopologyPropertyHandler(Irp, Request, Data, &This->Topology);
915
916}
917
919NTAPI
921 IN PIRP Irp,
924{
925 PIO_STACK_LOCATION IoStack;
927
928 /* get filter implementation */
929 This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
930
931 /* sanity check */
932 ASSERT(This);
933
934 /* get current stack location */
936 ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSCOMPONENTID));
937
938 if (This->Filter.Descriptor->ComponentId != NULL)
939 {
940 RtlMoveMemory(Data, This->Filter.Descriptor->ComponentId, sizeof(KSCOMPONENTID));
941 Irp->IoStatus.Information = sizeof(KSCOMPONENTID);
942 return STATUS_SUCCESS;
943 }
944 else
945 {
946 /* not valid */
947 return STATUS_NOT_FOUND;
948 }
949
950}
951
953NTAPI
955 IN PIRP Irp,
958{
959 PIO_STACK_LOCATION IoStack;
962
963 /* get filter implementation */
964 This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
965
966 /* sanity check */
967 ASSERT(This);
968
969 /* get current stack location */
971
972 switch(Request->Id)
973 {
983 Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize);
984 break;
987 break;
990 break;
993 break;
994
996 Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This);
997 break;
998 default:
1001 }
1002 DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->Filter.Descriptor->PinDescriptorsCount, Request->Id, Status);
1003
1004
1005 return Status;
1006}
1007
1009NTAPI
1012 IN PIRP Irp)
1013{
1014 PIO_STACK_LOCATION IoStack;
1015 IKsFilter * Filter;
1018 PKSFILTER FilterInstance;
1021 ULONG SetCount = 0;
1022 PKSP_NODE NodeProperty;
1023 PKSNODE_DESCRIPTOR NodeDescriptor;
1024
1025 /* obtain filter from object header */
1027 if (!NT_SUCCESS(Status))
1028 return Status;
1029
1030 /* get our real implementation */
1032
1033 /* current irp stack */
1035
1036 /* get property from input buffer */
1037 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
1038
1039 /* get filter instance */
1040 FilterInstance = Filter->lpVtbl->GetStruct(Filter);
1041
1042 /* sanity check */
1043 ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER));
1044 ASSERT(FilterInstance);
1045 ASSERT(FilterInstance->Descriptor);
1046 ASSERT(FilterInstance->Descriptor->AutomationTable);
1047
1048 /* acquire control mutex */
1049 KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
1050
1051 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD)
1052 {
1053 const KSMETHOD_SET *MethodSet = NULL;
1054 ULONG MethodItemSize = 0;
1055
1056 /* check if the driver supports method sets */
1057 if (FilterInstance->Descriptor->AutomationTable->MethodSetsCount)
1058 {
1059 SetCount = FilterInstance->Descriptor->AutomationTable->MethodSetsCount;
1060 MethodSet = FilterInstance->Descriptor->AutomationTable->MethodSets;
1061 MethodItemSize = FilterInstance->Descriptor->AutomationTable->MethodItemSize;
1062 }
1063
1064 /* call method set handler */
1065 Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize);
1066 }
1067 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
1068 {
1069 const KSPROPERTY_SET *PropertySet = NULL;
1070 ULONG PropertyItemSize = 0;
1071
1072 /* check if the driver supports method sets */
1074 {
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)
1079 {
1080 SetCount = NodeDescriptor->AutomationTable->PropertySetsCount;
1081 PropertySet = NodeDescriptor->AutomationTable->PropertySets;
1082 PropertyItemSize = 0;
1083 }
1084 }
1085 else if (FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
1086 {
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;
1093 }
1094
1095 /* needed for our property handlers */
1096 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This;
1097
1098 /* call property handler */
1099 Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize);
1100 }
1101 else
1102 {
1103 /* sanity check */
1104 ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT ||
1105 IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT);
1106
1107 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
1108 {
1109 /* call enable event handlers */
1111 FilterInstance->Descriptor->AutomationTable->EventSetsCount,
1112 (PKSEVENT_SET)FilterInstance->Descriptor->AutomationTable->EventSets,
1113 &This->Header.EventList,
1115 (PVOID)&This->Header.EventListLock,
1116 NULL,
1117 FilterInstance->Descriptor->AutomationTable->EventItemSize);
1118 }
1119 else
1120 {
1121 /* disable event handler */
1122 Status = KsDisableEvent(Irp, &This->Header.EventList, KSEVENTS_SPINLOCK, &This->Header.EventListLock);
1123 }
1124 }
1125
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);
1130
1131 /* release filter */
1132 Filter->lpVtbl->Release(Filter);
1133
1134 /* release control mutex */
1135 KeReleaseMutex(This->Header.ControlMutex, FALSE);
1136
1137 if (Status != STATUS_PENDING)
1138 {
1139 Irp->IoStatus.Status = Status;
1141 }
1142
1143 /* done */
1144 return Status;
1145}
1146
1147static KSDISPATCH_TABLE DispatchTable =
1148{
1159};
1160
1161
1165 KSFILTER_DESCRIPTOR* FilterDescriptor)
1166{
1167 ULONG Index = 0;
1169 PKSNODE_DESCRIPTOR NodeDescriptor;
1170
1171 /* initialize pin descriptors */
1172 This->FirstPin = NULL;
1173 This->PinInstanceCount = NULL;
1174 This->ProcessPinIndex = NULL;
1175
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;
1182
1183 /* are there any templates */
1184 if (FilterDescriptor->PinDescriptorsCount)
1185 {
1186 /* sanity check */
1187 ASSERT(FilterDescriptor->PinDescriptors);
1188
1189 /* FIXME handle variable sized pin descriptors */
1190 ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
1191
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);
1195
1196 if (!NT_SUCCESS(Status))
1197 {
1198 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
1199 return Status;
1200 }
1201
1202 /* store pin instance count */
1203 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount,
1204 sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0);
1205
1206 if (!NT_SUCCESS(Status))
1207 {
1208 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
1209 return Status;
1210 }
1211
1212 /* store instantiated pin arrays */
1213 Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->FirstPin, sizeof(PVOID) * FilterDescriptor->PinDescriptorsCount,
1214 sizeof(PVOID) * FilterDescriptor->PinDescriptorsCount, 0);
1215
1216 if (!NT_SUCCESS(Status))
1217 {
1218 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
1219 return Status;
1220 }
1221
1222 /* add new pin factory */
1223 RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount);
1224
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);
1228
1229 if (!NT_SUCCESS(Status))
1230 {
1231 DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status);
1232 return Status;
1233 }
1234
1235 }
1236
1237
1238 if (FilterDescriptor->ConnectionsCount)
1239 {
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),
1245 0);
1246
1247 This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
1248 This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount;
1249 }
1250
1251 if (FilterDescriptor->NodeDescriptorsCount)
1252 {
1253 /* sanity check */
1254 ASSERT(FilterDescriptor->NodeDescriptors);
1255
1256 /* sanity check */
1257 ASSERT(FilterDescriptor->NodeDescriptorSize >= sizeof(KSNODE_DESCRIPTOR));
1258
1259 This->Topology.TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescriptor->NodeDescriptorsCount);
1260 /* allocate topology node types array */
1261 if (!This->Topology.TopologyNodes)
1262 {
1263 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor->NodeDescriptorsCount);
1265 }
1266
1267 This->Topology.TopologyNodesNames = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescriptor->NodeDescriptorsCount);
1268 /* allocate topology names array */
1269 if (!This->Topology.TopologyNodesNames)
1270 {
1271 FreeItem((PVOID)This->Topology.TopologyNodes);
1272 DPRINT("IKsFilter_CreateDescriptors OutOfMemory TopologyNodesCount %lu\n", FilterDescriptor->NodeDescriptorsCount);
1274 }
1275
1276 DPRINT("NodeDescriptorCount %lu\n", FilterDescriptor->NodeDescriptorsCount);
1277 NodeDescriptor = (PKSNODE_DESCRIPTOR)FilterDescriptor->NodeDescriptors;
1278 for(Index = 0; Index < FilterDescriptor->NodeDescriptorsCount; Index++)
1279 {
1280 DPRINT("Index %lu Type %p Name %p\n", Index, NodeDescriptor->Type, NodeDescriptor->Name);
1281
1282 /* copy topology type */
1283 if (NodeDescriptor->Type)
1284 RtlMoveMemory((PVOID)&This->Topology.TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID));
1285
1286 /* copy topology name */
1287 if (NodeDescriptor->Name)
1288 RtlMoveMemory((PVOID)&This->Topology.TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID));
1289
1290 // next node descriptor
1291 NodeDescriptor = (PKSNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescriptor->NodeDescriptorSize);
1292 }
1293 }
1294 /* done! */
1295 return STATUS_SUCCESS;
1296}
1297
1301 const KSFILTER_DESCRIPTOR* FilterDescriptor)
1302{
1304 KSAUTOMATION_TABLE AutomationTable;
1305
1306 This->Filter.Descriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR));
1307 if (!This->Filter.Descriptor)
1309
1310 Status = KsAddItemToObjectBag(This->Filter.Bag, (PVOID)This->Filter.Descriptor, NULL);
1311 if (!NT_SUCCESS(Status))
1312 {
1313 FreeItem((PVOID)This->Filter.Descriptor);
1314 This->Filter.Descriptor = NULL;
1316 }
1317
1318 /* copy filter descriptor fields */
1319 RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
1320
1321 /* zero automation table */
1322 RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE));
1323
1324 /* setup filter property sets */
1325 AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM);
1326 AutomationTable.PropertySetsCount = 3;
1327 AutomationTable.PropertySets = FilterPropertySet;
1328
1329 /* merge filter automation table */
1330 Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Filter.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)FilterDescriptor->AutomationTable, &AutomationTable, This->Filter.Bag);
1331
1332 return Status;
1333}
1334
1335
1336VOID
1338 PKSFILTER Filter,
1339 PKSPIN Pin)
1340{
1341 PKSPIN NextPin, CurPin;
1342 PKSBASIC_HEADER BasicHeader;
1344
1345 /* sanity check */
1346 ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
1347
1348 if (This->FirstPin[Pin->Id] == NULL)
1349 {
1350 /* welcome first pin */
1351 This->FirstPin[Pin->Id] = Pin;
1352 This->PinInstanceCount[Pin->Id]++;
1353 return;
1354 }
1355
1356 /* get first pin */
1357 CurPin = This->FirstPin[Pin->Id];
1358
1359 do
1360 {
1361 /* get next instantiated pin */
1362 NextPin = KsPinGetNextSiblingPin(CurPin);
1363 if (!NextPin)
1364 break;
1365
1366 NextPin = CurPin;
1367
1368 }while(NextPin != NULL);
1369
1370 /* get basic header */
1371 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)CurPin - sizeof(KSBASIC_HEADER));
1372
1373 /* store pin */
1374 BasicHeader->Next.Pin = Pin;
1375}
1376
1377VOID
1379 PKSFILTER Filter,
1380 PKSPIN Pin)
1381{
1382 PKSPIN NextPin, CurPin, LastPin;
1383 PKSBASIC_HEADER BasicHeader;
1385
1386 /* sanity check */
1387 ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount);
1388
1389 /* get first pin */
1390 CurPin = This->FirstPin[Pin->Id];
1391
1392 LastPin = NULL;
1393 do
1394 {
1395 /* get next instantiated pin */
1396 NextPin = KsPinGetNextSiblingPin(CurPin);
1397
1398 if (CurPin == Pin)
1399 {
1400 if (LastPin)
1401 {
1402 /* get basic header of last pin */
1403 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastPin - sizeof(KSBASIC_HEADER));
1404
1405 BasicHeader->Next.Pin = NextPin;
1406 }
1407 else
1408 {
1409 /* erase last pin */
1410 This->FirstPin[Pin->Id] = NextPin;
1411 }
1412 /* decrement pin instance count */
1413 This->PinInstanceCount[Pin->Id]--;
1414 return;
1415 }
1416
1417 if (!NextPin)
1418 break;
1419
1420 LastPin = CurPin;
1421 NextPin = CurPin;
1422
1423 }while(NextPin != NULL);
1424
1425 /* pin not found */
1426 ASSERT(0);
1427}
1428
1429
1431NTAPI
1434 IN PIRP Irp)
1435{
1437 PKSOBJECT_CREATE_ITEM CreateItem;
1440
1441 DPRINT("IKsFilter_DispatchCreatePin\n");
1442
1443 /* get the create item */
1444 CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
1445
1446 /* get the filter object */
1447 This = (IKsFilterImpl*)CreateItem->Context;
1448
1449 /* sanity check */
1450 ASSERT(This->Header.Type == KsObjectTypeFilter);
1451
1452 /* acquire control mutex */
1453 KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL);
1454
1455 /* now validate the connect request */
1456 Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect);
1457
1458 DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status);
1459
1460 if (NT_SUCCESS(Status))
1461 {
1462 /* sanity check */
1463 ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount);
1464
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);
1468
1469 if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible)
1470 {
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]);
1473
1474 DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status);
1475 }
1476 else
1477 {
1478 /* maximum instance count reached, bye-bye */
1480 DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]);
1481 }
1482 }
1483
1484 /* release control mutex */
1485 KeReleaseMutex(This->Header.ControlMutex, FALSE);
1486
1487 if (Status != STATUS_PENDING)
1488 {
1489 /* complete request */
1490 Irp->IoStatus.Status = Status;
1492 }
1493
1494 /* done */
1495 DPRINT("IKsFilter_DispatchCreatePin Result %lx\n", Status);
1496 return Status;
1497}
1498
1500NTAPI
1503 IN PIRP Irp)
1504{
1506 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
1508 return STATUS_UNSUCCESSFUL;
1509}
1510
1511
1512VOID
1515 PKSFILTERFACTORY FilterFactory)
1516{
1517 PKSBASIC_HEADER BasicHeader;
1518 PKSFILTER Filter;
1519
1520
1521 /* get filter factory basic header */
1522 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
1523
1524 /* sanity check */
1525 ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
1526
1527 if (BasicHeader->FirstChild.FilterFactory == NULL)
1528 {
1529 /* welcome first instantiated filter */
1530 BasicHeader->FirstChild.Filter = &This->Filter;
1531 return;
1532 }
1533
1534 /* set to first entry */
1535 Filter = BasicHeader->FirstChild.Filter;
1536
1537 do
1538 {
1539 /* get basic header */
1540 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER));
1541 /* sanity check */
1542 ASSERT(BasicHeader->Type == KsObjectTypeFilter);
1543
1544 if (BasicHeader->Next.Filter)
1545 {
1546 /* iterate to next filter factory */
1547 Filter = BasicHeader->Next.Filter;
1548 }
1549 else
1550 {
1551 /* found last entry */
1552 break;
1553 }
1554 }while(TRUE);
1555
1556 /* attach filter factory */
1557 BasicHeader->Next.Filter = &This->Filter;
1558}
1559
1560VOID
1563 PKSFILTERFACTORY FilterFactory)
1564{
1565 PKSBASIC_HEADER BasicHeader;
1566 PKSFILTER Filter, LastFilter;
1567
1568 /* get filter factory basic header */
1569 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
1570
1571 /* sanity check */
1572 ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
1573 ASSERT(BasicHeader->FirstChild.Filter != NULL);
1574
1575
1576 /* set to first entry */
1577 Filter = BasicHeader->FirstChild.Filter;
1578 LastFilter = NULL;
1579
1580 do
1581 {
1582 if (Filter == &This->Filter)
1583 {
1584 if (LastFilter)
1585 {
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;
1590 break;
1591 }
1592 else
1593 {
1594 /* remove filter instance */
1595 BasicHeader->FirstChild.Filter = This->Header.Next.Filter;
1596 break;
1597 }
1598 }
1599
1600 /* get basic header */
1601 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER));
1602 /* sanity check */
1603 ASSERT(BasicHeader->Type == KsObjectTypeFilter);
1604
1605 LastFilter = Filter;
1606 if (BasicHeader->Next.Filter)
1607 {
1608 /* iterate to next filter factory */
1609 Filter = BasicHeader->Next.Filter;
1610 }
1611 else
1612 {
1613 /* filter is not in list */
1614 ASSERT(0);
1615 break;
1616 }
1617 }while(TRUE);
1618}
1619
1620VOID
1621NTAPI
1623 IN PVOID Ctx)
1624{
1625 IKsProcessingObject * Object = (IKsProcessingObject*)Ctx;
1626
1627 /* sanity check */
1628 ASSERT(Object);
1629
1630 /* perform work */
1631 Object->lpVtbl->ProcessingObjectWork(Object);
1632}
1633
1635NTAPI
1638 IN PIRP Irp,
1639 IN IKsFilterFactory *iface)
1640{
1642 IKsDevice *KsDevice;
1643 PKSFILTERFACTORY Factory;
1644 PIO_STACK_LOCATION IoStack;
1645 PDEVICE_EXTENSION DeviceExtension;
1647 PKSOBJECT_CREATE_ITEM CreateItem;
1648
1649 /* get device extension */
1650 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
1651
1652 /* get the filter factory */
1653 Factory = iface->lpVtbl->GetStruct(iface);
1654
1655 if (!Factory || !Factory->FilterDescriptor)
1656 {
1657 /* Sorry it just will not work */
1658 return STATUS_UNSUCCESSFUL;
1659 }
1660
1661 if (Factory->FilterDescriptor->Flags & KSFILTER_FLAG_DENY_USERMODE_ACCESS)
1662 {
1663 if (Irp->RequestorMode == UserMode)
1664 {
1665 /* filter not accessible from user mode */
1666 DPRINT1("Access denied\n");
1667 return STATUS_UNSUCCESSFUL;
1668 }
1669 }
1670
1671 /* allocate filter instance */
1673 if (!This)
1674 {
1675 DPRINT1("KspCreateFilter OutOfMemory\n");
1677 }
1678
1679 /* initialize object bag */
1680 This->Filter.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG));
1681 if (!This->Filter.Bag)
1682 {
1683 /* no memory */
1684 FreeItem(This);
1685 DPRINT1("KspCreateFilter OutOfMemory\n");
1687 }
1688 KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
1689 KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL);
1690
1691 /* copy filter descriptor */
1692 Status = IKsFilter_CopyFilterDescriptor(This, Factory->FilterDescriptor);
1693 if (!NT_SUCCESS(Status))
1694 {
1695 /* not enough memory */
1696 FreeItem(This->Filter.Bag);
1697 FreeItem(This);
1698 DPRINT("KspCreateFilter IKsFilter_CopyFilterDescriptor failed %lx\n", Status);
1700 }
1701
1702 /* get current irp stack */
1704
1705 /* allocate create items */
1706 CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2);
1707 if (!CreateItem)
1708 {
1709 /* no memory */
1710 FreeItem(This->Filter.Bag);
1711 FreeItem(This);
1712 DPRINT1("KspCreateFilter OutOfMemory\n");
1714 }
1715
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);
1726
1727
1728 /* initialize filter instance */
1729 This->ref = 1;
1730 This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter;
1731 This->lpVtblKsControl = &vt_IKsControl;
1732 This->lpVtblKsProcessingObject = &vt_IKsProcessingObject;
1733
1734 This->Factory = Factory;
1735 This->FilterFactory = iface;
1736 This->FileObject = IoStack->FileObject;
1737 KeInitializeMutex(&This->ProcessingMutex, 0);
1738
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);
1747
1748 /* initialize and gate */
1749 KsGateInitializeAnd(&This->Gate, NULL);
1750
1751 /* FIXME initialize and gate based on pin flags */
1752
1753 /* initialize work item */
1754 ExInitializeWorkItem(&This->WorkItem, IKsFilter_FilterCentricWorker, (PVOID)This->lpVtblKsProcessingObject);
1755
1756 /* allocate counted work item */
1758 if (!NT_SUCCESS(Status))
1759 {
1760 /* what can go wrong, goes wrong */
1761 DPRINT1("KsRegisterCountedWorker failed with %lx\n", Status);
1762 FreeItem(This);
1763 FreeItem(CreateItem);
1764 return Status;
1765 }
1766
1767 /* allocate the stream descriptors */
1768 Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor);
1769 if (!NT_SUCCESS(Status))
1770 {
1771 /* what can go wrong, goes wrong */
1772 DPRINT1("IKsFilter_CreateDescriptors failed with %lx\n", Status);
1773 KsUnregisterWorker(This->Worker);
1774 FreeItem(This);
1775 FreeItem(CreateItem);
1776 return Status;
1777 }
1778
1779
1780
1781 /* does the filter have a filter dispatch */
1782 if (Factory->FilterDescriptor->Dispatch)
1783 {
1784 /* does it have a create routine */
1785 if (Factory->FilterDescriptor->Dispatch->Create)
1786 {
1787 /* now let driver initialize the filter instance */
1788
1789 ASSERT(This->Header.KsDevice);
1790 ASSERT(This->Header.KsDevice->Started);
1791 Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp);
1792
1794 {
1795 /* driver failed to initialize */
1796 DPRINT1("Driver: Status %x\n", Status);
1797
1798 /* free filter instance */
1799 KsUnregisterWorker(This->Worker);
1800 FreeItem(This);
1801 FreeItem(CreateItem);
1802 return Status;
1803 }
1804 }
1805 }
1806
1807 /* now allocate the object header */
1808 Status = KsAllocateObjectHeader((PVOID*)&This->ObjectHeader, 2, CreateItem, Irp, &DispatchTable);
1809 if (!NT_SUCCESS(Status))
1810 {
1811 /* failed to allocate object header */
1812 DPRINT1("Failed to allocate object header %x\n", Status);
1813
1814 return Status;
1815 }
1816
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;
1821
1822 /* attach filter to filter factory */
1823 IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory);
1824
1825 /* completed initialization */
1826 DPRINT1("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice);
1827 return Status;
1828}
1829
1830/*
1831 @implemented
1832*/
1834VOID
1835NTAPI
1837 IN PKSFILTER Filter)
1838{
1840
1842}
1843
1844/*
1845 @implemented
1846*/
1848VOID
1849NTAPI
1851 IN PKSFILTER Filter)
1852{
1854
1855 KeReleaseMutex(&This->ProcessingMutex, FALSE);
1856}
1857
1858
1859/*
1860 @implemented
1861*/
1864NTAPI
1866 IN PKSFILTER Filter,
1867 IN ULONG NewConnectionsCount,
1868 IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections)
1869{
1870 ULONG Count;
1873
1874 DPRINT("KsFilterAddTopologyConnections\n");
1875
1876 ASSERT(This->Filter.Descriptor);
1877 Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount;
1878
1879
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),
1885 0);
1886
1887 if (!NT_SUCCESS(Status))
1888 {
1889 /* failed */
1890 DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status);
1891 return Status;
1892 }
1893
1894 /* FIXME verify connections */
1895
1896 /* copy new connections */
1897 RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount],
1898 NewTopologyConnections,
1899 NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
1900
1901 /* update topology */
1902 This->Topology.TopologyConnectionsCount += NewConnectionsCount;
1903 ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount;
1904 This->Topology.TopologyConnections = This->Filter.Descriptor->Connections;
1905
1906 return Status;
1907}
1908
1909/*
1910 @implemented
1911*/
1913VOID
1914NTAPI
1916 IN PKSFILTER Filter,
1918{
1919 PKSGATE Gate;
1921
1922 /* get gate */
1923 Gate = This->lpVtblKsProcessingObject->GetAndGate((IKsProcessingObject*)This->lpVtblKsProcessingObject);
1924
1925 if (!KsGateCaptureThreshold(Gate))
1926 {
1927 /* filter control gate is closed */
1928 return;
1929 }
1930DPRINT1("processing\n");
1931 /* try initiate processing */
1932 This->lpVtblKsProcessingObject->Process((IKsProcessingObject*)This->lpVtblKsProcessingObject, Asynchronous);
1933}
1934
1935/*
1936 @unimplemented
1937*/
1940NTAPI
1942 IN PKSFILTER Filter,
1943 IN const KSNODE_DESCRIPTOR *const NodeDescriptor,
1944 OUT PULONG NodeID)
1945{
1948}
1949
1950/*
1951 @implemented
1952*/
1955NTAPI
1957 IN PKSFILTER Filter,
1958 IN const KSPIN_DESCRIPTOR_EX *const InPinDescriptor,
1959 OUT PULONG PinID)
1960{
1961 ULONG Count;
1964
1965 DPRINT("KsFilterCreatePinFactory\n");
1966
1967 /* calculate new count */
1968 Count = This->Filter.Descriptor->PinDescriptorsCount + 1;
1969
1970 /* sanity check */
1971 ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
1972
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))
1976 {
1977 /* failed */
1978 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
1979 return Status;
1980 }
1981
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))
1985 {
1986 /* failed */
1987 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
1988 return Status;
1989 }
1990
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))
1994 {
1995 /* failed */
1996 DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status);
1997 return Status;
1998 }
1999
2000 /* add new pin factory */
2001 RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
2002
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);
2006
2007 if (!NT_SUCCESS(Status))
2008 {
2009 DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status);
2010 return Status;
2011 }
2012
2013 /* store new pin id */
2014 *PinID = This->Filter.Descriptor->PinDescriptorsCount;
2015
2016 /* increment pin descriptor count */
2017 ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++;
2018
2019
2020 DPRINT("KsFilterCreatePinFactory done\n");
2021 return STATUS_SUCCESS;
2022
2023}
2024
2025/*
2026 @unimplemented
2027*/
2029PKSGATE
2030NTAPI
2032 IN PKSFILTER Filter)
2033{
2035
2036 /* return and-gate */
2037 return &This->Gate;
2038}
2039
2040/*
2041 @implemented
2042*/
2044ULONG
2045NTAPI
2047 IN PKSFILTER Filter,
2048 IN ULONG PinId)
2049{
2051
2052 if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
2053 {
2054 /* index is out of bounds */
2055 return 0;
2056 }
2057 /* return pin instance count */
2058 return This->PinInstanceCount[PinId];
2059}
2060
2061/*
2062 @implemented
2063*/
2065PKSPIN
2066NTAPI
2068 IN PKSFILTER Filter,
2069 IN ULONG PinId)
2070{
2072
2073 if (PinId >= This->Filter.Descriptor->PinDescriptorsCount)
2074 {
2075 /* index is out of bounds */
2076 return NULL;
2077 }
2078
2079 /* return first pin index */
2080 return This->FirstPin[PinId];
2081}
2082
2083/*
2084 @implemented
2085*/
2087VOID
2088NTAPI
2090 IN PKSFILTER Filter,
2091 IN PFNKSFILTERPOWER Sleep OPTIONAL,
2092 IN PFNKSFILTERPOWER Wake OPTIONAL)
2093{
2095
2096 This->Sleep = Sleep;
2097 This->Wake = Wake;
2098}
2099
2100/*
2101 @implemented
2102*/
2104PKSFILTER
2105NTAPI
2107 IN PIRP Irp)
2108{
2109 PIO_STACK_LOCATION IoStack;
2110 PKSIOBJECT_HEADER ObjectHeader;
2111
2112 DPRINT("KsGetFilterFromIrp\n");
2113
2114 /* get current irp stack location */
2116
2117 /* sanity check */
2118 ASSERT(IoStack->FileObject);
2119
2120 /* get object header */
2121 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
2122
2123 if (ObjectHeader->Type == KsObjectTypeFilter)
2124 {
2125 /* irp is targeted at the filter */
2126 return (PKSFILTER)ObjectHeader->ObjectType;
2127 }
2128 else if (ObjectHeader->Type == KsObjectTypePin)
2129 {
2130 /* irp is for a pin */
2131 return KsPinGetParentFilter((PKSPIN)ObjectHeader->ObjectType);
2132 }
2133 else
2134 {
2135 /* irp is unappropiate to retrieve a filter */
2136 return NULL;
2137 }
2138}
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
NTSTATUS NTAPI KsAddItemToObjectBag(IN KSOBJECT_BAG ObjectBag, IN PVOID Item, IN PFNKSFREE Free OPTIONAL)
Definition: bag.c:86
KSDDKAPI NTSTATUS NTAPI _KsEdit(IN KSOBJECT_BAG ObjectBag, IN OUT PVOID *PointerToPointerToItem, IN ULONG NewSize, IN ULONG OldSize, IN ULONG Tag)
Definition: bag.c:358
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
@ Create
Definition: registry.c:563
const GUID IID_IUnknown
#define UNIMPLEMENTED
Definition: debug.h:115
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
Definition: Header.h:9
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
KSDDKAPI NTSTATUS NTAPI KspPinPropertyHandler(IN PIRP Irp, IN PKSPROPERTY Property, IN OUT PVOID Data, IN ULONG DescriptorsCount, IN const KSPIN_DESCRIPTOR *Descriptors, IN ULONG DescriptorSize)
Definition: connectivity.c:324
NTSTATUS KspValidateConnectRequest(IN PIRP Irp, IN ULONG DescriptorsCount, IN PVOID Descriptors, IN ULONG DescriptorSize, OUT PKSPIN_CONNECT *Connect)
Definition: connectivity.c:60
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
static VOID Wake(_In_ UCHAR Csn)
Definition: hardware.c:149
NTSTATUS NTAPI KsMergeAutomationTables(OUT PKSAUTOMATION_TABLE *AutomationTableAB, IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL, IN KSOBJECT_BAG Bag OPTIONAL)
Definition: api.c:2303
KSDDKAPI VOID NTAPI KsFreeObjectHeader(IN PVOID Header)
Definition: api.c:720
KSDDKAPI NTSTATUS NTAPI KsSynchronousIoControlDevice(IN PFILE_OBJECT FileObject, IN KPROCESSOR_MODE RequestorMode, IN ULONG IoControl, IN PVOID InBuffer, IN ULONG InSize, OUT PVOID OutBuffer, IN ULONG OutSize, OUT PULONG BytesReturned)
Definition: api.c:1099
KSDDKAPI NTSTATUS NTAPI KsAllocateObjectHeader(OUT KSOBJECT_HEADER *Header, IN ULONG ItemsCount, IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL, IN PIRP Irp, IN KSDISPATCH_TABLE *Table)
Definition: api.c:610
KSDDKAPI NTSTATUS NTAPI KsDisableEvent(IN PIRP Irp, IN OUT PLIST_ENTRY EventsList, IN KSEVENTS_LOCKTYPE EventsFlags, IN PVOID EventsLock)
Definition: event.c:469
NTSTATUS KspEnableEvent(IN PIRP Irp, IN ULONG EventSetsCount, IN const KSEVENT_SET *EventSet, IN OUT PLIST_ENTRY EventsList OPTIONAL, IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL, IN PVOID EventsLock OPTIONAL, IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG EventItemSize OPTIONAL)
Definition: event.c:87
KSDDKAPI NTSTATUS NTAPI KsFilterCreateNode(IN PKSFILTER Filter, IN const KSNODE_DESCRIPTOR *const NodeDescriptor, OUT PULONG NodeID)
Definition: filter.c:1941
NTSTATUS NTAPI IKsControl_fnQueryInterface(IKsControl *iface, IN REFIID refiid, OUT PVOID *Output)
Definition: filter.c:280
const GUID KSPROPSETID_Pin
Definition: filter.c:47
NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: filter.c:901
NTSTATUS IKsFilter_CopyFilterDescriptor(IKsFilterImpl *This, const KSFILTER_DESCRIPTOR *FilterDescriptor)
Definition: filter.c:1299
static IKsFilterVtbl vt_IKsFilter
Definition: filter.c:642
KSPROPERTY_SET FilterPropertySet[]
Definition: filter.c:63
NTSTATUS NTAPI IKsFilter_fnBindProcessPinsToPipeSection(IKsFilter *iface, IN struct KSPROCESSPIPESECTION *Section, IN PVOID Create, IN PKSPIN KsPin, OUT IKsPin **Pin, OUT PKSGATE *OutGate)
Definition: filter.c:487
ULONG NTAPI IKsProcessingObject_fnAddRef(IKsProcessingObject *iface)
Definition: filter.c:108
NTSTATUS NTAPI IKsControl_fnKsMethod(IKsControl *iface, IN PKSMETHOD Method, IN ULONG MethodLength, IN OUT PVOID MethodData, IN ULONG DataLength, OUT ULONG *BytesReturned)
Definition: filter.c:337
static IKsControlVtbl vt_IKsControl
Definition: filter.c:374
KSDDKAPI NTSTATUS NTAPI KsFilterCreatePinFactory(IN PKSFILTER Filter, IN const KSPIN_DESCRIPTOR_EX *const InPinDescriptor, OUT PULONG PinID)
Definition: filter.c:1956
PKSGATE NTAPI IKsProcessingObject_fnGetAndGate(IKsProcessingObject *iface)
Definition: filter.c:189
KSDDKAPI VOID NTAPI KsFilterAcquireProcessingMutex(IN PKSFILTER Filter)
Definition: filter.c:1836
KSDDKAPI ULONG NTAPI KsFilterGetChildPinCount(IN PKSFILTER Filter, IN ULONG PinId)
Definition: filter.c:2046
VOID IKsFilter_RemoveFilterFromFilterFactory(IKsFilterImpl *This, PKSFILTERFACTORY FilterFactory)
Definition: filter.c:1561
NTSTATUS KspHandlePropertyInstances(IN PIO_STATUS_BLOCK IoStatus, IN PKSIDENTIFIER Request, IN OUT PVOID Data, IN IKsFilterImpl *This, IN BOOL Global)
Definition: filter.c:751
NTSTATUS NTAPI IKsFilter_fnAddProcessPin(IKsFilter *iface, IN PKSPROCESSPIN ProcessPin)
Definition: filter.c:511
NTSTATUS NTAPI IKsControl_fnKsProperty(IKsControl *iface, IN PKSPROPERTY Property, IN ULONG PropertyLength, IN OUT PVOID PropertyData, IN ULONG DataLength, OUT ULONG *BytesReturned)
Definition: filter.c:321
BOOL NTAPI IKsFilter_fnReprepareProcessPipeSection(IKsFilter *iface, IN struct KSPROCESSPIPESECTION *PipeSection, IN PULONG Data)
Definition: filter.c:594
KSDDKAPI NTSTATUS NTAPI KsFilterAddTopologyConnections(IN PKSFILTER Filter, IN ULONG NewConnectionsCount, IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections)
Definition: filter.c:1865
PKSFILTER NTAPI IKsFilter_fnGetStruct(IKsFilter *iface)
Definition: filter.c:456
NTSTATUS KspHandleDataIntersection(IN PIRP Irp, IN PIO_STATUS_BLOCK IoStatus, IN PKSIDENTIFIER Request, IN OUT PVOID Data, IN ULONG DataLength, IN IKsFilterImpl *This)
Definition: filter.c:813
VOID NTAPI IKsFilter_fnRegisterForCopyCallbacks(IKsFilter *iface, IKsQueue *Queue, BOOL Register)
Definition: filter.c:624
NTSTATUS NTAPI IKsFilter_fnUnbindProcessPinsFromPipeSection(IKsFilter *iface, IN struct KSPROCESSPIPESECTION *Section)
Definition: filter.c:501
NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: filter.c:954
NTSTATUS IKsFilter_GetFilterFromIrp(IN PIRP Irp, OUT IKsFilter **Filter)
Definition: filter.c:662
NTSTATUS NTAPI IKsFilter_DispatchCreatePin(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: filter.c:1432
VOID NTAPI IKsProcessingObject_fnProcessingObjectWork(IKsProcessingObject *iface)
Definition: filter.c:131
VOID IKsFilter_AddPin(PKSFILTER Filter, PKSPIN Pin)
Definition: filter.c:1337
ULONG NTAPI IKsFilter_fnAddRef(IKsFilter *iface)
Definition: filter.c:427
NTSTATUS KspHandleNecessaryPropertyInstances(IN PIO_STATUS_BLOCK IoStatus, IN PKSIDENTIFIER Request, IN OUT PVOID Data, IN IKsFilterImpl *This)
Definition: filter.c:784
VOID NTAPI IKsProcessingObject_fnProcess(IKsProcessingObject *iface, IN BOOLEAN Asynchronous)
Definition: filter.c:200
NTSTATUS NTAPI IKsFilter_fnCreateNode(IKsFilter *iface, IN PIRP Irp, IN IKsPin *Pin, IN PLIST_ENTRY ListEntry)
Definition: filter.c:475
NTSTATUS NTAPI IKsFilter_fnRemoveProcessPin(IKsFilter *iface, IN PKSPROCESSPIN ProcessPin)
Definition: filter.c:545
NTSTATUS NTAPI IKsFilter_fnQueryInterface(IKsFilter *iface, IN REFIID refiid, OUT PVOID *Output)
Definition: filter.c:387
KSDDKAPI PKSGATE NTAPI KsFilterGetAndGate(IN PKSFILTER Filter)
Definition: filter.c:2031
VOID IKsFilter_AttachFilterToFilterFactory(IKsFilterImpl *This, PKSFILTERFACTORY FilterFactory)
Definition: filter.c:1513
static IKsProcessingObjectVtbl vt_IKsProcessingObject
Definition: filter.c:264
NTSTATUS NTAPI IKsProcessingObject_fnQueryInterface(IKsProcessingObject *iface, IN REFIID refiid, OUT PVOID *Output)
Definition: filter.c:90
KSDDKAPI VOID NTAPI KsFilterAttemptProcessing(IN PKSFILTER Filter, IN BOOLEAN Asynchronous)
Definition: filter.c:1915
VOID NTAPI IKsProcessingObject_fnReset(IKsProcessingObject *iface)
Definition: filter.c:233
KSDDKAPI PKSPIN NTAPI KsFilterGetFirstChildPin(IN PKSFILTER Filter, IN ULONG PinId)
Definition: filter.c:2067
ULONG NTAPI IKsControl_fnRelease(IKsControl *iface)
Definition: filter.c:308
VOID IKsFilter_RemovePin(PKSFILTER Filter, PKSPIN Pin)
Definition: filter.c:1378
VOID NTAPI IKsFilter_fnDeliverResetState(IKsFilter *iface, IN struct KSPROCESSPIPESECTION *PipeSection, IN KSRESET ResetState)
Definition: filter.c:605
PKSPROCESSPIN_INDEXENTRY NTAPI IKsFilter_fnGetProcessDispatch(IKsFilter *iface)
Definition: filter.c:634
ULONG NTAPI IKsProcessingObject_fnRelease(IKsProcessingObject *iface)
Definition: filter.c:118
NTSTATUS NTAPI IKsControl_fnKsEvent(IKsControl *iface, IN PKSEVENT Event OPTIONAL, IN ULONG EventLength, IN OUT PVOID EventData, IN ULONG DataLength, OUT ULONG *BytesReturned)
Definition: filter.c:353
NTSTATUS NTAPI IKsFilter_DispatchDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: filter.c:1010
NTSTATUS NTAPI IKsFilter_DispatchCreateNode(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: filter.c:1501
NTSTATUS NTAPI FilterGeneralComponentIdHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: filter.c:920
const GUID IID_IKsControl
Definition: filter.c:44
KSDDKAPI VOID NTAPI KsFilterRegisterPowerCallbacks(IN PKSFILTER Filter, IN PFNKSFILTERPOWER Sleep OPTIONAL, IN PFNKSFILTERPOWER Wake OPTIONAL)
Definition: filter.c:2089
VOID NTAPI IKsFilter_FilterCentricWorker(IN PVOID Ctx)
Definition: filter.c:1622
const GUID KSPROPSETID_General
Definition: filter.c:48
NTSTATUS NTAPI KspCreateFilter(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN IKsFilterFactory *iface)
Definition: filter.c:1636
const GUID KSPROPSETID_Topology
Definition: filter.c:46
BOOL NTAPI IKsFilter_fnDoAllNecessaryPinsExist(IKsFilter *iface)
Definition: filter.c:466
ULONG NTAPI IKsFilter_fnRelease(IKsFilter *iface)
Definition: filter.c:437
KSDDKAPI PKSFILTER NTAPI KsGetFilterFromIrp(IN PIRP Irp)
Definition: filter.c:2106
const GUID IID_IKsFilter
Definition: filter.c:45
NTSTATUS IKsFilter_CreateDescriptors(IKsFilterImpl *This, KSFILTER_DESCRIPTOR *FilterDescriptor)
Definition: filter.c:1163
ULONG NTAPI IKsControl_fnAddRef(IKsControl *iface)
Definition: filter.c:298
VOID NTAPI IKsProcessingObject_fnTriggerNotification(IKsProcessingObject *iface)
Definition: filter.c:258
BOOL NTAPI IKsFilter_fnIsFrameHolding(IKsFilter *iface)
Definition: filter.c:615
KSDDKAPI VOID NTAPI KsFilterReleaseProcessingMutex(IN PKSFILTER Filter)
Definition: filter.c:1850
NTSTATUS NTAPI IKsFilter_DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: filter.c:702
KSDDKAPI NTSTATUS NTAPI KsDispatchInvalidDeviceRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1189
KSDDKAPI BOOLEAN NTAPI KsDispatchFastReadFailure(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: irp.c:1271
KSDDKAPI NTSTATUS NTAPI KsDispatchSetSecurity(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:67
KSDDKAPI NTSTATUS NTAPI KsDispatchQuerySecurity(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:22
KSDDKAPI BOOLEAN NTAPI KsDispatchFastIoDeviceControlFailure(IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: irp.c:1251
PKSFILTER NTAPI KsPinGetParentFilter(IN PKSPIN Pin)
Definition: pin.c:1097
PKSPIN NTAPI KsPinGetNextSiblingPin(IN PKSPIN Pin)
Definition: pin.c:1086
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet, PropGeneral, PropInstances, PropIntersection)
Definition: precomp.h:20
#define DEFINE_KSPROPERTY_GENEREAL_COMPONENTID(PinSet, PropGeneral)
Definition: precomp.h:36
KSDDKAPI NTSTATUS NTAPI KsTopologyPropertyHandler(IN PIRP Irp, IN PKSPROPERTY Property, IN OUT PVOID Data, IN const KSTOPOLOGY *Topology)
Definition: topology.c:144
#define KSPROPERTY_TYPE_TOPOLOGY
Definition: dmksctrl.h:53
struct KSIDENTIFIER * PKSPROPERTY
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:427
unsigned int BOOL
Definition: ntddk_ex.h:94
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
_In_ WDFDEVICE _In_ PWDF_DEVICE_INTERFACE_PROPERTY_DATA PropertyData
Status
Definition: gdiplustypes.h:25
@ ResetState
Definition: hdaudio.h:83
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
struct _KSPROCESSPIN_INDEXENTRY KSPROCESSPIN_INDEXENTRY
Definition: ks.h:3028
KSRESET
Definition: ks.h:1226
struct _KSPROCESSPIN_INDEXENTRY * PKSPROCESSPIN_INDEXENTRY
Definition: ks.h:3028
#define IOCTL_KS_METHOD
Definition: ks.h:136
#define IOCTL_KS_PROPERTY
Definition: ks.h:127
#define KSSTRING_Pin
Definition: ks.h:48
#define DEFINE_KSPROPERTY_TOPOLOGYSET(TopologySet, Handler)
Definition: ks.h:2663
#define KSSTRING_TopologyNode
Definition: ks.h:52
@ KsObjectTypeFilter
Definition: ks.h:1210
@ KsObjectTypePin
Definition: ks.h:1211
@ KsObjectTypeFilterFactory
Definition: ks.h:1209
@ KSPROPERTY_PIN_COMMUNICATION
Definition: ks.h:632
@ KSPROPERTY_PIN_CATEGORY
Definition: ks.h:636
@ KSPROPERTY_PIN_DATAINTERSECTION
Definition: ks.h:629
@ KSPROPERTY_PIN_NECESSARYINSTANCES
Definition: ks.h:634
@ KSPROPERTY_PIN_GLOBALCINSTANCES
Definition: ks.h:633
@ KSPROPERTY_PIN_CINSTANCES
Definition: ks.h:625
@ KSPROPERTY_PIN_MEDIUMS
Definition: ks.h:631
@ KSPROPERTY_PIN_NAME
Definition: ks.h:637
@ KSPROPERTY_PIN_CONSTRAINEDDATARANGES
Definition: ks.h:638
@ KSPROPERTY_PIN_DATARANGES
Definition: ks.h:628
@ KSPROPERTY_PIN_CTYPES
Definition: ks.h:626
@ KSPROPERTY_PIN_DATAFLOW
Definition: ks.h:627
@ KSPROPERTY_PIN_INTERFACES
Definition: ks.h:630
@ KSEVENTS_SPINLOCK
Definition: ks.h:1233
_In_ PKSPIN_CONNECT Connect
Definition: ks.h:4536
struct KSP_NODE * PKSP_NODE
#define IOCTL_KS_ENABLE_EVENT
Definition: ks.h:130
union KSDATAFORMAT * PKSDATARANGE
#define KSDDKAPI
Definition: ks.h:40
struct KSMULTIPLE_ITEM * PKSMULTIPLE_ITEM
#define IOCTL_KS_DISABLE_EVENT
Definition: ks.h:133
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
NTSTATUS KspPropertyHandler(IN PIRP Irp, IN ULONG PropertySetsCount, IN const KSPROPERTY_SET *PropertySet, IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG PropertyItemSize OPTIONAL)
Definition: property.c:138
NTSTATUS NTAPI KspMethodHandlerWithAllocator(IN PIRP Irp, IN ULONG MethodSetsCount, IN const KSMETHOD_SET *MethodSet, IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG MethodItemSize OPTIONAL)
Definition: methods.c:99
NTSTATUS KspCreatePin(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PKSDEVICE KsDevice, IN IKsFilterFactory *FilterFactory, IN IKsFilter *Filter, IN PKSPIN_CONNECT Connect, IN KSPIN_DESCRIPTOR_EX *Descriptor)
Definition: pin.c:2283
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
struct KSBASIC_HEADER * PKSBASIC_HEADER
struct KSIOBJECT_HEADER * PKSIOBJECT_HEADER
if(dx< 0)
Definition: linetemp.h:194
UNICODE_STRING Global
Definition: symlink.c:37
#define ASSERT(a)
Definition: mode.c:44
static PWSTR GuidString
Definition: apphelp.c:93
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
int Count
Definition: noreturn.cpp:7
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
_In_ SYSTEM_POWER_STATE _In_ ULONG _In_ BOOLEAN Asynchronous
Definition: ntpoapi.h:305
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MATCH
Definition: ntstatus.h:751
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
long LONG
Definition: pedump.c:60
#define REFIID
Definition: guiddef.h:118
@ Output
Definition: arc.h:85
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:71
const KSFILTER_DESCRIPTOR FilterDescriptor
Definition: splitter.c:229
const KSNODE_DESCRIPTOR NodeDescriptor[]
Definition: splitter.c:217
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PKSFILTERFACTORY Factory
Definition: filter.c:26
KSTOPOLOGY Topology
Definition: filter.c:25
PFNKSFILTERPOWER Wake
Definition: filter.c:36
KSFILTER Filter
Definition: filter.c:17
KMUTEX ProcessingMutex
Definition: filter.c:29
PKSIOBJECT_HEADER ObjectHeader
Definition: filter.c:24
PFNKSFILTERPOWER Sleep
Definition: filter.c:35
WORK_QUEUE_ITEM WorkItem
Definition: filter.c:32
LONG ref
Definition: filter.c:22
PFILE_OBJECT FileObject
Definition: filter.c:27
PKSPIN * FirstPin
Definition: filter.c:39
ULONG * PinInstanceCount
Definition: filter.c:38
IKsFilterFactory * FilterFactory
Definition: filter.c:20
KMUTEX ControlMutex
Definition: filter.c:28
PKSPROCESSPIN_INDEXENTRY ProcessPinIndex
Definition: filter.c:40
KSBASIC_HEADER Header
Definition: filter.c:16
IKsProcessingObjectVtbl * lpVtblKsProcessingObject
Definition: filter.c:21
KSGATE Gate
Definition: filter.c:33
PKSWORKER Worker
Definition: filter.c:31
IKsControlVtbl * lpVtblKsControl
Definition: filter.c:19
union KSBASIC_HEADER::@962 Next
PKSFILTER Filter
Definition: kstypes.h:73
PKSPIN Pin
Definition: kstypes.h:74
KSOBJECTTYPE Type
Definition: kstypes.h:56
PKSFILTERFACTORY FilterFactory
Definition: kstypes.h:72
union KSBASIC_HEADER::@963 FirstChild
LONGLONG Alignment
Definition: ks.h:256
PVOID ObjectType
Definition: kstypes.h:30
KSOBJECTTYPE Type
Definition: kstypes.h:23
PUNKNOWN Unknown
Definition: kstypes.h:29
ULONG Count
Definition: ks.h:1980
ULONG CurrentCount
Definition: ks.h:652
ULONG PossibleCount
Definition: ks.h:651
ULONG PinId
Definition: ks.h:2603
Definition: ks.h:2074
ULONG NodeId
Definition: ks.h:2076
Definition: ks.h:642
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: typedefs.h:120
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define LL
Definition: tui.h:150
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052
_In_ PWDFDEVICE_INIT _In_ PWDF_PDO_EVENT_CALLBACKS DispatchTable
Definition: wdfpdo.h:248
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
KSDDKAPI NTSTATUS NTAPI KsQueueWorkItem(IN PKSWORKER Worker, IN PWORK_QUEUE_ITEM WorkItem)
Definition: worker.c:252
KSDDKAPI VOID NTAPI KsUnregisterWorker(IN PKSWORKER Worker)
Definition: worker.c:128
KSDDKAPI NTSTATUS NTAPI KsRegisterCountedWorker(IN WORK_QUEUE_TYPE WorkQueueType, IN PWORK_QUEUE_ITEM CountedWorkItem, OUT PKSWORKER *Worker)
Definition: worker.c:166
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ HyperCriticalWorkQueue
Definition: extypes.h:191
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998
@ Executive
Definition: ketypes.h:415