[HEADERS]
[reactos.git] / reactos / drivers / multimedia / bdasup / bdasup.c
1
2 #include "precomp.h"
3
4 const GUID KSPROPSETID_BdaPinControl = {0xded49d5, 0xa8b7, 0x4d5d, {0x97, 0xa1, 0x12, 0xb0, 0xc1, 0x95, 0x87, 0x4d}};
5 const GUID KSMETHODSETID_BdaDeviceConfiguration = {0x71985f45, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
6 const GUID KSPROPSETID_BdaTopology = {0xa14ee835, 0x0a23, 0x11d3, {0x9c, 0xc7, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
7
8 BDA_GLOBAL g_Settings =
9 {
10 0,
11 0,
12 {NULL, NULL}
13 };
14
15 KSPROPERTY_ITEM FilterPropertyItem[] =
16 {
17 DEFINE_KSPROPERTY_ITEM_BDA_NODE_TYPES(BdaPropertyNodeTypes, NULL),
18 DEFINE_KSPROPERTY_ITEM_BDA_PIN_TYPES( BdaPropertyPinTypes, NULL),
19 DEFINE_KSPROPERTY_ITEM_BDA_TEMPLATE_CONNECTIONS(BdaPropertyTemplateConnections, NULL),
20 DEFINE_KSPROPERTY_ITEM_BDA_NODE_METHODS(BdaPropertyNodeMethods, NULL),
21 DEFINE_KSPROPERTY_ITEM_BDA_NODE_PROPERTIES(BdaPropertyNodeProperties, NULL),
22 DEFINE_KSPROPERTY_ITEM_BDA_NODE_EVENTS(BdaPropertyNodeEvents, NULL),
23 DEFINE_KSPROPERTY_ITEM_BDA_CONTROLLING_PIN_ID(BdaPropertyGetControllingPinId, NULL),
24 DEFINE_KSPROPERTY_ITEM_BDA_NODE_DESCRIPTORS(BdaPropertyNodeDescriptors, NULL)
25 };
26
27
28 KSPROPERTY_SET FilterPropertySet =
29 {
30 &KSPROPSETID_BdaTopology,
31 8,
32 FilterPropertyItem,
33 0,
34 NULL
35 };
36
37 KSMETHOD_ITEM FilterMethodItem[] =
38 {
39 //DEFINE_KSMETHOD_ITEM_BDA_CREATE_PIN_FACTORY(BdaMethodCreatePin, NULL),
40 DEFINE_KSMETHOD_ITEM_BDA_CREATE_TOPOLOGY(BdaMethodCreateTopology, NULL)
41 };
42
43 KSMETHOD_SET FilterMethodSet =
44 {
45 &KSMETHODSETID_BdaDeviceConfiguration,
46 2,
47 FilterMethodItem,
48 0,
49 NULL
50 };
51
52 KSAUTOMATION_TABLE FilterAutomationTable =
53 {
54 1,
55 sizeof(KSPROPERTY_SET),
56 &FilterPropertySet,
57 1,
58 sizeof(KSMETHOD_SET),
59 &FilterMethodSet,
60 0,
61 sizeof(KSEVENT_SET),
62 NULL
63 };
64
65 KSPROPERTY_ITEM PinPropertyItem[] =
66 {
67 DEFINE_KSPROPERTY_ITEM_BDA_PIN_ID(BdaPropertyGetPinControl, NULL),
68 DEFINE_KSPROPERTY_ITEM_BDA_PIN_TYPE(BdaPropertyGetPinControl, NULL)
69 };
70
71 KSPROPERTY_SET PinPropertySet =
72 {
73 &KSPROPSETID_BdaPinControl,
74 2,
75 PinPropertyItem,
76 0,
77 NULL
78 };
79
80 KSAUTOMATION_TABLE PinAutomationTable =
81 {
82 1,
83 sizeof(KSPROPERTY_SET),
84 &PinPropertySet,
85 0,
86 sizeof(KSMETHOD_SET),
87 NULL,
88 0,
89 sizeof(KSEVENT_SET),
90 NULL
91 };
92
93
94 PVOID
95 AllocateItem(
96 IN POOL_TYPE PoolType,
97 IN SIZE_T NumberOfBytes)
98 {
99 PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
100 if (!Item)
101 return Item;
102
103 RtlZeroMemory(Item, NumberOfBytes);
104 return Item;
105 }
106
107 VOID
108 FreeItem(
109 IN PVOID Item)
110 {
111 ExFreePool(Item);
112 }
113
114
115 PBDA_FILTER_INSTANCE_ENTRY
116 GetFilterInstanceEntry(
117 IN PKSFILTERFACTORY FilterFactory)
118 {
119 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry = NULL;
120 PLIST_ENTRY Entry;
121 KIRQL OldLevel;
122
123 /* acquire list lock */
124 KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
125
126 /* point to first entry */
127 Entry = g_Settings.FilterFactoryInstanceList.Flink;
128
129 while(Entry != &g_Settings.FilterFactoryInstanceList)
130 {
131 /* get instance entry from list entry offset */
132 InstanceEntry = (PBDA_FILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BDA_FILTER_INSTANCE_ENTRY, Entry);
133
134 /* is the instance entry the requested one */
135 if (InstanceEntry->FilterFactoryInstance == FilterFactory)
136 break;
137
138 /* move to next entry */
139 Entry = Entry->Flink;
140 /* set to null as it has not been found */
141 InstanceEntry = NULL;
142 }
143
144
145 /* release spin lock */
146 KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
147
148 /* return result */
149 return InstanceEntry;
150 }
151
152 /*
153 @implemented
154 */
155 NTSTATUS
156 NTAPI
157 DllInitialize(
158 PUNICODE_STRING RegistryPath)
159 {
160 KeInitializeSpinLock(&g_Settings.FilterFactoryInstanceListLock);
161 InitializeListHead(&g_Settings.FilterFactoryInstanceList);
162 g_Settings.Initialized = TRUE;
163
164 return STATUS_SUCCESS;
165 }
166
167 /*
168 @implemented
169 */
170 NTSTATUS
171 NTAPI
172 BdaCheckChanges(IN PIRP Irp)
173 {
174 if (!Irp)
175 return STATUS_INVALID_PARAMETER;
176
177 return STATUS_SUCCESS;
178 }
179
180 /*
181 @implemented
182 */
183 NTSTATUS
184 NTAPI
185 BdaCommitChanges(IN PIRP Irp)
186 {
187 if (!Irp)
188 return STATUS_INVALID_PARAMETER;
189
190 return STATUS_SUCCESS;
191 }
192
193 /*
194 @implemented
195 */
196 NTSTATUS
197 NTAPI
198 BdaCreateFilterFactory(
199 IN PKSDEVICE pKSDevice,
200 IN const KSFILTER_DESCRIPTOR *pFilterDescriptor,
201 IN const BDA_FILTER_TEMPLATE *pBdaFilterTemplate)
202 {
203 return BdaCreateFilterFactoryEx(pKSDevice, pFilterDescriptor, pBdaFilterTemplate, NULL);
204 }
205
206 VOID
207 NTAPI
208 FreeFilterInstance(
209 IN PVOID Context)
210 {
211 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry = NULL;
212 PLIST_ENTRY Entry;
213 KIRQL OldLevel;
214
215 /* acquire list lock */
216 KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
217
218 /* point to first entry */
219 Entry = g_Settings.FilterFactoryInstanceList.Flink;
220
221 while(Entry != &g_Settings.FilterFactoryInstanceList)
222 {
223 /* get instance entry from list entry offset */
224 InstanceEntry = (PBDA_FILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BDA_FILTER_INSTANCE_ENTRY, Entry);
225
226 /* is the instance entry the requested one */
227 if (InstanceEntry == (PBDA_FILTER_INSTANCE_ENTRY)Context)
228 {
229 RemoveEntryList(&InstanceEntry->Entry);
230 FreeItem(InstanceEntry);
231 break;
232 }
233
234 /* move to next entry */
235 Entry = Entry->Flink;
236 }
237
238 /* release spin lock */
239 KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
240 }
241
242
243 /*
244 @implemented
245 */
246 NTSTATUS
247 NTAPI
248 BdaCreateFilterFactoryEx(
249 IN PKSDEVICE pKSDevice,
250 IN const KSFILTER_DESCRIPTOR *pFilterDescriptor,
251 IN const BDA_FILTER_TEMPLATE *BdaFilterTemplate,
252 OUT PKSFILTERFACTORY *ppKSFilterFactory)
253 {
254 PKSFILTERFACTORY FilterFactory;
255 PBDA_FILTER_INSTANCE_ENTRY FilterInstance;
256 KIRQL OldLevel;
257 NTSTATUS Status;
258 KSFILTER_DESCRIPTOR FilterDescriptor;
259
260 /* backup filter descriptor */
261 RtlMoveMemory(&FilterDescriptor, pFilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
262
263 /* merge the automation tables */
264 Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&FilterDescriptor.AutomationTable, (PKSAUTOMATION_TABLE)pFilterDescriptor->AutomationTable, &FilterAutomationTable, NULL);
265
266 /* check for success */
267 if (!NT_SUCCESS(Status))
268 return Status;
269
270 /* allocate filter instance */
271 FilterInstance = AllocateItem(NonPagedPool, sizeof(BDA_FILTER_INSTANCE_ENTRY));
272 if (!FilterInstance)
273 {
274 /* not enough memory */
275 return STATUS_INSUFFICIENT_RESOURCES;
276 }
277
278 /* create the filter factory */
279 Status = KsCreateFilterFactory(pKSDevice->FunctionalDeviceObject, &FilterDescriptor, NULL, NULL, 0, NULL, NULL, &FilterFactory);
280
281 /* check for success */
282 if (NT_SUCCESS(Status))
283 {
284
285 /* add the item to filter object bag */
286 Status = KsAddItemToObjectBag(FilterFactory->Bag, FilterInstance, FreeFilterInstance);
287 if (!NT_SUCCESS(Status))
288 {
289 /* destroy filter instance */
290 FreeItem(FilterInstance);
291 KsDeleteFilterFactory(FilterFactory);
292 return Status;
293 }
294
295 /* initialize filter instance entry */
296 FilterInstance->FilterFactoryInstance = FilterFactory;
297 FilterInstance->FilterTemplate = (BDA_FILTER_TEMPLATE *)BdaFilterTemplate;
298
299 /* acquire list lock */
300 KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
301
302 /* insert factory at the end */
303 InsertTailList(&g_Settings.FilterFactoryInstanceList, &FilterInstance->Entry);
304
305 /* release spin lock */
306 KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
307
308
309 if (ppKSFilterFactory)
310 {
311 /* store result */
312 *ppKSFilterFactory = FilterFactory;
313 }
314 }
315 else
316 {
317 /* failed to create filter factory */
318 FreeItem(FilterInstance);
319 }
320
321 /* done */
322 return Status;
323 }
324
325 /*
326 @implemented
327 */
328 NTSTATUS
329 NTAPI
330 BdaCreatePin(
331 IN PKSFILTER pKSFilter,
332 IN ULONG ulPinType,
333 OUT ULONG *pulPinId)
334 {
335 PKSPIN_DESCRIPTOR_EX PinDescriptor;
336 PKSFILTERFACTORY FilterFactory;
337 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
338 NTSTATUS Status;
339 ULONG PinId;
340 KSPIN_DESCRIPTOR_EX NewPinDescriptor;
341
342 if (!pulPinId || !pKSFilter)
343 return STATUS_INVALID_PARAMETER;
344
345 /* get parent filter factory */
346 FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
347
348 /* sanity check */
349 ASSERT(FilterFactory);
350
351 /* find instance entry */
352 InstanceEntry = GetFilterInstanceEntry(FilterFactory);
353
354 if (!InstanceEntry)
355 {
356 /* the filter was not initialized with BDA */
357 return STATUS_NOT_FOUND;
358 }
359
360 /* sanity checks */
361 ASSERT(InstanceEntry->FilterTemplate);
362 ASSERT(InstanceEntry->FilterTemplate->pFilterDescriptor);
363
364 /* does the filter support any pins */
365 if (!InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount)
366 {
367 /* no pins supported */
368 return STATUS_UNSUCCESSFUL;
369 }
370
371 /* is pin factory still existing */
372 if (InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount <= ulPinType)
373 {
374 /* pin request is out of bounds */
375 return STATUS_INVALID_PARAMETER;
376 }
377
378 /* FIXME custom pin descriptors */
379 ASSERT(InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
380
381 /* get pin descriptor */
382 PinDescriptor = (PKSPIN_DESCRIPTOR_EX)&InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptors[ulPinType];
383
384 /* make a copy of the pin descriptor */
385 RtlMoveMemory(&NewPinDescriptor, PinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
386
387 /* merge the automation tables */
388 Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&NewPinDescriptor.AutomationTable, (PKSAUTOMATION_TABLE)PinDescriptor->AutomationTable, &PinAutomationTable, pKSFilter->Bag);
389
390 /* check for success */
391 if (NT_SUCCESS(Status))
392 {
393 /* create the pin factory */
394 Status = KsFilterCreatePinFactory(pKSFilter, &NewPinDescriptor, &PinId);
395
396 /* check for success */
397 if (NT_SUCCESS(Status))
398 {
399 /* store result */
400 *pulPinId = PinId;
401 }
402 }
403
404
405 DPRINT("BdaCreatePin Result %x\n", Status);
406 return Status;
407 }
408
409 /*
410 @implemented
411 */
412 NTSTATUS
413 NTAPI
414 BdaMethodCreatePin(
415 IN PIRP Irp,
416 IN KSMETHOD *pKSMethod,
417 OUT ULONG *pulPinFactoryID)
418 {
419 PKSM_PIN Pin;
420 PKSFILTER Filter;
421
422 if (!Irp)
423 {
424 /* invalid parameter */
425 return STATUS_INVALID_PARAMETER;
426 }
427
428 /* get filter from irp */
429 Filter = KsGetFilterFromIrp(Irp);
430
431 /* sanity check */
432 ASSERT(Filter);
433 ASSERT(pKSMethod);
434
435 /* get method request */
436 Pin = (PKSM_PIN)pKSMethod;
437
438 /* create the pin */
439 return BdaCreatePin(Filter, Pin->PinId, pulPinFactoryID);
440 }
441
442 /*
443 @implemented
444 */
445 NTSTATUS
446 NTAPI
447 BdaInitFilter(
448 IN PKSFILTER pKSFilter,
449 IN const BDA_FILTER_TEMPLATE *pBdaFilterTemplate)
450 {
451 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
452 PKSFILTERFACTORY FilterFactory;
453 ULONG Index, PinId;
454 NTSTATUS Status = STATUS_SUCCESS;
455
456 /* check input parameters */
457 if (!pKSFilter)
458 return STATUS_INVALID_PARAMETER;
459
460 /* get parent filter factory */
461 FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
462
463 /* sanity check */
464 ASSERT(FilterFactory);
465
466 /* find instance entry */
467 InstanceEntry = GetFilterInstanceEntry(FilterFactory);
468
469 /* sanity check */
470 ASSERT(InstanceEntry);
471 ASSERT(InstanceEntry->FilterTemplate == pBdaFilterTemplate);
472
473 /* now create the pins */
474 for(Index = 0; Index < pBdaFilterTemplate->pFilterDescriptor->PinDescriptorsCount; Index++)
475 {
476 /* create the pin */
477 Status = BdaCreatePin(pKSFilter, Index, &PinId);
478
479 /* check for success */
480 if (!NT_SUCCESS(Status))
481 break;
482 }
483
484 /* done */
485 return Status;
486 }
487
488
489
490 /*
491 @implemented
492 */
493 NTSTATUS
494 NTAPI
495 BdaCreateTopology(
496 IN PKSFILTER pKSFilter,
497 IN ULONG InputPinId,
498 IN ULONG OutputPinId)
499 {
500 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
501 PKSFILTERFACTORY FilterFactory;
502 KSTOPOLOGY_CONNECTION Connection;
503
504 /* check input parameters */
505 if (!pKSFilter)
506 return STATUS_INVALID_PARAMETER;
507
508 /* get parent filter factory */
509 FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
510
511 /* sanity check */
512 ASSERT(FilterFactory);
513
514 /* find instance entry */
515 InstanceEntry = GetFilterInstanceEntry(FilterFactory);
516
517 if (!InstanceEntry)
518 {
519 /* the filter was not initialized with BDA */
520 return STATUS_NOT_FOUND;
521 }
522
523 if (InputPinId >= InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount ||
524 OutputPinId >= InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount)
525 {
526 /* invalid pin id */
527 return STATUS_INVALID_PARAMETER;
528 }
529
530 /* initialize topology connection */
531 Connection.FromNode = KSFILTER_NODE;
532 Connection.ToNode = KSFILTER_NODE;
533 Connection.FromNodePin = InputPinId;
534 Connection.ToNodePin = OutputPinId;
535
536 /* add the connection */
537 return KsFilterAddTopologyConnections(pKSFilter, 1, &Connection);
538 }
539
540 /*
541 @unimplemented
542 */
543 NTSTATUS
544 NTAPI
545 BdaDeletePin(
546 IN PKSFILTER pKSFilter,
547 IN ULONG *pulPinId)
548 {
549 UNIMPLEMENTED
550 return STATUS_NOT_IMPLEMENTED;
551 }
552
553 /*
554 @implemented
555 */
556 NTSTATUS
557 NTAPI
558 BdaFilterFactoryUpdateCacheData(
559 IN PKSFILTERFACTORY FilterFactory,
560 IN const KSFILTER_DESCRIPTOR *FilterDescriptor OPTIONAL)
561 {
562 return KsFilterFactoryUpdateCacheData(FilterFactory, FilterDescriptor);
563 }
564
565 /*
566 @implemented
567 */
568 NTSTATUS
569 NTAPI
570 BdaGetChangeState(
571 IN PIRP Irp,
572 OUT BDA_CHANGE_STATE *ChangeState)
573 {
574 if (Irp && ChangeState)
575 {
576 *ChangeState = BDA_CHANGES_COMPLETE;
577 return STATUS_SUCCESS;
578 }
579
580 /* invalid parameters supplied */
581 return STATUS_INVALID_PARAMETER;
582
583 }
584
585 /*
586 @implemented
587 */
588 NTSTATUS
589 NTAPI
590 BdaMethodCreateTopology(
591 IN PIRP Irp,
592 IN KSMETHOD *pKSMethod,
593 OPTIONAL PVOID pvIgnored)
594 {
595 PKSFILTER Filter;
596 PKSP_BDA_NODE_PIN Node;
597
598 /* check input parameters */
599 if (!Irp || !pKSMethod)
600 return STATUS_INVALID_PARAMETER;
601
602 /* get filter */
603 Filter = KsGetFilterFromIrp(Irp);
604
605 /* sanity check */
606 ASSERT(Filter);
607
608 /* get method request */
609 Node = (PKSP_BDA_NODE_PIN)pKSMethod;
610
611 /* create the topology */
612 return BdaCreateTopology(Filter, Node->ulInputPinId, Node->ulOutputPinId);
613 }
614
615 /*
616 @implemented
617 */
618 NTSTATUS
619 NTAPI
620 BdaMethodDeletePin(
621 IN PIRP Irp,
622 IN KSMETHOD *pKSMethod,
623 OPTIONAL PVOID pvIgnored)
624 {
625 if (!Irp)
626 return STATUS_INVALID_PARAMETER;
627
628 return STATUS_SUCCESS;
629 }
630
631 /*
632 @unimplemented
633 */
634 NTSTATUS
635 NTAPI
636 BdaPropertyGetControllingPinId(
637 IN PIRP Irp,
638 IN KSP_BDA_NODE_PIN *pProperty,
639 OUT ULONG *pulControllingPinId)
640 {
641 UNIMPLEMENTED
642 return STATUS_NOT_IMPLEMENTED;
643 }
644
645 /*
646 @implemented
647 */
648 NTSTATUS
649 NTAPI
650 BdaPropertyGetPinControl(
651 IN PIRP Irp,
652 IN KSPROPERTY *pKSProperty,
653 OUT ULONG *pulProperty)
654 {
655 PKSPIN Pin;
656 PKSFILTER Filter;
657 PKSFILTERFACTORY FilterFactory;
658 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
659
660 /* first get the pin */
661 Pin = KsGetPinFromIrp(Irp);
662 ASSERT(Pin);
663
664 /* now get the parent filter */
665 Filter = KsPinGetParentFilter(Pin);
666 ASSERT(Filter);
667
668 /* get parent filter factory */
669 FilterFactory = KsFilterGetParentFilterFactory(Filter);
670 ASSERT(FilterFactory);
671
672 /* find instance entry */
673 InstanceEntry = GetFilterInstanceEntry(FilterFactory);
674 ASSERT(InstanceEntry);
675
676 /* sanity check */
677 pKSProperty++;
678 ASSERT(pKSProperty->Id == KSPROPERTY_BDA_PIN_TYPE);
679
680 /* store pin id */
681 *pulProperty = Pin->Id;
682
683 return STATUS_SUCCESS;
684 }
685
686 /*
687 @unimplemented
688 */
689 NTSTATUS
690 NTAPI
691 BdaPropertyNodeDescriptors(
692 IN PIRP Irp,
693 IN KSPROPERTY *pKSProperty,
694 OUT BDANODE_DESCRIPTOR *pNodeDescriptorProperty)
695 {
696 UNIMPLEMENTED
697 return STATUS_NOT_IMPLEMENTED;
698 }
699
700 /*
701 @unimplemented
702 */
703 NTSTATUS
704 NTAPI
705 BdaPropertyNodeEvents(
706 IN PIRP Irp,
707 IN KSP_NODE *pKSProperty,
708 OUT GUID *pguidProperty)
709 {
710 UNIMPLEMENTED
711 return STATUS_NOT_IMPLEMENTED;
712 }
713
714 /*
715 @unimplemented
716 */
717 NTSTATUS
718 NTAPI
719 BdaPropertyNodeMethods(
720 IN PIRP Irp,
721 IN KSP_NODE *pKSProperty,
722 OUT GUID *pguidProperty)
723 {
724 UNIMPLEMENTED
725 return STATUS_NOT_IMPLEMENTED;
726 }
727
728 /*
729 @unimplemented
730 */
731 NTSTATUS
732 NTAPI
733 BdaPropertyNodeProperties(
734 IN PIRP Irp,
735 IN KSP_NODE *pKSProperty,
736 OUT GUID *pguidProperty)
737 {
738 UNIMPLEMENTED
739 return STATUS_NOT_IMPLEMENTED;
740 }
741
742 /*
743 @implemented
744 */
745 NTSTATUS
746 NTAPI
747 BdaPropertyNodeTypes(
748 IN PIRP Irp,
749 IN KSPROPERTY *pKSProperty,
750 OUT ULONG *pulProperty)
751 {
752 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
753 PKSFILTERFACTORY FilterFactory;
754 PKSFILTER pKSFilter;
755 PIO_STACK_LOCATION IoStack;
756 ULONG Index;
757
758 /* check input parameter */
759 if (!Irp || !pKSProperty)
760 return STATUS_INVALID_PARAMETER;
761
762 /* first get the filter */
763 pKSFilter = KsGetFilterFromIrp(Irp);
764
765 /* sanity check */
766 ASSERT(pKSFilter);
767
768 /* get parent filter factory */
769 FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
770
771 /* sanity check */
772 ASSERT(FilterFactory);
773
774 /* find instance entry */
775 InstanceEntry = GetFilterInstanceEntry(FilterFactory);
776 ASSERT(InstanceEntry);
777
778 /* get current irp stack */
779 IoStack = IoGetCurrentIrpStackLocation(Irp);
780
781 /* are there node types provided */
782 if (!pulProperty)
783 {
784 /* no node entry array provided */
785 Irp->IoStatus.Information = InstanceEntry->FilterTemplate->pFilterDescriptor->NodeDescriptorsCount * sizeof(ULONG);
786 Irp->IoStatus.Status = STATUS_MORE_ENTRIES;
787 return STATUS_MORE_ENTRIES;
788 }
789
790 if (InstanceEntry->FilterTemplate->pFilterDescriptor->NodeDescriptorsCount * sizeof(ULONG) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
791 {
792 /* buffer too small */
793 Irp->IoStatus.Information = InstanceEntry->FilterTemplate->pFilterDescriptor->NodeDescriptorsCount * sizeof(ULONG);
794 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
795 return STATUS_BUFFER_TOO_SMALL;
796 }
797
798 /* now copy all descriptors */
799 for(Index = 0; Index < InstanceEntry->FilterTemplate->pFilterDescriptor->NodeDescriptorsCount; Index++)
800 {
801 /* use the index as the type */
802 pulProperty[Index] = Index;
803 }
804
805 return STATUS_SUCCESS;
806 }
807
808 /*
809 @implemented
810 */
811 NTSTATUS
812 NTAPI
813 BdaPropertyPinTypes(
814 IN PIRP Irp,
815 IN KSPROPERTY *pKSProperty,
816 OUT ULONG *pulProperty)
817 {
818 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
819 PKSFILTERFACTORY FilterFactory;
820 PKSFILTER pKSFilter;
821 PIO_STACK_LOCATION IoStack;
822 ULONG Index;
823
824 /* check input parameter */
825 if (!Irp || !pKSProperty)
826 return STATUS_INVALID_PARAMETER;
827
828 /* first get the filter */
829 pKSFilter = KsGetFilterFromIrp(Irp);
830
831 /* sanity check */
832 ASSERT(pKSFilter);
833
834 /* get parent filter factory */
835 FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
836
837 /* sanity check */
838 ASSERT(FilterFactory);
839
840 /* find instance entry */
841 InstanceEntry = GetFilterInstanceEntry(FilterFactory);
842 ASSERT(InstanceEntry);
843
844 /* get current irp stack */
845 IoStack = IoGetCurrentIrpStackLocation(Irp);
846
847 /* are there node types provided */
848 if (!pKSProperty)
849 {
850 /* no node entry array provided */
851 Irp->IoStatus.Information = InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount * sizeof(ULONG);
852 Irp->IoStatus.Status = STATUS_MORE_ENTRIES;
853 return STATUS_MORE_ENTRIES;
854 }
855
856 if (InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount * sizeof(ULONG) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
857 {
858 /* buffer too small */
859 Irp->IoStatus.Information = InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount * sizeof(ULONG);
860 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
861 return STATUS_BUFFER_TOO_SMALL;
862 }
863
864 /* now copy all descriptors */
865 for(Index = 0; Index < InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount; Index++)
866 {
867 /* use the index as the type */
868 pulProperty[Index] = Index;
869 }
870
871 return STATUS_SUCCESS;
872 }
873
874 /*
875 @implemented
876 */
877 NTSTATUS
878 NTAPI
879 BdaPropertyTemplateConnections(
880 IN PIRP Irp,
881 IN KSPROPERTY *pKSProperty,
882 OUT KSTOPOLOGY_CONNECTION *pConnectionProperty)
883 {
884 PBDA_FILTER_INSTANCE_ENTRY FilterInstance;
885 PKSFILTER Filter;
886 PIO_STACK_LOCATION IoStack;
887 ULONG Index;
888
889 /* validate parameters */
890 if (!Irp || !pKSProperty)
891 return STATUS_INVALID_PARAMETER;
892
893 /* first get the filter */
894 Filter = KsGetFilterFromIrp(Irp);
895
896 /* sanity check */
897 ASSERT(Filter);
898
899 /* verify filter has been registered with BDA */
900 FilterInstance = GetFilterInstanceEntry(KsFilterGetParentFilterFactory(Filter));
901
902 if (!FilterInstance)
903 return STATUS_INVALID_PARAMETER;
904
905 /* get current irp stack */
906 IoStack = IoGetCurrentIrpStackLocation(Irp);
907
908 if (!pConnectionProperty)
909 {
910 /* caller needs the size first */
911 Irp->IoStatus.Information = FilterInstance->FilterTemplate->pFilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION);
912 Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
913 return STATUS_BUFFER_OVERFLOW;
914 }
915
916 /* sanity check */
917 ASSERT(FilterInstance->FilterTemplate->pFilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION) <= IoStack->Parameters.DeviceIoControl.OutputBufferLength);
918
919 for(Index = 0; Index < FilterInstance->FilterTemplate->pFilterDescriptor->ConnectionsCount; Index++)
920 {
921 /* sanity check */
922 ASSERT(FilterInstance->FilterTemplate->pFilterDescriptor->Connections);
923
924 /* copy connection */
925 RtlMoveMemory(pConnectionProperty, &FilterInstance->FilterTemplate->pFilterDescriptor->Connections[Index], sizeof(KSTOPOLOGY_CONNECTION));
926 }
927
928 /* store result */
929 Irp->IoStatus.Information = FilterInstance->FilterTemplate->pFilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION);
930 Irp->IoStatus.Status = STATUS_SUCCESS;
931
932 /* done */
933 return STATUS_SUCCESS;
934
935 }
936
937 /*
938 @implemented
939 */
940 NTSTATUS
941 NTAPI
942 BdaStartChanges(IN PIRP Irp)
943 {
944 if (Irp)
945 return STATUS_SUCCESS;
946 else
947 return STATUS_INVALID_PARAMETER;
948
949 }
950
951 /*
952 @implemented
953 */
954 NTSTATUS
955 NTAPI
956 BdaUninitFilter(IN PKSFILTER pKSFilter)
957 {
958 return STATUS_SUCCESS;
959 }
960
961 /*
962 @implemented
963 */
964 NTSTATUS
965 NTAPI
966 BdaValidateNodeProperty(
967 IN PIRP Irp,
968 IN KSPROPERTY *KSProperty)
969 {
970 /* check for valid parameter */
971 if (Irp && KSProperty)
972 return STATUS_SUCCESS;
973
974 return STATUS_INVALID_PARAMETER;
975 }