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 95 AllocateItem( 96 IN POOL_TYPE PoolType, 97 IN SIZE_T NumberOfBytes) 98 { 99 return ExAllocatePoolZero(PoolType, NumberOfBytes, TAG_BDASUP); 100 } 101 102 VOID 103 FreeItem( 104 IN PVOID Item) 105 { 106 ExFreePoolWithTag(Item, TAG_BDASUP); 107 } 108 109 PBDA_FILTER_INSTANCE_ENTRY 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 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 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 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 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 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 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 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 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 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 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 } 1050