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