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 } 1062