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