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