1
2 #include "precomp.h"
3
4 #define TAG_BDASUP 'SadB'
5
6 const GUID KSPROPSETID_BdaPinControl = {0xded49d5, 0xa8b7, 0x4d5d, {0x97, 0xa1, 0x12, 0xb0, 0xc1, 0x95, 0x87, 0x4d}};
7 const GUID KSMETHODSETID_BdaDeviceConfiguration = {0x71985f45, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
8 const GUID KSPROPSETID_BdaTopology = {0xa14ee835, 0x0a23, 0x11d3, {0x9c, 0xc7, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
9
10 BDA_GLOBAL g_Settings =
11 {
12 0,
13 0,
14 {NULL, NULL}
15 };
16
17 KSPROPERTY_ITEM FilterPropertyItem[] =
18 {
19 DEFINE_KSPROPERTY_ITEM_BDA_NODE_TYPES(BdaPropertyNodeTypes, NULL),
20 DEFINE_KSPROPERTY_ITEM_BDA_PIN_TYPES( BdaPropertyPinTypes, NULL),
21 DEFINE_KSPROPERTY_ITEM_BDA_TEMPLATE_CONNECTIONS(BdaPropertyTemplateConnections, NULL),
22 DEFINE_KSPROPERTY_ITEM_BDA_NODE_METHODS(BdaPropertyNodeMethods, NULL),
23 DEFINE_KSPROPERTY_ITEM_BDA_NODE_PROPERTIES(BdaPropertyNodeProperties, NULL),
24 DEFINE_KSPROPERTY_ITEM_BDA_NODE_EVENTS(BdaPropertyNodeEvents, NULL),
25 DEFINE_KSPROPERTY_ITEM_BDA_CONTROLLING_PIN_ID(BdaPropertyGetControllingPinId, NULL),
26 DEFINE_KSPROPERTY_ITEM_BDA_NODE_DESCRIPTORS(BdaPropertyNodeDescriptors, NULL)
27 };
28
29 KSPROPERTY_SET FilterPropertySet =
30 {
31 &KSPROPSETID_BdaTopology,
32 8,
33 FilterPropertyItem,
34 0,
35 NULL
36 };
37
38 KSMETHOD_ITEM FilterMethodItem[] =
39 {
40 //DEFINE_KSMETHOD_ITEM_BDA_CREATE_PIN_FACTORY(BdaMethodCreatePin, NULL),
41 DEFINE_KSMETHOD_ITEM_BDA_CREATE_TOPOLOGY(BdaMethodCreateTopology, NULL)
42 };
43
44 KSMETHOD_SET FilterMethodSet =
45 {
46 &KSMETHODSETID_BdaDeviceConfiguration,
47 2,
48 FilterMethodItem,
49 0,
50 NULL
51 };
52
53 KSAUTOMATION_TABLE FilterAutomationTable =
54 {
55 1,
56 sizeof(KSPROPERTY_ITEM),
57 &FilterPropertySet,
58 1,
59 sizeof(KSMETHOD_ITEM),
60 &FilterMethodSet,
61 0,
62 sizeof(KSEVENT_ITEM),
63 NULL
64 };
65
66 KSPROPERTY_ITEM PinPropertyItem[] =
67 {
68 DEFINE_KSPROPERTY_ITEM_BDA_PIN_ID(BdaPropertyGetPinControl, NULL),
69 DEFINE_KSPROPERTY_ITEM_BDA_PIN_TYPE(BdaPropertyGetPinControl, NULL)
70 };
71
72 KSPROPERTY_SET PinPropertySet =
73 {
74 &KSPROPSETID_BdaPinControl,
75 2,
76 PinPropertyItem,
77 0,
78 NULL
79 };
80
81 KSAUTOMATION_TABLE PinAutomationTable =
82 {
83 1,
84 sizeof(KSPROPERTY_ITEM),
85 &PinPropertySet,
86 0,
87 sizeof(KSMETHOD_ITEM),
88 NULL,
89 0,
90 sizeof(KSEVENT_ITEM),
91 NULL
92 };
93
94 PVOID
AllocateItem(IN POOL_TYPE PoolType,IN SIZE_T NumberOfBytes)95 AllocateItem(
96 IN POOL_TYPE PoolType,
97 IN SIZE_T NumberOfBytes)
98 {
99 return ExAllocatePoolZero(PoolType, NumberOfBytes, TAG_BDASUP);
100 }
101
102 VOID
FreeItem(IN PVOID Item)103 FreeItem(
104 IN PVOID Item)
105 {
106 ExFreePoolWithTag(Item, TAG_BDASUP);
107 }
108
109 PBDA_FILTER_INSTANCE_ENTRY
GetFilterInstanceEntry(IN PKSFILTERFACTORY FilterFactory)110 GetFilterInstanceEntry(
111 IN PKSFILTERFACTORY FilterFactory)
112 {
113 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry = NULL;
114 PLIST_ENTRY Entry;
115 KIRQL OldLevel;
116
117 /* acquire list lock */
118 KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
119
120 /* point to first entry */
121 Entry = g_Settings.FilterFactoryInstanceList.Flink;
122
123 while(Entry != &g_Settings.FilterFactoryInstanceList)
124 {
125 /* get instance entry from list entry offset */
126 InstanceEntry = (PBDA_FILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BDA_FILTER_INSTANCE_ENTRY, Entry);
127
128 /* is the instance entry the requested one */
129 if (InstanceEntry->FilterFactoryInstance == FilterFactory)
130 break;
131
132 /* move to next entry */
133 Entry = Entry->Flink;
134 /* set to null as it has not been found */
135 InstanceEntry = NULL;
136 }
137
138 /* release spin lock */
139 KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
140
141 /* return result */
142 return InstanceEntry;
143 }
144
145 /*
146 @implemented
147 */
148 NTSTATUS
149 NTAPI
DllInitialize(PUNICODE_STRING RegistryPath)150 DllInitialize(
151 PUNICODE_STRING RegistryPath)
152 {
153 DPRINT("BDASUP::DllInitialize\n");
154
155 KeInitializeSpinLock(&g_Settings.FilterFactoryInstanceListLock);
156 InitializeListHead(&g_Settings.FilterFactoryInstanceList);
157 g_Settings.Initialized = TRUE;
158
159 return STATUS_SUCCESS;
160 }
161
162 /*
163 @implemented
164 */
165 NTSTATUS
166 NTAPI
BdaCheckChanges(IN PIRP Irp)167 BdaCheckChanges(IN PIRP Irp)
168 {
169 DPRINT("BdaCheckChanges\n");
170
171 if (!Irp)
172 return STATUS_INVALID_PARAMETER;
173
174 return STATUS_SUCCESS;
175 }
176
177 /*
178 @implemented
179 */
180 NTSTATUS
181 NTAPI
BdaCommitChanges(IN PIRP Irp)182 BdaCommitChanges(IN PIRP Irp)
183 {
184 DPRINT("BdaCommitChanges\n");
185
186 if (!Irp)
187 return STATUS_INVALID_PARAMETER;
188
189 return STATUS_SUCCESS;
190 }
191
192 /*
193 @implemented
194 */
195 NTSTATUS
196 NTAPI
BdaCreateFilterFactory(IN PKSDEVICE pKSDevice,IN const KSFILTER_DESCRIPTOR * pFilterDescriptor,IN const BDA_FILTER_TEMPLATE * pBdaFilterTemplate)197 BdaCreateFilterFactory(
198 IN PKSDEVICE pKSDevice,
199 IN const KSFILTER_DESCRIPTOR *pFilterDescriptor,
200 IN const BDA_FILTER_TEMPLATE *pBdaFilterTemplate)
201 {
202 return BdaCreateFilterFactoryEx(pKSDevice, pFilterDescriptor, pBdaFilterTemplate, NULL);
203 }
204
205 VOID
206 NTAPI
FreeFilterInstance(IN PVOID Context)207 FreeFilterInstance(
208 IN PVOID Context)
209 {
210 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry = NULL;
211 PLIST_ENTRY Entry;
212 KIRQL OldLevel;
213
214 /* acquire list lock */
215 KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
216
217 /* point to first entry */
218 Entry = g_Settings.FilterFactoryInstanceList.Flink;
219
220 while(Entry != &g_Settings.FilterFactoryInstanceList)
221 {
222 /* get instance entry from list entry offset */
223 InstanceEntry = (PBDA_FILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BDA_FILTER_INSTANCE_ENTRY, Entry);
224
225 /* is the instance entry the requested one */
226 if (InstanceEntry == (PBDA_FILTER_INSTANCE_ENTRY)Context)
227 {
228 RemoveEntryList(&InstanceEntry->Entry);
229 FreeItem(InstanceEntry);
230 break;
231 }
232
233 /* move to next entry */
234 Entry = Entry->Flink;
235 }
236
237 /* release spin lock */
238 KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
239 }
240
241 /*
242 @implemented
243 */
244 NTSTATUS
245 NTAPI
BdaCreateFilterFactoryEx(IN PKSDEVICE pKSDevice,IN const KSFILTER_DESCRIPTOR * pFilterDescriptor,IN const BDA_FILTER_TEMPLATE * BdaFilterTemplate,OUT PKSFILTERFACTORY * ppKSFilterFactory)246 BdaCreateFilterFactoryEx(
247 IN PKSDEVICE pKSDevice,
248 IN const KSFILTER_DESCRIPTOR *pFilterDescriptor,
249 IN const BDA_FILTER_TEMPLATE *BdaFilterTemplate,
250 OUT PKSFILTERFACTORY *ppKSFilterFactory)
251 {
252 PKSFILTERFACTORY FilterFactory;
253 PBDA_FILTER_INSTANCE_ENTRY FilterInstance;
254 KIRQL OldLevel;
255 NTSTATUS Status;
256 PKSFILTER_DESCRIPTOR FilterDescriptor;
257
258 DPRINT("BdaCreateFilterFactoryEx\n");
259
260 FilterDescriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR));
261 if (!FilterDescriptor)
262 {
263 /* no memory */
264 return STATUS_INSUFFICIENT_RESOURCES;
265 }
266
267 /* copy filter descriptor template */
268 RtlMoveMemory(FilterDescriptor, pFilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
269
270 /* erase pin / nodes / connections from filter descriptor */
271 FilterDescriptor->PinDescriptorsCount = 0;
272 FilterDescriptor->PinDescriptors = NULL;
273 FilterDescriptor->NodeDescriptorsCount = 0;
274 FilterDescriptor->NodeDescriptors = NULL;
275 FilterDescriptor->ConnectionsCount = 0;
276 FilterDescriptor->Connections = NULL;
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 if (FilterDescriptor->AutomationTable != &FilterAutomationTable)
305 {
306 /* add the item to filter object bag */
307 KsAddItemToObjectBag(FilterFactory->Bag, (PVOID)FilterDescriptor->AutomationTable, FreeFilterInstance);
308 }
309 else
310 {
311 /* make sure the automation table is not-read only */
312 Status = _KsEdit(FilterFactory->Bag, (PVOID*)&FilterDescriptor->AutomationTable, sizeof(KSAUTOMATION_TABLE), sizeof(KSAUTOMATION_TABLE), 0);
313
314 /* sanity check */
315 ASSERT(Status == STATUS_SUCCESS);
316
317 /* add to object bag */
318 KsAddItemToObjectBag(FilterFactory->Bag, (PVOID)FilterDescriptor->AutomationTable, FreeFilterInstance);
319 }
320
321 /* initialize filter instance entry */
322 FilterInstance->FilterFactoryInstance = FilterFactory;
323 FilterInstance->FilterTemplate = (BDA_FILTER_TEMPLATE *)BdaFilterTemplate;
324
325 /* acquire list lock */
326 KeAcquireSpinLock(&g_Settings.FilterFactoryInstanceListLock, &OldLevel);
327
328 /* insert factory at the end */
329 InsertTailList(&g_Settings.FilterFactoryInstanceList, &FilterInstance->Entry);
330
331 /* release spin lock */
332 KeReleaseSpinLock(&g_Settings.FilterFactoryInstanceListLock, OldLevel);
333
334 if (ppKSFilterFactory)
335 {
336 /* store result */
337 *ppKSFilterFactory = FilterFactory;
338 }
339 }
340 else
341 {
342 /* failed to create filter factory */
343 FreeItem(FilterInstance);
344 FreeItem(FilterDescriptor);
345 }
346
347 /* done */
348 DPRINT("BdaCreateFilterFactoryEx Status %x\n", Status);
349 return Status;
350 }
351
352 /*
353 @implemented
354 */
355 NTSTATUS
356 NTAPI
BdaCreatePin(IN PKSFILTER pKSFilter,IN ULONG ulPinType,OUT ULONG * pulPinId)357 BdaCreatePin(
358 IN PKSFILTER pKSFilter,
359 IN ULONG ulPinType,
360 OUT ULONG *pulPinId)
361 {
362 PKSPIN_DESCRIPTOR_EX PinDescriptor;
363 PKSFILTERFACTORY FilterFactory;
364 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
365 NTSTATUS Status;
366 ULONG PinId;
367 PKSPIN_DESCRIPTOR_EX NewPinDescriptor;
368
369 DPRINT("BdaCreatePin\n");
370
371 if (!pulPinId || !pKSFilter)
372 return STATUS_INVALID_PARAMETER;
373
374 /* get parent filter factory */
375 FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
376
377 /* sanity check */
378 ASSERT(FilterFactory);
379
380 /* find instance entry */
381 InstanceEntry = GetFilterInstanceEntry(FilterFactory);
382
383 if (!InstanceEntry)
384 {
385 /* the filter was not initialized with BDA */
386 return STATUS_NOT_FOUND;
387 }
388
389 /* sanity checks */
390 ASSERT(InstanceEntry->FilterTemplate);
391 ASSERT(InstanceEntry->FilterTemplate->pFilterDescriptor);
392
393 /* does the filter support any pins */
394 if (!InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount)
395 {
396 /* no pins supported */
397 DPRINT("BdaCreatePin NoPins supported\n");
398 return STATUS_UNSUCCESSFUL;
399 }
400
401 /* is pin factory still existing */
402 if (InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount <= ulPinType)
403 {
404 /* pin request is out of bounds */
405 DPRINT("BdaCreatePin ulPinType %lu >= PinDescriptorCount %lu\n", ulPinType, InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorsCount);
406 return STATUS_INVALID_PARAMETER;
407 }
408
409 /* FIXME custom pin descriptors */
410 ASSERT(InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX));
411
412 /* get pin descriptor */
413 PinDescriptor = (PKSPIN_DESCRIPTOR_EX)&InstanceEntry->FilterTemplate->pFilterDescriptor->PinDescriptors[ulPinType];
414
415 /* allocate pin descriptor */
416 NewPinDescriptor = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR_EX));
417 if (!NewPinDescriptor)
418 {
419 /* no memory */
420 DPRINT("BdaCreatePin OutOfMemory\n");
421 return STATUS_INSUFFICIENT_RESOURCES;
422 }
423
424 /* make a copy of the pin descriptor */
425 RtlMoveMemory(NewPinDescriptor, PinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX));
426
427 /* merge the automation tables */
428 Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&NewPinDescriptor->AutomationTable, (PKSAUTOMATION_TABLE)PinDescriptor->AutomationTable, &PinAutomationTable, pKSFilter->Bag);
429
430 /* check for success */
431 if (NT_SUCCESS(Status))
432 {
433 /* create the pin factory */
434 Status = KsFilterCreatePinFactory(pKSFilter, NewPinDescriptor, &PinId);
435
436 /* check for success */
437 if (NT_SUCCESS(Status))
438 {
439 /* store result */
440 *pulPinId = PinId;
441 }
442 }
443
444 DPRINT("BdaCreatePin Result %x PinId %u\n", Status, PinId);
445 return Status;
446 }
447
448 /*
449 @implemented
450 */
451 NTSTATUS
452 NTAPI
BdaMethodCreatePin(IN PIRP Irp,IN KSMETHOD * pKSMethod,OUT ULONG * pulPinFactoryID)453 BdaMethodCreatePin(
454 IN PIRP Irp,
455 IN KSMETHOD *pKSMethod,
456 OUT ULONG *pulPinFactoryID)
457 {
458 PKSM_PIN Pin;
459 PKSFILTER Filter;
460
461 DPRINT("BdaMethodCreatePin\n");
462
463 if (!Irp)
464 {
465 /* invalid parameter */
466 return STATUS_INVALID_PARAMETER;
467 }
468
469 /* get filter from irp */
470 Filter = KsGetFilterFromIrp(Irp);
471
472 /* sanity check */
473 ASSERT(Filter);
474 ASSERT(pKSMethod);
475
476 /* get method request */
477 Pin = (PKSM_PIN)pKSMethod;
478
479 /* create the pin */
480 return BdaCreatePin(Filter, Pin->PinId, pulPinFactoryID);
481 }
482
483 /*
484 @implemented
485 */
486 NTSTATUS
487 NTAPI
BdaInitFilter(IN PKSFILTER pKSFilter,IN const BDA_FILTER_TEMPLATE * pBdaFilterTemplate)488 BdaInitFilter(
489 IN PKSFILTER pKSFilter,
490 IN const BDA_FILTER_TEMPLATE *pBdaFilterTemplate)
491 {
492 PBDA_FILTER_INSTANCE_ENTRY InstanceEntry;
493 PKSFILTERFACTORY FilterFactory;
494 ULONG Index, PinId;
495 NTSTATUS Status = STATUS_SUCCESS;
496
497 DPRINT("BdaInitFilter %p\n", pBdaFilterTemplate);
498
499 /* check input parameters */
500 if (!pKSFilter)
501 return STATUS_INVALID_PARAMETER;
502
503 /* get parent filter factory */
504 FilterFactory = KsFilterGetParentFilterFactory(pKSFilter);
505
506 /* sanity check */
507 ASSERT(FilterFactory);
508
509 /* find instance entry */
510 InstanceEntry = GetFilterInstanceEntry(FilterFactory);
511
512 /* sanity check */
513 ASSERT(InstanceEntry);
514
515 if (!pBdaFilterTemplate)
516 {
517 /* use template from BdaCreateFilterFactoryEx */
518 pBdaFilterTemplate = InstanceEntry->FilterTemplate;
519 }
520
521 /* now create the pins */
522 for(Index = 0; Index < pBdaFilterTemplate->pFilterDescriptor->PinDescriptorsCount; Index++)
523 {
524 /* create the pin */
525 Status = BdaCreatePin(pKSFilter, Index, &PinId);
526
527 /* check for success */
528 if (!NT_SUCCESS(Status))
529 break;
530 }
531
532 /* done */
533 return Status;
534 }
535
536 /*
537 @implemented
538 */
539 NTSTATUS
540 NTAPI
BdaCreateTopology(IN PKSFILTER pKSFilter,IN ULONG InputPinId,IN ULONG OutputPinId)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
BdaDeletePin(IN PKSFILTER pKSFilter,IN ULONG * pulPinId)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
BdaFilterFactoryUpdateCacheData(IN PKSFILTERFACTORY FilterFactory,IN const KSFILTER_DESCRIPTOR * FilterDescriptor OPTIONAL)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
BdaGetChangeState(IN PIRP Irp,OUT BDA_CHANGE_STATE * ChangeState)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
BdaMethodCreateTopology(IN PIRP Irp,IN KSMETHOD * pKSMethod,OPTIONAL PVOID pvIgnored)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
BdaMethodDeletePin(IN PIRP Irp,IN KSMETHOD * pKSMethod,OPTIONAL PVOID pvIgnored)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
BdaPropertyGetControllingPinId(IN PIRP Irp,IN KSP_BDA_NODE_PIN * pProperty,OUT ULONG * pulControllingPinId)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
BdaPropertyGetPinControl(IN PIRP Irp,IN KSPROPERTY * pKSProperty,OUT ULONG * pulProperty)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
BdaPropertyNodeDescriptors(IN PIRP Irp,IN KSPROPERTY * pKSProperty,OUT BDANODE_DESCRIPTOR * pNodeDescriptorProperty)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
BdaPropertyNodeEvents(IN PIRP Irp,IN KSP_NODE * pKSProperty,OUT GUID * pguidProperty)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
BdaPropertyNodeMethods(IN PIRP Irp,IN KSP_NODE * pKSProperty,OUT GUID * pguidProperty)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
BdaPropertyNodeProperties(IN PIRP Irp,IN KSP_NODE * pKSProperty,OUT GUID * pguidProperty)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
BdaPropertyNodeTypes(IN PIRP Irp,IN KSPROPERTY * pKSProperty,OUT ULONG * pulProperty)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
BdaPropertyPinTypes(IN PIRP Irp,IN KSPROPERTY * pKSProperty,OUT ULONG * pulProperty)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
BdaPropertyTemplateConnections(IN PIRP Irp,IN KSPROPERTY * pKSProperty,OUT KSTOPOLOGY_CONNECTION * pConnectionProperty)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
BdaStartChanges(IN PIRP Irp)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
BdaUninitFilter(IN PKSFILTER pKSFilter)1027 BdaUninitFilter(IN PKSFILTER pKSFilter)
1028 {
1029 DPRINT("BdaUninitFilter\n");
1030 return STATUS_SUCCESS;
1031 }
1032
1033 /*
1034 @implemented
1035 */
1036 NTSTATUS
1037 NTAPI
BdaValidateNodeProperty(IN PIRP Irp,IN KSPROPERTY * KSProperty)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 }
1050