1 /* 2 * PROJECT: ReactOS Universal Audio Class Driver 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: drivers/usb/usbaudio/filter.c 5 * PURPOSE: USB Audio device driver. 6 * PROGRAMMERS: 7 * Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9 10 #include "usbaudio.h" 11 12 GUID NodeTypeMicrophone = { STATIC_KSNODETYPE_MICROPHONE }; 13 GUID NodeTypeDesktopMicrophone = { STATIC_KSNODETYPE_DESKTOP_MICROPHONE }; 14 GUID NodeTypePersonalMicrophone = { STATIC_KSNODETYPE_PERSONAL_MICROPHONE }; 15 GUID NodeTypeOmmniMicrophone = { STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE }; 16 GUID NodeTypeArrayMicrophone = { STATIC_KSNODETYPE_MICROPHONE_ARRAY }; 17 GUID NodeTypeProcessingArrayMicrophone = { STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY }; 18 GUID NodeTypeSpeaker = { STATIC_KSNODETYPE_SPEAKER }; 19 GUID NodeTypeHeadphonesSpeaker = { STATIC_KSNODETYPE_HEADPHONES }; 20 GUID NodeTypeHMDA = { STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO }; 21 GUID NodeTypeDesktopSpeaker = { STATIC_KSNODETYPE_DESKTOP_SPEAKER }; 22 GUID NodeTypeRoomSpeaker = { STATIC_KSNODETYPE_ROOM_SPEAKER }; 23 GUID NodeTypeCommunicationSpeaker = { STATIC_KSNODETYPE_COMMUNICATION_SPEAKER }; 24 GUID NodeTypeSubwoofer = { STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER }; 25 GUID NodeTypeCapture = { STATIC_PINNAME_CAPTURE }; 26 GUID NodeTypePlayback = { STATIC_KSCATEGORY_AUDIO }; 27 GUID GUID_KSCATEGORY_AUDIO = { STATIC_KSCATEGORY_AUDIO }; 28 29 KSPIN_INTERFACE StandardPinInterface = 30 { 31 {STATIC_KSINTERFACESETID_Standard}, 32 KSINTERFACE_STANDARD_STREAMING, 33 0 34 }; 35 36 KSPIN_MEDIUM StandardPinMedium = 37 { 38 {STATIC_KSMEDIUMSETID_Standard}, 39 KSMEDIUM_TYPE_ANYINSTANCE, 40 0 41 }; 42 43 KSDATARANGE BridgePinAudioFormat[] = 44 { 45 { 46 { 47 sizeof(KSDATAFORMAT), 48 0, 49 0, 50 0, 51 {STATIC_KSDATAFORMAT_TYPE_AUDIO}, 52 {STATIC_KSDATAFORMAT_SUBTYPE_ANALOG}, 53 {STATIC_KSDATAFORMAT_SPECIFIER_NONE} 54 } 55 } 56 }; 57 58 static PKSDATARANGE BridgePinAudioFormats[] = 59 { 60 &BridgePinAudioFormat[0] 61 }; 62 63 static LPWSTR ReferenceString = L"global"; 64 65 NTSTATUS 66 NTAPI 67 USBAudioFilterCreate( 68 PKSFILTER Filter, 69 PIRP Irp); 70 71 static KSFILTER_DISPATCH USBAudioFilterDispatch = 72 { 73 USBAudioFilterCreate, 74 NULL, 75 NULL, 76 NULL 77 }; 78 79 static KSPIN_DISPATCH UsbAudioPinDispatch = 80 { 81 USBAudioPinCreate, 82 USBAudioPinClose, 83 USBAudioPinProcess, 84 USBAudioPinReset, 85 USBAudioPinSetDataFormat, 86 USBAudioPinSetDeviceState, 87 NULL, 88 NULL, 89 NULL, 90 NULL 91 }; 92 93 NTSTATUS NTAPI FilterAudioVolumeHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 94 NTSTATUS NTAPI FilterAudioMuteHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 95 96 DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME(FilterAudioVolumePropertySet, FilterAudioVolumeHandler); 97 DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE(FilterAudioMutePropertySet, FilterAudioMuteHandler); 98 99 100 static KSPROPERTY_SET FilterAudioVolumePropertySetArray[] = 101 { 102 { 103 &KSPROPSETID_Audio, 104 sizeof(FilterAudioVolumePropertySet) / sizeof(KSPROPERTY_ITEM), 105 (const KSPROPERTY_ITEM*)&FilterAudioVolumePropertySet, 106 0, 107 NULL 108 } 109 }; 110 111 static KSPROPERTY_SET FilterAudioMutePropertySetArray[] = 112 { 113 { 114 &KSPROPSETID_Audio, 115 sizeof(FilterAudioMutePropertySet) / sizeof(KSPROPERTY_ITEM), 116 (const KSPROPERTY_ITEM*)&FilterAudioMutePropertySet, 117 0, 118 NULL 119 } 120 }; 121 122 NTSTATUS 123 UsbAudioGetSetProperty( 124 IN PDEVICE_OBJECT DeviceObject, 125 IN UCHAR Request, 126 IN USHORT Value, 127 IN USHORT Index, 128 IN PVOID TransferBuffer, 129 IN ULONG TransferBufferLength, 130 IN ULONG TransferFlags) 131 { 132 PURB Urb; 133 NTSTATUS Status; 134 135 /* allocate urb */ 136 Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); 137 if (!Urb) 138 { 139 /* no memory */ 140 return STATUS_INSUFFICIENT_RESOURCES; 141 } 142 143 /* format urb */ 144 UsbBuildVendorRequest(Urb, 145 URB_FUNCTION_CLASS_INTERFACE, 146 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), 147 TransferFlags, 148 0, 149 Request, 150 Value, 151 Index, 152 TransferBuffer, 153 NULL, 154 TransferBufferLength, 155 NULL); 156 157 /* submit urb */ 158 Status = SubmitUrbSync(DeviceObject, Urb); 159 160 FreeFunction(Urb); 161 return Status; 162 } 163 164 PNODE_CONTEXT 165 FindNodeContextWithNode( 166 IN PNODE_CONTEXT NodeContext, 167 IN ULONG NodeContextCount, 168 IN ULONG NodeId) 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 } 183 184 185 NTSTATUS 186 NTAPI 187 FilterAudioMuteHandler( 188 IN PIRP Irp, 189 IN PKSIDENTIFIER Request, 190 IN OUT PVOID Data) 191 { 192 PKSNODEPROPERTY_AUDIO_CHANNEL Property; 193 PKSFILTER Filter; 194 PFILTER_CONTEXT FilterContext; 195 PNODE_CONTEXT NodeContext; 196 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor; 197 NTSTATUS Status = STATUS_INVALID_PARAMETER; 198 199 /* get filter from irp */ 200 Filter = KsGetFilterFromIrp(Irp); 201 202 if (Filter) 203 { 204 /* get property */ 205 Property = (PKSNODEPROPERTY_AUDIO_CHANNEL)Request; 206 207 /* get filter context */ 208 FilterContext = (PFILTER_CONTEXT)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 } 228 229 NTSTATUS 230 NTAPI 231 FilterAudioVolumeHandler( 232 IN PIRP Irp, 233 IN PKSIDENTIFIER Request, 234 IN OUT PVOID Data) 235 { 236 PKSNODEPROPERTY_AUDIO_CHANNEL Property; 237 PKSFILTER Filter; 238 PFILTER_CONTEXT FilterContext; 239 PNODE_CONTEXT NodeContext; 240 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor; 241 PSHORT TransferBuffer; 242 LONG Value; 243 NTSTATUS Status = STATUS_INVALID_PARAMETER; 244 245 246 /* get filter from irp */ 247 Filter = KsGetFilterFromIrp(Irp); 248 249 if (Filter) 250 { 251 /* get property */ 252 Property = (PKSNODEPROPERTY_AUDIO_CHANNEL)Request; 253 254 /* get filter context */ 255 FilterContext = (PFILTER_CONTEXT)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 } 316 317 318 ULONG 319 CountTopologyComponents( 320 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 321 OUT PULONG OutDescriptorCount) 322 { 323 PUSB_INTERFACE_DESCRIPTOR Descriptor; 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; 328 PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor; 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 { 394 UNIMPLEMENTED; 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 } 406 407 PNODE_CONTEXT 408 FindNodeContextWithId( 409 IN PNODE_CONTEXT NodeContext, 410 IN ULONG NodeContextCount, 411 IN UCHAR TerminalId) 412 { 413 ULONG Index; 414 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor; 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 } 424 425 NTSTATUS 426 BuildUSBAudioFilterTopology( 427 PKSDEVICE Device, 428 PKSFILTER_DESCRIPTOR FilterDescriptor) 429 { 430 PDEVICE_EXTENSION DeviceExtension; 431 ULONG NodeCount, Index, DescriptorCount, StreamingTerminalIndex, NonStreamingTerminalDescriptorCount, TotalTerminalDescriptorCount, StreamingTerminalPinOffset, ControlDescriptorCount, Length; 432 UCHAR Value; 433 PUSB_INTERFACE_DESCRIPTOR Descriptor; 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; 438 PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor; 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; 443 PKSTOPOLOGY_CONNECTION Connections; 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 */ 457 return STATUS_INSUFFICIENT_RESOURCES; 458 } 459 FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR); 460 461 DeviceExtension->NodeContext = NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount); 462 if (!NodeContext) 463 { 464 /* no memory */ 465 return STATUS_INSUFFICIENT_RESOURCES; 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 { 746 UNIMPLEMENTED; 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 */ 761 return STATUS_INSUFFICIENT_RESOURCES; 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 { 910 UNIMPLEMENTED; 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 } 924 925 NTSTATUS 926 NTAPI 927 USBAudioFilterCreate( 928 PKSFILTER Filter, 929 PIRP Irp) 930 { 931 PKSFILTERFACTORY FilterFactory; 932 PKSDEVICE Device; 933 PFILTER_CONTEXT FilterContext; 934 935 FilterFactory = KsGetParent(Filter); 936 if (FilterFactory == NULL) 937 { 938 /* invalid parameter */ 939 return STATUS_INVALID_PARAMETER; 940 } 941 942 Device = KsGetParent(FilterFactory); 943 if (Device == NULL) 944 { 945 /* invalid parameter */ 946 return STATUS_INVALID_PARAMETER; 947 } 948 949 /* alloc filter context */ 950 FilterContext = AllocFunction(sizeof(FILTER_CONTEXT)); 951 if (FilterContext == NULL) 952 { 953 /* no memory */ 954 return STATUS_INSUFFICIENT_RESOURCES; 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); 963 KsAddItemToObjectBag(Filter->Bag, FilterContext, ExFreePool); 964 return STATUS_SUCCESS; 965 } 966 967 968 VOID 969 NTAPI 970 CountTerminalUnits( 971 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 972 OUT PULONG NonStreamingTerminalDescriptorCount, 973 OUT PULONG TotalTerminalDescriptorCount) 974 { 975 PUSB_INTERFACE_DESCRIPTOR Descriptor; 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 { 1011 UNIMPLEMENTED; 1012 } 1013 } 1014 *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount; 1015 *TotalTerminalDescriptorCount = TotalTerminalCount; 1016 } 1017 1018 LPGUID 1019 UsbAudioGetPinCategoryFromTerminalDescriptor( 1020 IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor) 1021 { 1022 if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE) 1023 return &NodeTypeMicrophone; 1024 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE) 1025 return &NodeTypeDesktopMicrophone; 1026 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE) 1027 return &NodeTypePersonalMicrophone; 1028 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE) 1029 return &NodeTypeOmmniMicrophone; 1030 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE) 1031 return &NodeTypeArrayMicrophone; 1032 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE) 1033 return &NodeTypeProcessingArrayMicrophone; 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) 1039 return &NodeTypeHeadphonesSpeaker; 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) 1047 return &NodeTypeCommunicationSpeaker; 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 } 1061 1062 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR 1063 UsbAudioGetStreamingTerminalDescriptorByIndex( 1064 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 1065 IN ULONG Index) 1066 { 1067 PUSB_INTERFACE_DESCRIPTOR Descriptor; 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 } 1106 1107 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR 1108 UsbAudioGetNonStreamingTerminalDescriptorByIndex( 1109 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 1110 IN ULONG Index) 1111 { 1112 1113 PUSB_INTERFACE_DESCRIPTOR Descriptor; 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 } 1152 1153 VOID 1154 UsbAudioGetDataRanges( 1155 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 1156 IN UCHAR bTerminalID, 1157 OUT PKSDATARANGE** OutDataRanges, 1158 OUT PULONG OutDataRangesCount) 1159 { 1160 PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR StreamingInterfaceDescriptor; 1161 PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR StreamingFormatDescriptor; 1162 PUSB_INTERFACE_DESCRIPTOR Descriptor; 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); 1224 DataRangeAudio->DataRange.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; 1225 DataRangeAudio->DataRange.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 1226 DataRangeAudio->DataRange.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; 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 } 1249 1250 1251 NTSTATUS 1252 USBAudioPinBuildDescriptors( 1253 PKSDEVICE Device, 1254 PKSPIN_DESCRIPTOR_EX *PinDescriptors, 1255 PULONG PinDescriptorsCount, 1256 PULONG PinDescriptorSize) 1257 { 1258 PDEVICE_EXTENSION DeviceExtension; 1259 PKSPIN_DESCRIPTOR_EX Pins; 1260 ULONG TotalTerminalDescriptorCount = 0; 1261 ULONG NonStreamingTerminalDescriptorCount = 0; 1262 ULONG Index = 0; 1263 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor = NULL; 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*/ 1276 return STATUS_INSUFFICIENT_RESOURCES; 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 } 1349 1350 NTSTATUS 1351 NTAPI 1352 USBAudioGetDescriptor( 1353 IN PDEVICE_OBJECT DeviceObject, 1354 IN UCHAR DescriptorType, 1355 IN ULONG DescriptorLength, 1356 IN UCHAR DescriptorIndex, 1357 IN LANGID LanguageId, 1358 OUT PVOID *OutDescriptor) 1359 { 1360 PURB Urb; 1361 NTSTATUS Status; 1362 PVOID Descriptor; 1363 1364 /* sanity checks */ 1365 ASSERT(DeviceObject); 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 */ 1376 return STATUS_INSUFFICIENT_RESOURCES; 1377 } 1378 1379 /* allocate urb */ 1380 Urb = (PURB)AllocFunction(sizeof(URB)); 1381 if (!Urb) 1382 { 1383 /* no memory */ 1384 FreeFunction(Descriptor); 1385 return STATUS_INSUFFICIENT_RESOURCES; 1386 } 1387 1388 /* initialize urb */ 1389 UsbBuildGetDescriptorRequest(Urb, 1390 sizeof(Urb->UrbControlDescriptorRequest), 1391 DescriptorType, 1392 DescriptorIndex, 1393 LanguageId, 1394 Descriptor, 1395 NULL, 1396 DescriptorLength, 1397 NULL); 1398 1399 /* submit urb */ 1400 Status = SubmitUrbSync(DeviceObject, 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 */ 1413 FreeFunction(Descriptor); 1414 } 1415 1416 /* done */ 1417 return Status; 1418 } 1419 1420 NTSTATUS 1421 NTAPI 1422 USBAudioGetStringDescriptor( 1423 IN PDEVICE_OBJECT DeviceObject, 1424 IN ULONG DescriptorLength, 1425 IN UCHAR DescriptorIndex, 1426 IN LANGID LanguageId, 1427 OUT PVOID *OutDescriptor) 1428 { 1429 NTSTATUS Status; 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 } 1440 1441 NTSTATUS 1442 USBAudioRegCreateMediaCategoriesKey( 1443 IN PUNICODE_STRING Name, 1444 OUT PHANDLE OutHandle) 1445 { 1446 NTSTATUS Status; 1447 OBJECT_ATTRIBUTES ObjectAttributes; 1448 UNICODE_STRING DestinationString; 1449 HANDLE Handle; 1450 1451 /* initialize root name*/ 1452 RtlInitUnicodeString(&DestinationString, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\"); 1453 1454 /* initialize object attributes */ 1455 InitializeObjectAttributes(&ObjectAttributes, &DestinationString, OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_KERNEL_HANDLE, NULL, NULL); 1456 1457 /* create the key */ 1458 Status = ZwOpenKey(&Handle, KEY_ALL_ACCESS, &ObjectAttributes); 1459 if (NT_SUCCESS(Status)) 1460 { 1461 /* initialize object attributes */ 1462 InitializeObjectAttributes(&ObjectAttributes, Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, Handle, NULL); 1463 1464 Status = ZwCreateKey(OutHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL); 1465 ZwClose(Handle); 1466 1467 } 1468 return Status; 1469 } 1470 1471 1472 NTSTATUS 1473 USBAudioInitComponentId( 1474 PKSDEVICE Device, 1475 IN PKSCOMPONENTID ComponentId) 1476 { 1477 PDEVICE_EXTENSION DeviceExtension; 1478 NTSTATUS Status; 1479 LPWSTR DescriptionBuffer; 1480 UNICODE_STRING GuidString; 1481 UNICODE_STRING Name; 1482 HANDLE hKey; 1483 GUID TempGuid; 1484 1485 /* get device extension */ 1486 DeviceExtension = Device->Context; 1487 1488 /* init component id */ 1489 ComponentId->Component = KSCOMPONENTID_USBAUDIO; 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 { 1505 Status = USBAudioRegCreateMediaCategoriesKey(&GuidString, &hKey); 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 } 1514 RtlFreeUnicodeString(&GuidString); 1515 } 1516 FreeFunction(DescriptionBuffer); 1517 } 1518 } 1519 return STATUS_SUCCESS; 1520 } 1521 1522 1523 NTSTATUS 1524 NTAPI 1525 USBAudioCreateFilterContext( 1526 PKSDEVICE Device) 1527 { 1528 PKSFILTER_DESCRIPTOR FilterDescriptor; 1529 PKSCOMPONENTID ComponentId; 1530 NTSTATUS Status; 1531 1532 /* allocate descriptor */ 1533 FilterDescriptor = AllocFunction(sizeof(KSFILTER_DESCRIPTOR)); 1534 if (!FilterDescriptor) 1535 { 1536 /* no memory */ 1537 return USBD_STATUS_INSUFFICIENT_RESOURCES; 1538 } 1539 1540 /* init filter descriptor*/ 1541 FilterDescriptor->Version = KSFILTER_DESCRIPTOR_VERSION; 1542 FilterDescriptor->Flags = 0; 1543 FilterDescriptor->ReferenceGuid = &KSNAME_Filter; 1544 FilterDescriptor->Dispatch = &USBAudioFilterDispatch; 1545 FilterDescriptor->CategoriesCount = 1; 1546 FilterDescriptor->Categories = &GUID_KSCATEGORY_AUDIO; 1547 1548 /* init component id*/ 1549 ComponentId = AllocFunction(sizeof(KSCOMPONENTID)); 1550 if (!ComponentId) 1551 { 1552 /* no memory */ 1553 return STATUS_INSUFFICIENT_RESOURCES; 1554 } 1555 Status = USBAudioInitComponentId(Device, ComponentId); 1556 if (!NT_SUCCESS(Status)) 1557 { 1558 /* failed*/ 1559 FreeFunction(ComponentId); 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*/ 1569 FreeFunction(ComponentId); 1570 return Status; 1571 } 1572 1573 /* build topology */ 1574 Status = BuildUSBAudioFilterTopology(Device, FilterDescriptor); 1575 if (!NT_SUCCESS(Status)) 1576 { 1577 /* failed*/ 1578 FreeFunction(ComponentId); 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 } 1588 1589 1590