ReactOS 0.4.15-dev-7918-g2a2556c
filter.c File Reference
#include "usbaudio.h"
Include dependency graph for filter.c:

Go to the source code of this file.

Functions

NTSTATUS NTAPI USBAudioFilterCreate (PKSFILTER Filter, PIRP Irp)
 
NTSTATUS NTAPI FilterAudioVolumeHandler (IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
 
NTSTATUS NTAPI FilterAudioMuteHandler (IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
 
 DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME (FilterAudioVolumePropertySet, FilterAudioVolumeHandler)
 
 DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE (FilterAudioMutePropertySet, FilterAudioMuteHandler)
 
NTSTATUS UsbAudioGetSetProperty (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Request, IN USHORT Value, IN USHORT Index, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN ULONG TransferFlags)
 
PNODE_CONTEXT FindNodeContextWithNode (IN PNODE_CONTEXT NodeContext, IN ULONG NodeContextCount, IN ULONG NodeId)
 
ULONG CountTopologyComponents (IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PULONG OutDescriptorCount)
 
PNODE_CONTEXT FindNodeContextWithId (IN PNODE_CONTEXT NodeContext, IN ULONG NodeContextCount, IN UCHAR TerminalId)
 
NTSTATUS BuildUSBAudioFilterTopology (PKSDEVICE Device, PKSFILTER_DESCRIPTOR FilterDescriptor)
 
VOID NTAPI CountTerminalUnits (IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PULONG NonStreamingTerminalDescriptorCount, OUT PULONG TotalTerminalDescriptorCount)
 
LPGUID UsbAudioGetPinCategoryFromTerminalDescriptor (IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
 
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetStreamingTerminalDescriptorByIndex (IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
 
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetNonStreamingTerminalDescriptorByIndex (IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
 
VOID UsbAudioGetDataRanges (IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN UCHAR bTerminalID, OUT PKSDATARANGE **OutDataRanges, OUT PULONG OutDataRangesCount)
 
NTSTATUS USBAudioPinBuildDescriptors (PKSDEVICE Device, PKSPIN_DESCRIPTOR_EX *PinDescriptors, PULONG PinDescriptorsCount, PULONG PinDescriptorSize)
 
NTSTATUS NTAPI USBAudioGetDescriptor (IN PDEVICE_OBJECT DeviceObject, IN UCHAR DescriptorType, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
 
NTSTATUS NTAPI USBAudioGetStringDescriptor (IN PDEVICE_OBJECT DeviceObject, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
 
NTSTATUS USBAudioRegCreateMediaCategoriesKey (IN PUNICODE_STRING Name, OUT PHANDLE OutHandle)
 
NTSTATUS USBAudioInitComponentId (PKSDEVICE Device, IN PKSCOMPONENTID ComponentId)
 
NTSTATUS NTAPI USBAudioCreateFilterContext (PKSDEVICE Device)
 

Variables

GUID NodeTypeMicrophone = { STATIC_KSNODETYPE_MICROPHONE }
 
GUID NodeTypeDesktopMicrophone = { STATIC_KSNODETYPE_DESKTOP_MICROPHONE }
 
GUID NodeTypePersonalMicrophone = { STATIC_KSNODETYPE_PERSONAL_MICROPHONE }
 
GUID NodeTypeOmmniMicrophone = { STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE }
 
GUID NodeTypeArrayMicrophone = { STATIC_KSNODETYPE_MICROPHONE_ARRAY }
 
GUID NodeTypeProcessingArrayMicrophone = { STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY }
 
GUID NodeTypeSpeaker = { STATIC_KSNODETYPE_SPEAKER }
 
GUID NodeTypeHeadphonesSpeaker = { STATIC_KSNODETYPE_HEADPHONES }
 
GUID NodeTypeHMDA = { STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO }
 
GUID NodeTypeDesktopSpeaker = { STATIC_KSNODETYPE_DESKTOP_SPEAKER }
 
GUID NodeTypeRoomSpeaker = { STATIC_KSNODETYPE_ROOM_SPEAKER }
 
GUID NodeTypeCommunicationSpeaker = { STATIC_KSNODETYPE_COMMUNICATION_SPEAKER }
 
GUID NodeTypeSubwoofer = { STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER }
 
GUID NodeTypeCapture = { STATIC_PINNAME_CAPTURE }
 
GUID NodeTypePlayback = { STATIC_KSCATEGORY_AUDIO }
 
GUID GUID_KSCATEGORY_AUDIO = { STATIC_KSCATEGORY_AUDIO }
 
KSPIN_INTERFACE StandardPinInterface
 
KSPIN_MEDIUM StandardPinMedium
 
KSDATARANGE BridgePinAudioFormat []
 
static PKSDATARANGE BridgePinAudioFormats []
 
static LPWSTR ReferenceString = L"global"
 
static KSFILTER_DISPATCH USBAudioFilterDispatch
 
static KSPIN_DISPATCH UsbAudioPinDispatch
 
static KSPROPERTY_SET FilterAudioVolumePropertySetArray []
 
static KSPROPERTY_SET FilterAudioMutePropertySetArray []
 

Function Documentation

◆ BuildUSBAudioFilterTopology()

NTSTATUS BuildUSBAudioFilterTopology ( PKSDEVICE  Device,
PKSFILTER_DESCRIPTOR  FilterDescriptor 
)

Definition at line 426 of file filter.c.

429{
430 PDEVICE_EXTENSION DeviceExtension;
431 ULONG NodeCount, Index, DescriptorCount, StreamingTerminalIndex, NonStreamingTerminalDescriptorCount, TotalTerminalDescriptorCount, StreamingTerminalPinOffset, ControlDescriptorCount, Length;
432 UCHAR Value;
434 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
435 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
436 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
437 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
439 PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR OutputTerminalDescriptor;
440 PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR SelectorUnitDescriptor;
441 PKSNODE_DESCRIPTOR NodeDescriptors;
442 PNODE_CONTEXT NodeContext, PreviousNodeContext;
444 PKSAUTOMATION_TABLE AutomationTable;
445
446 /* get device extension */
447 DeviceExtension = Device->Context;
448
449 /* count topology nodes */
450 NodeCount = CountTopologyComponents(DeviceExtension->ConfigurationDescriptor, &ControlDescriptorCount);
451
452 /* init node descriptors*/
453 FilterDescriptor->NodeDescriptors = NodeDescriptors = AllocFunction(NodeCount * sizeof(KSNODE_DESCRIPTOR));
454 if (FilterDescriptor->NodeDescriptors == NULL)
455 {
456 /* no memory */
458 }
459 FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR);
460
461 DeviceExtension->NodeContext = NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount);
462 if (!NodeContext)
463 {
464 /* no memory */
466 }
467 DeviceExtension->NodeContextCount = ControlDescriptorCount;
468 DescriptorCount = 0;
469
470 /* first enumerate all topology nodes */
471 for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
472 Descriptor != NULL;
473 Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
474 {
475 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
476 {
477 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
478 if (InterfaceHeaderDescriptor != NULL)
479 {
480 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
481 while (CommonDescriptor)
482 {
483 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
484 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/)
485 {
486 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
487 {
488 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC;
489 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC;
490 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
491
492 /* insert into node context*/
493 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
494 NodeContext[DescriptorCount].NodeCount = 1;
495 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
496 DescriptorCount++;
497
498 FilterDescriptor->NodeDescriptorsCount++;
499 }
500 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x200)
501 {
502 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_ADC;
503 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_ADC;
504 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
505
506 /* insert into node context*/
507 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
508 NodeContext[DescriptorCount].NodeCount = 1;
509 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
510 DescriptorCount++;
511
512
513 FilterDescriptor->NodeDescriptorsCount++;
514 }
515 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300)
516 {
517 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC;
518 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC;
519 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
520
521 /* insert into node context*/
522 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
523 NodeContext[DescriptorCount].NodeCount = 1;
524 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
525 DescriptorCount++;
526
527 FilterDescriptor->NodeDescriptorsCount++;
528 }
529 else
530 {
531 DPRINT1("Unexpected input terminal type %x\n", InputTerminalDescriptor->wTerminalType);
532 }
533 }
534 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
535 {
536 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
537 {
538 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC;
539 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC;
540 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
541
542 /* insert into node context*/
543 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
544 NodeContext[DescriptorCount].NodeCount = 1;
545 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
546 DescriptorCount++;
547
548 FilterDescriptor->NodeDescriptorsCount++;
549 }
550 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300)
551 {
552 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC;
553 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC;
554 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
555
556 /* insert into node context*/
557 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
558 NodeContext[DescriptorCount].NodeCount = 1;
559 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
560 DescriptorCount++;
561
562 FilterDescriptor->NodeDescriptorsCount++;
563 }
564 else
565 {
566 DPRINT1("Unexpected output terminal type %x\n", InputTerminalDescriptor->wTerminalType);
567 }
568 }
569
570 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
571 {
572 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)CommonDescriptor;
573
574 /* get controls from all channels*/
575 Value = 0;
576 Length = FeatureUnitDescriptor->bLength - 7;
577 for (Index = 0; Index < Length; Index++)
578 {
579 Value |= FeatureUnitDescriptor->bmaControls[Index];
580 }
581
582
583 if (Value & 0x01) /* MUTE*/
584 {
585 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUTE;
586 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUTE;
587 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
588 if (AutomationTable)
589 {
590 AutomationTable->PropertySets = FilterAudioMutePropertySetArray;
591 AutomationTable->PropertySetsCount = 1;
592 AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM);
593 }
594
595 /* insert into node context*/
596 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
597 NodeContext[DescriptorCount].NodeCount++;
598
599 FilterDescriptor->NodeDescriptorsCount++;
600 }
601 if (Value & 0x02) /* VOLUME */
602 {
603 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_VOLUME;
604 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_VOLUME;
605 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
606 if (AutomationTable)
607 {
608 AutomationTable->PropertySets = FilterAudioVolumePropertySetArray;
609 AutomationTable->PropertySetsCount = 1;
610 AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM);
611 }
612
613 /* insert into node context*/
614 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
615 NodeContext[DescriptorCount].NodeCount++;
616
617 FilterDescriptor->NodeDescriptorsCount++;
618 }
619
620 if (Value & 0x04) /* BASS */
621 {
622 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
623 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
624 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
625
626 /* insert into node context*/
627 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
628 NodeContext[DescriptorCount].NodeCount++;
629
630 FilterDescriptor->NodeDescriptorsCount++;
631 }
632
633 if (Value & 0x08) /* MID */
634 {
635 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
636 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
637 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
638
639 /* insert into node context*/
640 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
641 NodeContext[DescriptorCount].NodeCount++;
642
643 FilterDescriptor->NodeDescriptorsCount++;
644 }
645
646 if (Value & 0x10) /* TREBLE */
647 {
648 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
649 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
650 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
651
652 /* insert into node context*/
653 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
654 NodeContext[DescriptorCount].NodeCount++;
655
656
657 FilterDescriptor->NodeDescriptorsCount++;
658 }
659
660 if (Value & 0x20) /* GRAPHIC EQUALIZER */
661 {
662 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
663 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
664 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
665
666 /* insert into node context*/
667 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
668 NodeContext[DescriptorCount].NodeCount++;
669
670 FilterDescriptor->NodeDescriptorsCount++;
671 }
672
673 if (Value & 0x40) /* AUTOMATIC GAIN */
674 {
675 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_AGC;
676 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_AGC;
677 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
678
679 /* insert into node context*/
680 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
681 NodeContext[DescriptorCount].NodeCount++;
682
683
684 FilterDescriptor->NodeDescriptorsCount++;
685 }
686
687 if (Value & 0x80) /* DELAY */
688 {
689 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
690 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
691 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
692
693 /* insert into node context*/
694 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
695 NodeContext[DescriptorCount].NodeCount++;
696
697 FilterDescriptor->NodeDescriptorsCount++;
698 }
699 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
700 DescriptorCount++;
701
702 }
703 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
704 {
705 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)CommonDescriptor;
706 for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++)
707 {
708 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUPERMIX;
709 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUPERMIX;
710 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
711
712 /* insert into node context*/
713 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
714 NodeContext[DescriptorCount].NodeCount++;
715
716 FilterDescriptor->NodeDescriptorsCount++;
717 }
718
719 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUM;
720 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUM;
721 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
722
723 /* insert into node context*/
724 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
725 NodeContext[DescriptorCount].NodeCount++;
726 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
727 DescriptorCount++;
728
729 FilterDescriptor->NodeDescriptorsCount++;
730 }
731 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR UNIT */)
732 {
733 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUX;
734 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUX;
735 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
736
737 /* insert into node context*/
738 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
739 NodeContext[DescriptorCount].NodeCount = 1;
740 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
741 DescriptorCount++;
742 FilterDescriptor->NodeDescriptorsCount++;
743 }
744 else
745 {
747 }
748 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
749 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
750 break;
751 }
752 }
753 }
754 }
755
756 /* FIXME determine connections count*/
757 FilterDescriptor->Connections = Connections = AllocFunction(sizeof(KSTOPOLOGY_CONNECTION) * FilterDescriptor->NodeDescriptorsCount * 2);
758 if (!FilterDescriptor->Connections)
759 {
760 /* no memory */
762 }
763 FilterDescriptor->ConnectionsCount = 0;
764
765 /* now build connections array */
766 DescriptorCount = 0;
767 StreamingTerminalIndex = 0;
768 NodeCount = 0;
769
770 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
771 StreamingTerminalPinOffset = TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount;
772
773 for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
774 Descriptor != NULL;
775 Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
776 {
777 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
778 {
779 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
780 if (InterfaceHeaderDescriptor != NULL)
781 {
782 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
783 while (CommonDescriptor)
784 {
785 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
786 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/)
787 {
788 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
789 {
790 Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE;
791 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalIndex;
792 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
793 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
794 FilterDescriptor->ConnectionsCount++;
795 StreamingTerminalIndex++;
796
797 }
798 else
799 {
800 Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE;
801 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalPinOffset;
802 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
803 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
804 FilterDescriptor->ConnectionsCount++;
805 StreamingTerminalPinOffset++;
806 }
807 DescriptorCount++;
808 }
809 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
810 {
811 OutputTerminalDescriptor = (PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
812 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, OutputTerminalDescriptor->bSourceID);
813 if (PreviousNodeContext)
814 {
815 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
816 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
817 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
818 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
819 FilterDescriptor->ConnectionsCount++;
820 }
821
822 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
823 {
824 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0];
825 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
826 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalIndex;
827 Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE;
828 FilterDescriptor->ConnectionsCount++;
829 StreamingTerminalIndex++;
830 }
831 else
832 {
833 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0];
834 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
835 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalPinOffset;
836 Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE;
837 FilterDescriptor->ConnectionsCount++;
838
839 StreamingTerminalPinOffset++;
840 }
841 DescriptorCount++;
842 }
843 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
844 {
845 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
846 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, FeatureUnitDescriptor->bSourceID);
847 if (PreviousNodeContext)
848 {
849 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount-1];
850 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
851 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
852 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
853 FilterDescriptor->ConnectionsCount++;
854 }
855 for (Index = 1; Index < NodeContext[DescriptorCount].NodeCount; Index++)
856 {
857 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index - 1];
858 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
859 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
860 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index];
861 FilterDescriptor->ConnectionsCount++;
862 }
863
864 DescriptorCount++;
865 }
866 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
867 {
868 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
869 for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++)
870 {
871 Value = MixerUnitDescriptor->baSourceID[Index];
872 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value);
873 if (PreviousNodeContext)
874 {
875 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
876 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
877 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
878 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index];
879 FilterDescriptor->ConnectionsCount++;
880 }
881
882 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index];
883 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
884 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1 + Index;
885 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount-1];
886 FilterDescriptor->ConnectionsCount++;
887 }
888 DescriptorCount++;
889 }
890 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR_UNIT */)
891 {
892 SelectorUnitDescriptor = (PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR)InputTerminalDescriptor;
893 for (Index = 0; Index < SelectorUnitDescriptor->bNrInPins; Index++)
894 {
895 Value = SelectorUnitDescriptor->baSourceID[Index];
896 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value);
897 if (PreviousNodeContext)
898 {
899 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
900 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
901 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
902 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
903 FilterDescriptor->ConnectionsCount++;
904 }
905 }
906 DescriptorCount++;
907 }
908 else
909 {
911 }
912 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
913 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
914 break;
915 }
916 }
917 }
918 }
919
920
921
922 return STATUS_SUCCESS;
923}
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:115
#define NULL
Definition: types.h:112
static const WCHAR Connections[]
Definition: session.c:1502
#define ULONG_PTR
Definition: config.h:101
VOID NTAPI CountTerminalUnits(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PULONG NonStreamingTerminalDescriptorCount, OUT PULONG TotalTerminalDescriptorCount)
Definition: filter.c:970
PNODE_CONTEXT FindNodeContextWithId(IN PNODE_CONTEXT NodeContext, IN ULONG NodeContextCount, IN UCHAR TerminalId)
Definition: filter.c:408
static KSPROPERTY_SET FilterAudioVolumePropertySetArray[]
Definition: filter.c:100
static KSPROPERTY_SET FilterAudioMutePropertySetArray[]
Definition: filter.c:111
ULONG CountTopologyComponents(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PULONG OutDescriptorCount)
Definition: filter.c:319
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
#define KSFILTER_NODE
Definition: ks.h:44
#define KSNODETYPE_TONE
Definition: ksmedia.h:453
#define KSNODETYPE_SUM
Definition: ksmedia.h:363
#define KSNODETYPE_MUX
Definition: ksmedia.h:433
#define KSNODETYPE_SRC
Definition: ksmedia.h:282
#define KSNODETYPE_VOLUME
Definition: ksmedia.h:338
#define KSNODETYPE_MUTE
Definition: ksmedia.h:348
#define KSNODETYPE_ADC
Definition: ksmedia.h:262
#define KSNODETYPE_AGC
Definition: ksmedia.h:267
#define KSNODETYPE_DAC
Definition: ksmedia.h:287
#define KSNODETYPE_SUPERMIX
Definition: ksmedia.h:277
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_SUCCESS
Definition: shellext.h:65
const KSFILTER_DESCRIPTOR FilterDescriptor
Definition: splitter.c:229
ULONG Nodes[20]
Definition: usbaudio.h:173
ULONG NodeCount
Definition: usbaudio.h:172
PUSB_COMMON_DESCRIPTOR Descriptor
Definition: usbaudio.h:171
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
#define USB_DEVICE_CLASS_AUDIO
Definition: usb100.h:91
struct USB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR * PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR
struct USB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR
struct USB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR
struct USB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR * PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR
struct USB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR * PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
#define USB_AUDIO_STREAMING_TERMINAL_TYPE
Definition: usbaudio.h:17
#define USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
Definition: usbaudio.h:14
struct USB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR
PUSB_COMMON_DESCRIPTOR NTAPI USBD_ParseDescriptors(PVOID DescriptorBuffer, ULONG TotalLength, PVOID StartPosition, LONG DescriptorType)
Definition: usbd.c:445
PUSB_INTERFACE_DESCRIPTOR NTAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PVOID StartPosition, LONG InterfaceNumber, LONG AlternateSetting, LONG InterfaceClass, LONG InterfaceSubClass, LONG InterfaceProtocol)
Definition: usbd.c:496
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by USBAudioCreateFilterContext().

◆ CountTerminalUnits()

VOID NTAPI CountTerminalUnits ( IN PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor,
OUT PULONG  NonStreamingTerminalDescriptorCount,
OUT PULONG  TotalTerminalDescriptorCount 
)

Definition at line 970 of file filter.c.

974{
976 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
977 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
978 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
979 ULONG NonStreamingTerminalCount = 0;
980 ULONG TotalTerminalCount = 0;
981
982 for(Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
983 Descriptor != NULL;
984 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
985 {
986 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
987 {
988 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
989 if (InterfaceHeaderDescriptor != NULL)
990 {
991 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
992 while (CommonDescriptor)
993 {
994 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
995 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
996 {
997 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
998 {
999 NonStreamingTerminalCount++;
1000 }
1001 TotalTerminalCount++;
1002 }
1003 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1004 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1005 break;
1006 }
1007 }
1008 }
1009 else if (Descriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING */
1010 {
1012 }
1013 }
1014 *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount;
1015 *TotalTerminalDescriptorCount = TotalTerminalCount;
1016}

Referenced by BuildUSBAudioFilterTopology(), and USBAudioPinBuildDescriptors().

◆ CountTopologyComponents()

ULONG CountTopologyComponents ( IN PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor,
OUT PULONG  OutDescriptorCount 
)

Definition at line 319 of file filter.c.

322{
324 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
325 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
326 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
327 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
329 ULONG NodeCount = 0, Length, Index;
330 ULONG DescriptorCount = 0;
331 UCHAR Value;
332
333 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
334 Descriptor != NULL;
335 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
336 {
337 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
338 {
339 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
340 if (InterfaceHeaderDescriptor != NULL)
341 {
342 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
343 while (CommonDescriptor)
344 {
345 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
346 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
347 {
348 NodeCount++;
349 DescriptorCount++;
350 }
351 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
352 {
353 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
354 DescriptorCount++;
355
356 /* get controls from all channels*/
357 Value = 0;
358 Length = FeatureUnitDescriptor->bLength - 7;
359 for (Index = 0; Index < Length; Index++)
360 {
361 Value |= FeatureUnitDescriptor->bmaControls[Index];
362 }
363
364 if (Value & 0x01) /* MUTE*/
365 NodeCount++;
366 if (Value & 0x02) /* VOLUME */
367 NodeCount++;
368 if (Value & 0x04) /* BASS */
369 NodeCount++;
370 if (Value & 0x08) /* MID */
371 NodeCount++;
372 if (Value & 0x10) /* TREBLE */
373 NodeCount++;
374 if (Value & 0x20) /* GRAPHIC EQUALIZER */
375 NodeCount++;
376 if (Value & 0x40) /* AUTOMATIC GAIN */
377 NodeCount++;
378 if (Value & 0x80) /* DELAY */
379 NodeCount++;
380 }
381 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
382 {
383 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
384 DescriptorCount++;
385 NodeCount += MixerUnitDescriptor->bNrInPins + 1; /* KSNODETYPE_SUPERMIX for each source pin and KSNODETYPE_SUM for target */
386 }
387 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR_UNIT */)
388 {
389 DescriptorCount++;
390 NodeCount++;
391 }
392 else
393 {
395 }
396 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
397 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
398 break;
399 }
400 }
401 }
402 }
403 *OutDescriptorCount = DescriptorCount;
404 return NodeCount;
405}

Referenced by BuildUSBAudioFilterTopology().

◆ DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE()

DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE ( FilterAudioMutePropertySet  ,
FilterAudioMuteHandler   
)

◆ DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME()

DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME ( FilterAudioVolumePropertySet  ,
FilterAudioVolumeHandler   
)

◆ FilterAudioMuteHandler()

NTSTATUS NTAPI FilterAudioMuteHandler ( IN PIRP  Irp,
IN PKSIDENTIFIER  Request,
IN OUT PVOID  Data 
)

Definition at line 187 of file filter.c.

191{
193 PKSFILTER Filter;
195 PNODE_CONTEXT NodeContext;
196 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
198
199 /* get filter from irp */
201
202 if (Filter)
203 {
204 /* get property */
206
207 /* get filter context */
209
210 /* search for node context */
211 NodeContext = FindNodeContextWithNode(FilterContext->DeviceExtension->NodeContext, FilterContext->DeviceExtension->NodeContextCount, Property->NodeProperty.NodeId);
212 if (NodeContext)
213 {
214 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)NodeContext->Descriptor;
215 if (Property->NodeProperty.Property.Flags & KSPROPERTY_TYPE_GET)
216 {
217 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x81, 0x1 << 8, FeatureUnitDescriptor->bUnitID << 8, Data, 1, USBD_TRANSFER_DIRECTION_IN);
218 Irp->IoStatus.Information = sizeof(BOOL);
219 }
220 else
221 {
222 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x01, 0x1 << 8, FeatureUnitDescriptor->bUnitID << 8, Data, 1, USBD_TRANSFER_DIRECTION_OUT);
223 }
224 }
225 }
226 return Status;
227}
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
KSDDKAPI PKSFILTER NTAPI KsGetFilterFromIrp(IN PIRP Irp)
Definition: filter.c:2106
PNODE_CONTEXT FindNodeContextWithNode(IN PNODE_CONTEXT NodeContext, IN ULONG NodeContextCount, IN ULONG NodeId)
Definition: filter.c:165
NTSTATUS UsbAudioGetSetProperty(IN PDEVICE_OBJECT DeviceObject, IN UCHAR Request, IN USHORT Value, IN USHORT Index, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN ULONG TransferFlags)
Definition: filter.c:123
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG _In_opt_ PVOID _In_opt_ PVOID FilterContext
Definition: fsrtlfuncs.h:746
Status
Definition: gdiplustypes.h:25
struct KSNODEPROPERTY_AUDIO_CHANNEL * PKSNODEPROPERTY_AUDIO_CHANNEL
if(dx< 0)
Definition: linetemp.h:194
#define BOOL
Definition: nt_native.h:43
Property(long _type, long _tag, INREAL _value)
Definition: reader.h:125
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
struct FILTER_CONTEXT * PFILTER_CONTEXT
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547

◆ FilterAudioVolumeHandler()

NTSTATUS NTAPI FilterAudioVolumeHandler ( IN PIRP  Irp,
IN PKSIDENTIFIER  Request,
IN OUT PVOID  Data 
)

Definition at line 231 of file filter.c.

235{
237 PKSFILTER Filter;
239 PNODE_CONTEXT NodeContext;
240 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
241 PSHORT TransferBuffer;
242 LONG Value;
244
245
246 /* get filter from irp */
248
249 if (Filter)
250 {
251 /* get property */
253
254 /* get filter context */
256
257 TransferBuffer = AllocFunction(sizeof(USHORT) * 3);
258 ASSERT(TransferBuffer);
259
260 Value = *(PLONG)Data;
261
262 /* search for node context */
263 NodeContext = FindNodeContextWithNode(FilterContext->DeviceExtension->NodeContext, FilterContext->DeviceExtension->NodeContextCount, Property->NodeProperty.NodeId);
264 if (NodeContext)
265 {
266 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)NodeContext->Descriptor;
267 if (Property->NodeProperty.Property.Flags & KSPROPERTY_TYPE_GET)
268 {
269 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x81, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[0], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
270 Value = (LONG)TransferBuffer[0] * 256;
271
272 *(PLONG)Data = Value;
273 Irp->IoStatus.Information = sizeof(BOOL);
274 }
275 else
276 {
277 /* downscale value */
278 Value /= 256;
279
280 /* get minimum value */
281 UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x82, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[0], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
282
283 /* get maximum value */
284 UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x83, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[1], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
285
286 if (TransferBuffer[0] > Value)
287 {
288 /* use minimum value */
289 Value = TransferBuffer[0];
290 }
291
292 if (TransferBuffer[1] < Value)
293 {
294 /* use maximum value */
295 Value = TransferBuffer[1];
296 }
297
298 /* store value */
299 TransferBuffer[2] = Value;
300
301 /* set volume request */
302 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x01, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[2], sizeof(USHORT), USBD_TRANSFER_DIRECTION_OUT);
303 if (NT_SUCCESS(Status))
304 {
305 /* store number of bytes transferred*/
306 Irp->IoStatus.Information = sizeof(LONG);
307 }
308 }
309 }
310
311 /* free transfer buffer */
312 FreeFunction(TransferBuffer);
313 }
314 return Status;
315}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
#define ASSERT(a)
Definition: mode.c:44
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
int16_t * PSHORT
Definition: typedefs.h:55
int32_t * PLONG
Definition: typedefs.h:58

◆ FindNodeContextWithId()

PNODE_CONTEXT FindNodeContextWithId ( IN PNODE_CONTEXT  NodeContext,
IN ULONG  NodeContextCount,
IN UCHAR  TerminalId 
)

Definition at line 408 of file filter.c.

412{
413 ULONG Index;
415
416 for (Index = 0; Index < NodeContextCount; Index++)
417 {
418 TerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)NodeContext[Index].Descriptor;
419 if (TerminalDescriptor->bTerminalID == TerminalId)
420 return &NodeContext[Index];
421 }
422 return NULL;
423}

Referenced by BuildUSBAudioFilterTopology().

◆ FindNodeContextWithNode()

PNODE_CONTEXT FindNodeContextWithNode ( IN PNODE_CONTEXT  NodeContext,
IN ULONG  NodeContextCount,
IN ULONG  NodeId 
)

Definition at line 165 of file filter.c.

169{
170 ULONG Index, NodeIndex;
171 for (Index = 0; Index < NodeContextCount; Index++)
172 {
173 for (NodeIndex = 0; NodeIndex < NodeContext[Index].NodeCount; NodeIndex++)
174 {
175 if (NodeContext[Index].Nodes[NodeIndex] == NodeId)
176 {
177 return &NodeContext[Index];
178 }
179 }
180 }
181 return NULL;
182}

Referenced by FilterAudioMuteHandler(), and FilterAudioVolumeHandler().

◆ USBAudioCreateFilterContext()

NTSTATUS NTAPI USBAudioCreateFilterContext ( PKSDEVICE  Device)

Definition at line 1525 of file filter.c.

1527{
1528 PKSFILTER_DESCRIPTOR FilterDescriptor;
1531
1532 /* allocate descriptor */
1533 FilterDescriptor = AllocFunction(sizeof(KSFILTER_DESCRIPTOR));
1534 if (!FilterDescriptor)
1535 {
1536 /* no memory */
1538 }
1539
1540 /* init filter descriptor*/
1541 FilterDescriptor->Version = KSFILTER_DESCRIPTOR_VERSION;
1542 FilterDescriptor->Flags = 0;
1543 FilterDescriptor->ReferenceGuid = &KSNAME_Filter;
1545 FilterDescriptor->CategoriesCount = 1;
1547
1548 /* init component id*/
1550 if (!ComponentId)
1551 {
1552 /* no memory */
1554 }
1556 if (!NT_SUCCESS(Status))
1557 {
1558 /* failed*/
1560 return Status;
1561 }
1562 FilterDescriptor->ComponentId = ComponentId;
1563
1564 /* build pin descriptors */
1565 Status = USBAudioPinBuildDescriptors(Device, (PKSPIN_DESCRIPTOR_EX *)&FilterDescriptor->PinDescriptors, &FilterDescriptor->PinDescriptorsCount, &FilterDescriptor->PinDescriptorSize);
1566 if (!NT_SUCCESS(Status))
1567 {
1568 /* failed*/
1570 return Status;
1571 }
1572
1573 /* build topology */
1575 if (!NT_SUCCESS(Status))
1576 {
1577 /* failed*/
1579 return Status;
1580 }
1581
1582 /* lets create the filter */
1583 Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL);
1584 DPRINT("KsCreateFilterFactory: %x\n", Status);
1585
1586 return Status;
1587}
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char UINT32 ComponentId
Definition: acpixf.h:1281
static KSFILTER_DISPATCH USBAudioFilterDispatch
Definition: filter.c:71
NTSTATUS BuildUSBAudioFilterTopology(PKSDEVICE Device, PKSFILTER_DESCRIPTOR FilterDescriptor)
Definition: filter.c:426
GUID GUID_KSCATEGORY_AUDIO
Definition: filter.c:27
NTSTATUS USBAudioPinBuildDescriptors(PKSDEVICE Device, PKSPIN_DESCRIPTOR_EX *PinDescriptors, PULONG PinDescriptorsCount, PULONG PinDescriptorSize)
Definition: filter.c:1252
NTSTATUS USBAudioInitComponentId(PKSDEVICE Device, IN PKSCOMPONENTID ComponentId)
Definition: filter.c:1473
KSDDKAPI NTSTATUS NTAPI KsCreateFilterFactory(IN PDEVICE_OBJECT DeviceObject, IN const KSFILTER_DESCRIPTOR *Descriptor, IN PWSTR RefString OPTIONAL, IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN ULONG CreateItemFlags, IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL, IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL, OUT PKSFILTERFACTORY *FilterFactory OPTIONAL)
#define KSNAME_Filter
Definition: ks.h:111
#define DPRINT
Definition: sndvol32.h:71
#define USBD_STATUS_INSUFFICIENT_RESOURCES
Definition: usb.h:204
_Must_inspect_result_ _In_ WDFDEVICE _In_ CONST GUID _In_opt_ PCUNICODE_STRING ReferenceString
Definition: wdfdevice.h:3630

Referenced by USBAudioPnPStart().

◆ USBAudioFilterCreate()

NTSTATUS NTAPI USBAudioFilterCreate ( PKSFILTER  Filter,
PIRP  Irp 
)

Definition at line 927 of file filter.c.

930{
931 PKSFILTERFACTORY FilterFactory;
932 PKSDEVICE Device;
934
935 FilterFactory = KsGetParent(Filter);
936 if (FilterFactory == NULL)
937 {
938 /* invalid parameter */
940 }
941
942 Device = KsGetParent(FilterFactory);
943 if (Device == NULL)
944 {
945 /* invalid parameter */
947 }
948
949 /* alloc filter context */
951 if (FilterContext == NULL)
952 {
953 /* no memory */
955 }
956
957 /* init context */
958 FilterContext->DeviceExtension = Device->Context;
959 FilterContext->LowerDevice = Device->NextDeviceObject;
960 Filter->Context = FilterContext;
961
962 DPRINT("USBAudioFilterCreate FilterContext %p LowerDevice %p DeviceExtension %p\n", FilterContext, FilterContext->LowerDevice, FilterContext->DeviceExtension);
964 return STATUS_SUCCESS;
965}
NTSTATUS NTAPI KsAddItemToObjectBag(IN KSOBJECT_BAG ObjectBag, IN PVOID Item, IN PFNKSFREE Free OPTIONAL)
Definition: bag.c:86
KSDDKAPI PVOID NTAPI KsGetParent(IN PVOID Object)
Definition: misc.c:160
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ UsbAudioGetDataRanges()

VOID UsbAudioGetDataRanges ( IN PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor,
IN UCHAR  bTerminalID,
OUT PKSDATARANGE **  OutDataRanges,
OUT PULONG  OutDataRangesCount 
)

Definition at line 1154 of file filter.c.

1159{
1160 PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR StreamingInterfaceDescriptor;
1161 PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR StreamingFormatDescriptor;
1163 PKSDATARANGE_AUDIO DataRangeAudio;
1164 PKSDATARANGE *DataRangeAudioArray;
1165 ULONG NumFrequency, DataRangeCount, DataRangeIndex, Index;
1166
1167 /* count all data ranges */
1168 DataRangeCount = 0;
1169 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1170 Descriptor != NULL;
1171 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1172 {
1173 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */
1174 {
1175 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1176 if (StreamingInterfaceDescriptor != NULL)
1177 {
1178 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
1179 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
1180 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID)
1181 {
1182 DataRangeCount++;
1183 DPRINT1("StreamingInterfaceDescriptor %p TerminalID %x\n", StreamingInterfaceDescriptor, bTerminalID);
1184 }
1185 }
1186 Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor;
1187 }
1188 }
1189
1190 DataRangeAudioArray = AllocFunction(sizeof(PVOID) * DataRangeCount);
1191 if (DataRangeAudioArray == NULL)
1192 {
1193 /* no memory */
1194 return;
1195 }
1196
1197 DataRangeIndex = 0;
1198 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1199 Descriptor != NULL;
1200 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1201 {
1202 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */
1203 {
1204 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1205 if (StreamingInterfaceDescriptor != NULL)
1206 {
1207 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
1208 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
1209 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID)
1210 {
1211 StreamingFormatDescriptor = (PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR)((ULONG_PTR)StreamingInterfaceDescriptor + StreamingInterfaceDescriptor->bLength);
1212 ASSERT(StreamingFormatDescriptor->bDescriptorType == 0x24);
1213 ASSERT(StreamingFormatDescriptor->bDescriptorSubtype == 0x02);
1214 ASSERT(StreamingFormatDescriptor->bFormatType == 0x01);
1215
1216 DataRangeAudio = AllocFunction(sizeof(KSDATARANGE_AUDIO));
1217 if (DataRangeAudio == NULL)
1218 {
1219 /* no memory*/
1220 return;
1221 }
1222
1223 DataRangeAudio->DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
1227 DataRangeAudio->MaximumChannels = StreamingFormatDescriptor->bNrChannels;
1228 DataRangeAudio->MinimumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
1229 DataRangeAudio->MaximumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
1230 NumFrequency = StreamingFormatDescriptor->bSamFreqType;
1231 DataRangeAudio->MinimumSampleFrequency = MAXULONG;
1232 DataRangeAudio->MaximumSampleFrequency = 0;
1233 for (Index = 0; Index < NumFrequency; Index++)
1234 {
1235 DataRangeAudio->MinimumSampleFrequency = min(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MinimumSampleFrequency);
1236 DataRangeAudio->MaximumSampleFrequency = max(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MaximumSampleFrequency);
1237 }
1238 DataRangeAudioArray[DataRangeIndex] = (PKSDATARANGE)DataRangeAudio;
1239 DataRangeIndex++;
1240 }
1241 }
1242 Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor;
1243 }
1244 }
1245
1246 *OutDataRanges = DataRangeAudioArray;
1247 *OutDataRangesCount = DataRangeCount;
1248}
#define WAVE_FORMAT_PCM
Definition: constants.h:425
union KSDATAFORMAT * PKSDATARANGE
#define KSDATAFORMAT_SUBTYPE_PCM
Definition: ksmedia.h:1021
#define KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:983
#define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
Definition: ksmedia.h:1031
#define min(a, b)
Definition: monoChain.cc:55
ULONG MaximumChannels
Definition: ksmedia.h:680
ULONG MinimumBitsPerSample
Definition: ksmedia.h:681
ULONG MaximumBitsPerSample
Definition: ksmedia.h:682
ULONG MaximumSampleFrequency
Definition: ksmedia.h:684
KSDATARANGE DataRange
Definition: ksmedia.h:679
ULONG MinimumSampleFrequency
Definition: ksmedia.h:683
#define max(a, b)
Definition: svc.c:63
#define MAXULONG
Definition: typedefs.h:251
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
struct USB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR * PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR
struct USB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR * PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR

Referenced by USBAudioPinBuildDescriptors().

◆ USBAudioGetDescriptor()

NTSTATUS NTAPI USBAudioGetDescriptor ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  DescriptorType,
IN ULONG  DescriptorLength,
IN UCHAR  DescriptorIndex,
IN LANGID  LanguageId,
OUT PVOID OutDescriptor 
)

Definition at line 1352 of file filter.c.

1359{
1360 PURB Urb;
1363
1364 /* sanity checks */
1366 ASSERT(OutDescriptor);
1367 ASSERT(DescriptorLength);
1368
1369 //
1370 // first allocate descriptor buffer
1371 //
1372 Descriptor = AllocFunction(DescriptorLength);
1373 if (!Descriptor)
1374 {
1375 /* no memory */
1377 }
1378
1379 /* allocate urb */
1380 Urb = (PURB)AllocFunction(sizeof(URB));
1381 if (!Urb)
1382 {
1383 /* no memory */
1386 }
1387
1388 /* initialize urb */
1390 sizeof(Urb->UrbControlDescriptorRequest),
1392 DescriptorIndex,
1393 LanguageId,
1394 Descriptor,
1395 NULL,
1396 DescriptorLength,
1397 NULL);
1398
1399 /* submit urb */
1401
1402 /* free urb */
1403 FreeFunction(Urb);
1404
1405 if (NT_SUCCESS(Status))
1406 {
1407 /* store result */
1408 *OutDescriptor = Descriptor;
1409 }
1410 else
1411 {
1412 /* failed */
1414 }
1415
1416 /* done */
1417 return Status;
1418}
Definition: usb.h:529
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
struct _URB * PURB
NTSTATUS SubmitUrbSync(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: usbaudio.c:37
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:160
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

Referenced by USBAudioGetStringDescriptor().

◆ UsbAudioGetNonStreamingTerminalDescriptorByIndex()

PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetNonStreamingTerminalDescriptorByIndex ( IN PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor,
IN ULONG  Index 
)

Definition at line 1108 of file filter.c.

1111{
1112
1114 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
1115 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
1116 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
1117 ULONG TerminalCount = 0;
1118
1119 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1120 Descriptor != NULL;
1121 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1122 {
1123 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
1124 {
1125 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1126 if (InterfaceHeaderDescriptor != NULL)
1127 {
1128 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1129 while (CommonDescriptor)
1130 {
1131 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
1132 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
1133 {
1134 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
1135 {
1136 if (TerminalCount == Index)
1137 {
1138 return InputTerminalDescriptor;
1139 }
1140 TerminalCount++;
1141 }
1142 }
1143 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1144 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1145 break;
1146 }
1147 }
1148 }
1149 }
1150 return NULL;
1151}

Referenced by USBAudioPinBuildDescriptors().

◆ UsbAudioGetPinCategoryFromTerminalDescriptor()

LPGUID UsbAudioGetPinCategoryFromTerminalDescriptor ( IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR  TerminalDescriptor)

Definition at line 1019 of file filter.c.

1021{
1022 if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE)
1023 return &NodeTypeMicrophone;
1024 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE)
1026 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE)
1028 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE)
1030 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE)
1032 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE)
1034
1035 /* playback types */
1036 if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE)
1037 return &NodeTypeSpeaker;
1038 else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE)
1040 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE)
1041 return &NodeTypeHMDA;
1042 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE)
1043 return &NodeTypeDesktopSpeaker;
1044 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE)
1045 return &NodeTypeRoomSpeaker;
1046 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE)
1048 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE)
1049 return &NodeTypeSubwoofer;
1050
1051 if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
1052 {
1053 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1054 return &NodeTypeCapture;
1055 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1056 return &NodeTypePlayback;
1057
1058 }
1059 return NULL;
1060}
GUID NodeTypeCommunicationSpeaker
Definition: filter.c:23
GUID NodeTypeCapture
Definition: filter.c:25
GUID NodeTypeSpeaker
Definition: filter.c:18
GUID NodeTypePersonalMicrophone
Definition: filter.c:14
GUID NodeTypeHeadphonesSpeaker
Definition: filter.c:19
GUID NodeTypeDesktopSpeaker
Definition: filter.c:21
GUID NodeTypeRoomSpeaker
Definition: filter.c:22
GUID NodeTypeHMDA
Definition: filter.c:20
GUID NodeTypeOmmniMicrophone
Definition: filter.c:15
GUID NodeTypeSubwoofer
Definition: filter.c:24
GUID NodeTypePlayback
Definition: filter.c:26
GUID NodeTypeDesktopMicrophone
Definition: filter.c:13
GUID NodeTypeMicrophone
Definition: filter.c:12
GUID NodeTypeArrayMicrophone
Definition: filter.c:16
GUID NodeTypeProcessingArrayMicrophone
Definition: filter.c:17
#define USB_AUDIO_OUTPUT_TERMINAL
Definition: usbaudio.h:36
#define USB_AUDIO_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:19
#define USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:23
#define USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:31
#define USB_AUDIO_HMDA_TERMINAL_TYPE
Definition: usbaudio.h:28
#define USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:20
#define USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:21
#define USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:29
#define USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:22
#define USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:30
#define USB_AUDIO_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:26
#define USB_HEADPHONES_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:27
#define USB_AUDIO_INPUT_TERMINAL
Definition: usbaudio.h:35
#define USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:24
#define USB_AUDIO_SUBWOOFER_TERMINAL_TYPE
Definition: usbaudio.h:32

Referenced by USBAudioPinBuildDescriptors().

◆ UsbAudioGetSetProperty()

NTSTATUS UsbAudioGetSetProperty ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  Request,
IN USHORT  Value,
IN USHORT  Index,
IN PVOID  TransferBuffer,
IN ULONG  TransferBufferLength,
IN ULONG  TransferFlags 
)

Definition at line 123 of file filter.c.

131{
132 PURB Urb;
134
135 /* allocate urb */
137 if (!Urb)
138 {
139 /* no memory */
141 }
142
143 /* format urb */
147 TransferFlags,
148 0,
149 Request,
150 Value,
151 Index,
152 TransferBuffer,
153 NULL,
154 TransferBufferLength,
155 NULL);
156
157 /* submit urb */
159
160 FreeFunction(Urb);
161 return Status;
162}
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
#define UsbBuildVendorRequest(urb, cmd, length, transferFlags, reservedbits, request, value, index, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:68

Referenced by FilterAudioMuteHandler(), and FilterAudioVolumeHandler().

◆ UsbAudioGetStreamingTerminalDescriptorByIndex()

PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetStreamingTerminalDescriptorByIndex ( IN PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor,
IN ULONG  Index 
)

Definition at line 1063 of file filter.c.

1066{
1068 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
1069 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
1070 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
1071 ULONG TerminalCount = 0;
1072
1073 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1074 Descriptor != NULL;
1075 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1076 {
1077 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
1078 {
1079 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1080 if (InterfaceHeaderDescriptor != NULL)
1081 {
1082 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1083 while (CommonDescriptor)
1084 {
1085 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
1086 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
1087 {
1088 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
1089 {
1090 if (TerminalCount == Index)
1091 {
1092 return InputTerminalDescriptor;
1093 }
1094 TerminalCount++;
1095 }
1096 }
1097 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1098 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1099 break;
1100 }
1101 }
1102 }
1103 }
1104 return NULL;
1105}

Referenced by USBAudioPinBuildDescriptors(), and USBAudioSelectAudioStreamingInterface().

◆ USBAudioGetStringDescriptor()

NTSTATUS NTAPI USBAudioGetStringDescriptor ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  DescriptorLength,
IN UCHAR  DescriptorIndex,
IN LANGID  LanguageId,
OUT PVOID OutDescriptor 
)

Definition at line 1422 of file filter.c.

1428{
1430
1431 /* retrieve descriptor */
1432 Status = USBAudioGetDescriptor(DeviceObject, USB_STRING_DESCRIPTOR_TYPE, DescriptorLength, DescriptorIndex, LanguageId, OutDescriptor);
1433 if (!NT_SUCCESS(Status))
1434 {
1435 // failed
1436 return Status;
1437 }
1438 return STATUS_SUCCESS;
1439}
NTSTATUS NTAPI USBAudioGetDescriptor(IN PDEVICE_OBJECT DeviceObject, IN UCHAR DescriptorType, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: filter.c:1352
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51

Referenced by USBAudioInitComponentId().

◆ USBAudioInitComponentId()

NTSTATUS USBAudioInitComponentId ( PKSDEVICE  Device,
IN PKSCOMPONENTID  ComponentId 
)

Definition at line 1473 of file filter.c.

1476{
1477 PDEVICE_EXTENSION DeviceExtension;
1479 LPWSTR DescriptionBuffer;
1482 HANDLE hKey;
1483 GUID TempGuid;
1484
1485 /* get device extension */
1486 DeviceExtension = Device->Context;
1487
1488 /* init component id */
1490 ComponentId->Version = HIBYTE(DeviceExtension->DeviceDescriptor->bcdDevice);
1491 ComponentId->Revision = LOBYTE(DeviceExtension->DeviceDescriptor->bcdDevice);
1492
1493 INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor);
1494 INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
1495 INIT_USBAUDIO_PRODUCT_NAME(&TempGuid, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0);
1496
1497 if (DeviceExtension->DeviceDescriptor->iProduct)
1498 {
1499 Status = USBAudioGetStringDescriptor(DeviceExtension->LowerDevice, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iProduct, 0x0409 /* FIXME */, (PVOID*)&DescriptionBuffer);
1500 if (NT_SUCCESS(Status))
1501 {
1502 Status = RtlStringFromGUID(&TempGuid, &GuidString);
1503 if (NT_SUCCESS(Status))
1504 {
1506 if (NT_SUCCESS(Status))
1507 {
1508 RtlInitUnicodeString(&Name, L"Name");
1509 ZwSetValueKey(hKey, &Name, 0, REG_SZ, DescriptionBuffer, (wcslen(DescriptionBuffer) + 1) * sizeof(WCHAR));
1510 ZwClose(hKey);
1511
1512 INIT_USBAUDIO_PRODUCT_NAME(&ComponentId->Name, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0);
1513 }
1515 }
1516 FreeFunction(DescriptionBuffer);
1517 }
1518 }
1519 return STATUS_SUCCESS;
1520}
struct NameRec_ * Name
Definition: cdprocs.h:460
NTSTATUS USBAudioRegCreateMediaCategoriesKey(IN PUNICODE_STRING Name, OUT PHANDLE OutHandle)
Definition: filter.c:1442
NTSTATUS NTAPI USBAudioGetStringDescriptor(IN PDEVICE_OBJECT DeviceObject, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: filter.c:1422
FxAutoRegKey hKey
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define INIT_USBAUDIO_PRODUCT_NAME(guid, vid, pid, strIndex)
Definition: ksmedia.h:99
#define INIT_USBAUDIO_PID(guid, id)
Definition: ksmedia.h:62
#define KSCOMPONENTID_USBAUDIO
Definition: ksmedia.h:123
#define INIT_USBAUDIO_MID(guid, id)
Definition: ksmedia.h:25
#define REG_SZ
Definition: layer.c:22
static PWSTR GuidString
Definition: apphelp.c:93
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define L(x)
Definition: ntvdm.h:50
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by USBAudioCreateFilterContext().

◆ USBAudioPinBuildDescriptors()

NTSTATUS USBAudioPinBuildDescriptors ( PKSDEVICE  Device,
PKSPIN_DESCRIPTOR_EX *  PinDescriptors,
PULONG  PinDescriptorsCount,
PULONG  PinDescriptorSize 
)

Definition at line 1252 of file filter.c.

1257{
1258 PDEVICE_EXTENSION DeviceExtension;
1259 PKSPIN_DESCRIPTOR_EX Pins;
1260 ULONG TotalTerminalDescriptorCount = 0;
1261 ULONG NonStreamingTerminalDescriptorCount = 0;
1262 ULONG Index = 0;
1264
1265 /* get device extension */
1266 DeviceExtension = Device->Context;
1267
1268 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
1269 DPRINT("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu\n", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount);
1270
1271 /* allocate pins */
1272 Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount);
1273 if (!Pins)
1274 {
1275 /* no memory*/
1277 }
1278
1279 for (Index = 0; Index < TotalTerminalDescriptorCount; Index++)
1280 {
1281 if (Index < (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount))
1282 {
1283 /* irp sink pins*/
1284 TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index);
1285 ASSERT(TerminalDescriptor != NULL);
1286
1287 Pins[Index].Dispatch = &UsbAudioPinDispatch;
1288 Pins[Index].PinDescriptor.InterfacesCount = 1;
1289 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
1290 Pins[Index].PinDescriptor.MediumsCount = 1;
1291 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
1292 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
1293 UsbAudioGetDataRanges(DeviceExtension->ConfigurationDescriptor, TerminalDescriptor->bTerminalID, (PKSDATARANGE**)&Pins[Index].PinDescriptor.DataRanges, &Pins[Index].PinDescriptor.DataRangesCount);
1294
1295 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1296 {
1297 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BOTH;
1298 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
1299
1300 /* pin flags */
1301 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSFILTER_FLAG_CRITICAL_PROCESSING;
1302 }
1303 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1304 {
1305 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK;
1306 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
1307
1308 /* pin flags */
1309 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSPIN_FLAG_GENERATE_EOS_EVENTS;
1310 }
1311
1312 /* data intersect handler */
1313 Pins[Index].IntersectHandler = UsbAudioPinDataIntersect;
1314
1315 /* irp sinks / sources can be instantiated */
1316 Pins[Index].InstancesPossible = 1;
1317 }
1318 else
1319 {
1320 /* bridge pins */
1321 TerminalDescriptor = UsbAudioGetNonStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index - (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount));
1322 Pins[Index].PinDescriptor.InterfacesCount = 1;
1323 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
1324 Pins[Index].PinDescriptor.MediumsCount = 1;
1325 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
1326 Pins[Index].PinDescriptor.DataRanges = BridgePinAudioFormats;
1327 Pins[Index].PinDescriptor.DataRangesCount = 1;
1328 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE;
1329 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
1330
1331 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1332 {
1333 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
1334 }
1335 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1336 {
1337 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
1338 }
1339 }
1340
1341 }
1342
1343 *PinDescriptors = Pins;
1344 *PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX);
1345 *PinDescriptorsCount = TotalTerminalDescriptorCount;
1346
1347 return STATUS_SUCCESS;
1348}
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetStreamingTerminalDescriptorByIndex(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
Definition: filter.c:1063
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetNonStreamingTerminalDescriptorByIndex(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
Definition: filter.c:1108
static PKSDATARANGE BridgePinAudioFormats[]
Definition: filter.c:58
KSPIN_MEDIUM StandardPinMedium
Definition: filter.c:36
static KSPIN_DISPATCH UsbAudioPinDispatch
Definition: filter.c:79
KSPIN_INTERFACE StandardPinInterface
Definition: filter.c:29
VOID UsbAudioGetDataRanges(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN UCHAR bTerminalID, OUT PKSDATARANGE **OutDataRanges, OUT PULONG OutDataRangesCount)
Definition: filter.c:1154
LPGUID UsbAudioGetPinCategoryFromTerminalDescriptor(IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
Definition: filter.c:1019
NTSTATUS NTAPI UsbAudioPinDataIntersect(_In_ PVOID Context, _In_ PIRP Irp, _In_ PKSP_PIN Pin, _In_ PKSDATARANGE DataRange, _In_ PKSDATARANGE MatchingDataRange, _In_ ULONG DataBufferSize, _Out_ PVOID Data, _Out_ PULONG DataSize)
Definition: pin.c:1416
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
@ KSPIN_COMMUNICATION_BRIDGE
Definition: ks.h:1258
@ KSPIN_COMMUNICATION_BOTH
Definition: ks.h:1257
@ KSPIN_COMMUNICATION_SINK
Definition: ks.h:1255
const KSPIN_DESCRIPTOR_EX PinDescriptors[]
Definition: splitter.c:154

Referenced by USBAudioCreateFilterContext().

◆ USBAudioRegCreateMediaCategoriesKey()

NTSTATUS USBAudioRegCreateMediaCategoriesKey ( IN PUNICODE_STRING  Name,
OUT PHANDLE  OutHandle 
)

Definition at line 1442 of file filter.c.

1445{
1449 HANDLE Handle;
1450
1451 /* initialize root name*/
1452 RtlInitUnicodeString(&DestinationString, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
1453
1454 /* initialize object attributes */
1456
1457 /* create the key */
1459 if (NT_SUCCESS(Status))
1460 {
1461 /* initialize object attributes */
1463
1464 Status = ZwCreateKey(OutHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL);
1465 ZwClose(Handle);
1466
1467 }
1468 return Status;
1469}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
ULONG Handle
Definition: gdb_input.c:15
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1909
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041

Referenced by USBAudioInitComponentId().

Variable Documentation

◆ BridgePinAudioFormat

KSDATARANGE BridgePinAudioFormat[]
Initial value:
=
{
{
{
sizeof(KSDATAFORMAT),
0,
0,
0,
}
}
}
#define STATIC_KSDATAFORMAT_SPECIFIER_NONE
Definition: ks.h:1154
#define STATIC_KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:980
#define STATIC_KSDATAFORMAT_SUBTYPE_ANALOG
Definition: ksmedia.h:990

Definition at line 43 of file filter.c.

◆ BridgePinAudioFormats

PKSDATARANGE BridgePinAudioFormats[]
static
Initial value:
=
{
}
KSDATARANGE BridgePinAudioFormat[]
Definition: filter.c:43

Definition at line 58 of file filter.c.

Referenced by USBAudioPinBuildDescriptors().

◆ FilterAudioMutePropertySetArray

KSPROPERTY_SET FilterAudioMutePropertySetArray[]
static
Initial value:
=
{
{
sizeof(FilterAudioMutePropertySet) / sizeof(KSPROPERTY_ITEM),
(const KSPROPERTY_ITEM*)&FilterAudioMutePropertySet,
0,
}
}
#define KSPROPSETID_Audio
Definition: ksmedia.h:1051

Definition at line 111 of file filter.c.

Referenced by BuildUSBAudioFilterTopology().

◆ FilterAudioVolumePropertySetArray

KSPROPERTY_SET FilterAudioVolumePropertySetArray[]
static
Initial value:
=
{
{
sizeof(FilterAudioVolumePropertySet) / sizeof(KSPROPERTY_ITEM),
(const KSPROPERTY_ITEM*)&FilterAudioVolumePropertySet,
0,
}
}

Definition at line 100 of file filter.c.

Referenced by BuildUSBAudioFilterTopology().

◆ GUID_KSCATEGORY_AUDIO

GUID GUID_KSCATEGORY_AUDIO = { STATIC_KSCATEGORY_AUDIO }

Definition at line 27 of file filter.c.

Referenced by USBAudioCreateFilterContext().

◆ NodeTypeArrayMicrophone

GUID NodeTypeArrayMicrophone = { STATIC_KSNODETYPE_MICROPHONE_ARRAY }

Definition at line 16 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeCapture

GUID NodeTypeCapture = { STATIC_PINNAME_CAPTURE }

Definition at line 25 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeCommunicationSpeaker

GUID NodeTypeCommunicationSpeaker = { STATIC_KSNODETYPE_COMMUNICATION_SPEAKER }

Definition at line 23 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeDesktopMicrophone

GUID NodeTypeDesktopMicrophone = { STATIC_KSNODETYPE_DESKTOP_MICROPHONE }

Definition at line 13 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeDesktopSpeaker

GUID NodeTypeDesktopSpeaker = { STATIC_KSNODETYPE_DESKTOP_SPEAKER }

Definition at line 21 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeHeadphonesSpeaker

GUID NodeTypeHeadphonesSpeaker = { STATIC_KSNODETYPE_HEADPHONES }

Definition at line 19 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeHMDA

◆ NodeTypeMicrophone

GUID NodeTypeMicrophone = { STATIC_KSNODETYPE_MICROPHONE }

Definition at line 12 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeOmmniMicrophone

GUID NodeTypeOmmniMicrophone = { STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE }

Definition at line 15 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypePersonalMicrophone

GUID NodeTypePersonalMicrophone = { STATIC_KSNODETYPE_PERSONAL_MICROPHONE }

Definition at line 14 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypePlayback

GUID NodeTypePlayback = { STATIC_KSCATEGORY_AUDIO }

Definition at line 26 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeProcessingArrayMicrophone

GUID NodeTypeProcessingArrayMicrophone = { STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY }

Definition at line 17 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeRoomSpeaker

GUID NodeTypeRoomSpeaker = { STATIC_KSNODETYPE_ROOM_SPEAKER }

Definition at line 22 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeSpeaker

GUID NodeTypeSpeaker = { STATIC_KSNODETYPE_SPEAKER }

Definition at line 18 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ NodeTypeSubwoofer

Definition at line 24 of file filter.c.

Referenced by UsbAudioGetPinCategoryFromTerminalDescriptor().

◆ ReferenceString

LPWSTR ReferenceString = L"global"
static

Definition at line 63 of file filter.c.

◆ StandardPinInterface

KSPIN_INTERFACE StandardPinInterface
Initial value:
=
{
0
}
#define STATIC_KSINTERFACESETID_Standard
Definition: ks.h:277
@ KSINTERFACE_STANDARD_STREAMING
Definition: ks.h:283

Definition at line 29 of file filter.c.

Referenced by USBAudioPinBuildDescriptors().

◆ StandardPinMedium

KSPIN_MEDIUM StandardPinMedium
Initial value:
=
{
0
}
#define KSMEDIUM_TYPE_ANYINSTANCE
Definition: ks.h:301
#define STATIC_KSMEDIUMSETID_Standard
Definition: ks.h:303

Definition at line 36 of file filter.c.

Referenced by USBAudioPinBuildDescriptors().

◆ USBAudioFilterDispatch

KSFILTER_DISPATCH USBAudioFilterDispatch
static
Initial value:
=
{
}
NTSTATUS NTAPI USBAudioFilterCreate(PKSFILTER Filter, PIRP Irp)
Definition: filter.c:927

Definition at line 71 of file filter.c.

Referenced by USBAudioCreateFilterContext().

◆ UsbAudioPinDispatch

KSPIN_DISPATCH UsbAudioPinDispatch
static
Initial value:
=
{
}
NTSTATUS NTAPI USBAudioPinCreate(_In_ PKSPIN Pin, _In_ PIRP Irp)
Definition: pin.c:764
VOID NTAPI USBAudioPinReset(_In_ PKSPIN Pin)
Definition: pin.c:1290
NTSTATUS NTAPI USBAudioPinProcess(_In_ PKSPIN Pin)
Definition: pin.c:1270
NTSTATUS NTAPI USBAudioPinClose(_In_ PKSPIN Pin, _In_ PIRP Irp)
Definition: pin.c:843
NTSTATUS NTAPI USBAudioPinSetDeviceState(_In_ PKSPIN Pin, _In_ KSSTATE ToState, _In_ KSSTATE FromState)
Definition: pin.c:1392
NTSTATUS NTAPI USBAudioPinSetDataFormat(_In_ PKSPIN Pin, _In_opt_ PKSDATAFORMAT OldFormat, _In_opt_ PKSMULTIPLE_ITEM OldAttributeList, _In_ const KSDATARANGE *DataRange, _In_opt_ const KSATTRIBUTE_LIST *AttributeRange)
Definition: pin.c:1298

Definition at line 79 of file filter.c.

Referenced by USBAudioPinBuildDescriptors().