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 PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR SelectorUnitDescriptor; 330 ULONG NodeCount = 0, Length, Index; 331 ULONG DescriptorCount = 0; 332 UCHAR Value; 333 334 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); 335 Descriptor != NULL; 336 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) 337 { 338 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */ 339 { 340 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 341 if (InterfaceHeaderDescriptor != NULL) 342 { 343 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 344 while (CommonDescriptor) 345 { 346 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; 347 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) 348 { 349 NodeCount++; 350 DescriptorCount++; 351 } 352 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/) 353 { 354 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor; 355 DescriptorCount++; 356 357 /* get controls from all channels*/ 358 Value = 0; 359 Length = FeatureUnitDescriptor->bLength - 7; 360 for (Index = 0; Index < Length; Index++) 361 { 362 Value |= FeatureUnitDescriptor->bmaControls[Index]; 363 } 364 365 if (Value & 0x01) /* MUTE*/ 366 NodeCount++; 367 if (Value & 0x02) /* VOLUME */ 368 NodeCount++; 369 if (Value & 0x04) /* BASS */ 370 NodeCount++; 371 if (Value & 0x08) /* MID */ 372 NodeCount++; 373 if (Value & 0x10) /* TREBLE */ 374 NodeCount++; 375 if (Value & 0x20) /* GRAPHIC EQUALIZER */ 376 NodeCount++; 377 if (Value & 0x40) /* AUTOMATIC GAIN */ 378 NodeCount++; 379 if (Value & 0x80) /* DELAY */ 380 NodeCount++; 381 } 382 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */) 383 { 384 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor; 385 DescriptorCount++; 386 NodeCount += MixerUnitDescriptor->bNrInPins + 1; /* KSNODETYPE_SUPERMIX for each source pin and KSNODETYPE_SUM for target */ 387 } 388 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR_UNIT */) 389 { 390 SelectorUnitDescriptor = (PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR)InputTerminalDescriptor; 391 DescriptorCount++; 392 NodeCount++; 393 } 394 else 395 { 396 UNIMPLEMENTED; 397 } 398 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); 399 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) 400 break; 401 } 402 } 403 } 404 } 405 *OutDescriptorCount = DescriptorCount; 406 return NodeCount; 407 } 408 409 PNODE_CONTEXT 410 FindNodeContextWithId( 411 IN PNODE_CONTEXT NodeContext, 412 IN ULONG NodeContextCount, 413 IN UCHAR TerminalId) 414 { 415 ULONG Index; 416 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor; 417 418 for (Index = 0; Index < NodeContextCount; Index++) 419 { 420 TerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)NodeContext[Index].Descriptor; 421 if (TerminalDescriptor->bTerminalID == TerminalId) 422 return &NodeContext[Index]; 423 } 424 return NULL; 425 } 426 427 NTSTATUS 428 BuildUSBAudioFilterTopology( 429 PKSDEVICE Device, 430 PKSFILTER_DESCRIPTOR FilterDescriptor) 431 { 432 PDEVICE_EXTENSION DeviceExtension; 433 ULONG NodeCount, Index, DescriptorCount, StreamingTerminalIndex, NonStreamingTerminalDescriptorCount, TotalTerminalDescriptorCount, StreamingTerminalPinOffset, ControlDescriptorCount, Length; 434 UCHAR Value; 435 PUSB_INTERFACE_DESCRIPTOR Descriptor; 436 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor; 437 PUSB_COMMON_DESCRIPTOR CommonDescriptor; 438 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor; 439 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor; 440 PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor; 441 PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR OutputTerminalDescriptor; 442 PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR SelectorUnitDescriptor; 443 PKSNODE_DESCRIPTOR NodeDescriptors; 444 PNODE_CONTEXT NodeContext, PreviousNodeContext; 445 PKSTOPOLOGY_CONNECTION Connections; 446 PKSAUTOMATION_TABLE AutomationTable; 447 448 /* get device extension */ 449 DeviceExtension = Device->Context; 450 451 /* count topology nodes */ 452 NodeCount = CountTopologyComponents(DeviceExtension->ConfigurationDescriptor, &ControlDescriptorCount); 453 454 /* init node descriptors*/ 455 FilterDescriptor->NodeDescriptors = NodeDescriptors = AllocFunction(NodeCount * sizeof(KSNODE_DESCRIPTOR)); 456 if (FilterDescriptor->NodeDescriptors == NULL) 457 { 458 /* no memory */ 459 return STATUS_INSUFFICIENT_RESOURCES; 460 } 461 FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR); 462 463 DeviceExtension->NodeContext = NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount); 464 if (!NodeContext) 465 { 466 /* no memory */ 467 return STATUS_INSUFFICIENT_RESOURCES; 468 } 469 DeviceExtension->NodeContextCount = ControlDescriptorCount; 470 DescriptorCount = 0; 471 472 /* first enumerate all topology nodes */ 473 for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); 474 Descriptor != NULL; 475 Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) 476 { 477 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */ 478 { 479 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 480 if (InterfaceHeaderDescriptor != NULL) 481 { 482 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 483 while (CommonDescriptor) 484 { 485 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; 486 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/) 487 { 488 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) 489 { 490 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC; 491 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC; 492 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 493 494 /* insert into node context*/ 495 NodeContext[DescriptorCount].Descriptor = CommonDescriptor; 496 NodeContext[DescriptorCount].NodeCount = 1; 497 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount; 498 DescriptorCount++; 499 500 FilterDescriptor->NodeDescriptorsCount++; 501 } 502 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x200) 503 { 504 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_ADC; 505 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_ADC; 506 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 507 508 /* insert into node context*/ 509 NodeContext[DescriptorCount].Descriptor = CommonDescriptor; 510 NodeContext[DescriptorCount].NodeCount = 1; 511 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount; 512 DescriptorCount++; 513 514 515 FilterDescriptor->NodeDescriptorsCount++; 516 } 517 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300) 518 { 519 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC; 520 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC; 521 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 522 523 /* insert into node context*/ 524 NodeContext[DescriptorCount].Descriptor = CommonDescriptor; 525 NodeContext[DescriptorCount].NodeCount = 1; 526 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount; 527 DescriptorCount++; 528 529 FilterDescriptor->NodeDescriptorsCount++; 530 } 531 else 532 { 533 DPRINT1("Unexpected input terminal type %x\n", InputTerminalDescriptor->wTerminalType); 534 } 535 } 536 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) 537 { 538 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) 539 { 540 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC; 541 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC; 542 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 543 544 /* insert into node context*/ 545 NodeContext[DescriptorCount].Descriptor = CommonDescriptor; 546 NodeContext[DescriptorCount].NodeCount = 1; 547 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount; 548 DescriptorCount++; 549 550 FilterDescriptor->NodeDescriptorsCount++; 551 } 552 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300) 553 { 554 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC; 555 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC; 556 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 557 558 /* insert into node context*/ 559 NodeContext[DescriptorCount].Descriptor = CommonDescriptor; 560 NodeContext[DescriptorCount].NodeCount = 1; 561 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount; 562 DescriptorCount++; 563 564 FilterDescriptor->NodeDescriptorsCount++; 565 } 566 else 567 { 568 DPRINT1("Unexpected output terminal type %x\n", InputTerminalDescriptor->wTerminalType); 569 } 570 } 571 572 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/) 573 { 574 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)CommonDescriptor; 575 576 /* get controls from all channels*/ 577 Value = 0; 578 Length = FeatureUnitDescriptor->bLength - 7; 579 for (Index = 0; Index < Length; Index++) 580 { 581 Value |= FeatureUnitDescriptor->bmaControls[Index]; 582 } 583 584 585 if (Value & 0x01) /* MUTE*/ 586 { 587 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUTE; 588 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUTE; 589 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 590 if (AutomationTable) 591 { 592 AutomationTable->PropertySets = FilterAudioMutePropertySetArray; 593 AutomationTable->PropertySetsCount = 1; 594 AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM); 595 } 596 597 /* insert into node context*/ 598 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 599 NodeContext[DescriptorCount].NodeCount++; 600 601 FilterDescriptor->NodeDescriptorsCount++; 602 } 603 if (Value & 0x02) /* VOLUME */ 604 { 605 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_VOLUME; 606 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_VOLUME; 607 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 608 if (AutomationTable) 609 { 610 AutomationTable->PropertySets = FilterAudioVolumePropertySetArray; 611 AutomationTable->PropertySetsCount = 1; 612 AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM); 613 } 614 615 /* insert into node context*/ 616 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 617 NodeContext[DescriptorCount].NodeCount++; 618 619 FilterDescriptor->NodeDescriptorsCount++; 620 } 621 622 if (Value & 0x04) /* BASS */ 623 { 624 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; 625 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; 626 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 627 628 /* insert into node context*/ 629 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 630 NodeContext[DescriptorCount].NodeCount++; 631 632 FilterDescriptor->NodeDescriptorsCount++; 633 } 634 635 if (Value & 0x08) /* MID */ 636 { 637 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; 638 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; 639 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 640 641 /* insert into node context*/ 642 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 643 NodeContext[DescriptorCount].NodeCount++; 644 645 FilterDescriptor->NodeDescriptorsCount++; 646 } 647 648 if (Value & 0x10) /* TREBLE */ 649 { 650 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; 651 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; 652 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 653 654 /* insert into node context*/ 655 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 656 NodeContext[DescriptorCount].NodeCount++; 657 658 659 FilterDescriptor->NodeDescriptorsCount++; 660 } 661 662 if (Value & 0x20) /* GRAPHIC EQUALIZER */ 663 { 664 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; 665 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; 666 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 667 668 /* insert into node context*/ 669 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 670 NodeContext[DescriptorCount].NodeCount++; 671 672 FilterDescriptor->NodeDescriptorsCount++; 673 } 674 675 if (Value & 0x40) /* AUTOMATIC GAIN */ 676 { 677 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_AGC; 678 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_AGC; 679 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 680 681 /* insert into node context*/ 682 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 683 NodeContext[DescriptorCount].NodeCount++; 684 685 686 FilterDescriptor->NodeDescriptorsCount++; 687 } 688 689 if (Value & 0x80) /* DELAY */ 690 { 691 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE; 692 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE; 693 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 694 695 /* insert into node context*/ 696 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 697 NodeContext[DescriptorCount].NodeCount++; 698 699 FilterDescriptor->NodeDescriptorsCount++; 700 } 701 NodeContext[DescriptorCount].Descriptor = CommonDescriptor; 702 DescriptorCount++; 703 704 } 705 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */) 706 { 707 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)CommonDescriptor; 708 for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++) 709 { 710 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUPERMIX; 711 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUPERMIX; 712 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 713 714 /* insert into node context*/ 715 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 716 NodeContext[DescriptorCount].NodeCount++; 717 718 FilterDescriptor->NodeDescriptorsCount++; 719 } 720 721 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUM; 722 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUM; 723 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 724 725 /* insert into node context*/ 726 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount; 727 NodeContext[DescriptorCount].NodeCount++; 728 NodeContext[DescriptorCount].Descriptor = CommonDescriptor; 729 DescriptorCount++; 730 731 FilterDescriptor->NodeDescriptorsCount++; 732 } 733 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR UNIT */) 734 { 735 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUX; 736 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUX; 737 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE)); 738 739 /* insert into node context*/ 740 NodeContext[DescriptorCount].Descriptor = CommonDescriptor; 741 NodeContext[DescriptorCount].NodeCount = 1; 742 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount; 743 DescriptorCount++; 744 FilterDescriptor->NodeDescriptorsCount++; 745 } 746 else 747 { 748 UNIMPLEMENTED; 749 } 750 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); 751 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) 752 break; 753 } 754 } 755 } 756 } 757 758 /* FIXME determine connections count*/ 759 FilterDescriptor->Connections = Connections = AllocFunction(sizeof(KSTOPOLOGY_CONNECTION) * FilterDescriptor->NodeDescriptorsCount * 2); 760 if (!FilterDescriptor->Connections) 761 { 762 /* no memory */ 763 return STATUS_INSUFFICIENT_RESOURCES; 764 } 765 FilterDescriptor->ConnectionsCount = 0; 766 767 /* now build connections array */ 768 DescriptorCount = 0; 769 StreamingTerminalIndex = 0; 770 NodeCount = 0; 771 772 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount); 773 StreamingTerminalPinOffset = TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount; 774 775 for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); 776 Descriptor != NULL; 777 Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) 778 { 779 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */ 780 { 781 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 782 if (InterfaceHeaderDescriptor != NULL) 783 { 784 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 785 while (CommonDescriptor) 786 { 787 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; 788 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/) 789 { 790 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) 791 { 792 Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE; 793 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalIndex; 794 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1; 795 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0]; 796 FilterDescriptor->ConnectionsCount++; 797 StreamingTerminalIndex++; 798 799 } 800 else 801 { 802 Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE; 803 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalPinOffset; 804 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1; 805 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0]; 806 FilterDescriptor->ConnectionsCount++; 807 StreamingTerminalPinOffset++; 808 } 809 DescriptorCount++; 810 } 811 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) 812 { 813 OutputTerminalDescriptor = (PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; 814 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, OutputTerminalDescriptor->bSourceID); 815 if (PreviousNodeContext) 816 { 817 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1]; 818 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0; 819 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1; 820 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0]; 821 FilterDescriptor->ConnectionsCount++; 822 } 823 824 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) 825 { 826 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0]; 827 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0; 828 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalIndex; 829 Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE; 830 FilterDescriptor->ConnectionsCount++; 831 StreamingTerminalIndex++; 832 } 833 else 834 { 835 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0]; 836 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0; 837 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalPinOffset; 838 Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE; 839 FilterDescriptor->ConnectionsCount++; 840 841 StreamingTerminalPinOffset++; 842 } 843 DescriptorCount++; 844 } 845 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/) 846 { 847 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor; 848 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, FeatureUnitDescriptor->bSourceID); 849 if (PreviousNodeContext) 850 { 851 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount-1]; 852 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0; 853 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1; 854 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0]; 855 FilterDescriptor->ConnectionsCount++; 856 } 857 for (Index = 1; Index < NodeContext[DescriptorCount].NodeCount; Index++) 858 { 859 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index - 1]; 860 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0; 861 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1; 862 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index]; 863 FilterDescriptor->ConnectionsCount++; 864 } 865 866 DescriptorCount++; 867 } 868 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */) 869 { 870 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor; 871 for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++) 872 { 873 Value = MixerUnitDescriptor->baSourceID[Index]; 874 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value); 875 if (PreviousNodeContext) 876 { 877 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1]; 878 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0; 879 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1; 880 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index]; 881 FilterDescriptor->ConnectionsCount++; 882 } 883 884 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index]; 885 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0; 886 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1 + Index; 887 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount-1]; 888 FilterDescriptor->ConnectionsCount++; 889 } 890 DescriptorCount++; 891 } 892 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR_UNIT */) 893 { 894 SelectorUnitDescriptor = (PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR)InputTerminalDescriptor; 895 for (Index = 0; Index < SelectorUnitDescriptor->bNrInPins; Index++) 896 { 897 Value = SelectorUnitDescriptor->baSourceID[Index]; 898 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value); 899 if (PreviousNodeContext) 900 { 901 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1]; 902 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0; 903 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1; 904 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0]; 905 FilterDescriptor->ConnectionsCount++; 906 } 907 } 908 DescriptorCount++; 909 } 910 else 911 { 912 UNIMPLEMENTED; 913 } 914 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); 915 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) 916 break; 917 } 918 } 919 } 920 } 921 922 923 924 return STATUS_SUCCESS; 925 } 926 927 NTSTATUS 928 NTAPI 929 USBAudioFilterCreate( 930 PKSFILTER Filter, 931 PIRP Irp) 932 { 933 PKSFILTERFACTORY FilterFactory; 934 PKSDEVICE Device; 935 PFILTER_CONTEXT FilterContext; 936 937 FilterFactory = KsGetParent(Filter); 938 if (FilterFactory == NULL) 939 { 940 /* invalid parameter */ 941 return STATUS_INVALID_PARAMETER; 942 } 943 944 Device = KsGetParent(FilterFactory); 945 if (Device == NULL) 946 { 947 /* invalid parameter */ 948 return STATUS_INVALID_PARAMETER; 949 } 950 951 /* alloc filter context */ 952 FilterContext = AllocFunction(sizeof(FILTER_CONTEXT)); 953 if (FilterContext == NULL) 954 { 955 /* no memory */ 956 return STATUS_INSUFFICIENT_RESOURCES; 957 } 958 959 /* init context */ 960 FilterContext->DeviceExtension = Device->Context; 961 FilterContext->LowerDevice = Device->NextDeviceObject; 962 Filter->Context = FilterContext; 963 964 DPRINT("USBAudioFilterCreate FilterContext %p LowerDevice %p DeviceExtension %p\n", FilterContext, FilterContext->LowerDevice, FilterContext->DeviceExtension); 965 KsAddItemToObjectBag(Filter->Bag, FilterContext, ExFreePool); 966 return STATUS_SUCCESS; 967 } 968 969 970 VOID 971 NTAPI 972 CountTerminalUnits( 973 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 974 OUT PULONG NonStreamingTerminalDescriptorCount, 975 OUT PULONG TotalTerminalDescriptorCount) 976 { 977 PUSB_INTERFACE_DESCRIPTOR Descriptor; 978 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor; 979 PUSB_COMMON_DESCRIPTOR CommonDescriptor; 980 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor; 981 ULONG NonStreamingTerminalCount = 0; 982 ULONG TotalTerminalCount = 0; 983 984 for(Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); 985 Descriptor != NULL; 986 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) 987 { 988 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */ 989 { 990 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 991 if (InterfaceHeaderDescriptor != NULL) 992 { 993 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 994 while (CommonDescriptor) 995 { 996 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; 997 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) 998 { 999 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE) 1000 { 1001 NonStreamingTerminalCount++; 1002 } 1003 TotalTerminalCount++; 1004 } 1005 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); 1006 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) 1007 break; 1008 } 1009 } 1010 } 1011 else if (Descriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING */ 1012 { 1013 UNIMPLEMENTED; 1014 } 1015 } 1016 *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount; 1017 *TotalTerminalDescriptorCount = TotalTerminalCount; 1018 } 1019 1020 LPGUID 1021 UsbAudioGetPinCategoryFromTerminalDescriptor( 1022 IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor) 1023 { 1024 if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE) 1025 return &NodeTypeMicrophone; 1026 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE) 1027 return &NodeTypeDesktopMicrophone; 1028 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE) 1029 return &NodeTypePersonalMicrophone; 1030 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE) 1031 return &NodeTypeOmmniMicrophone; 1032 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE) 1033 return &NodeTypeArrayMicrophone; 1034 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE) 1035 return &NodeTypeProcessingArrayMicrophone; 1036 1037 /* playback types */ 1038 if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE) 1039 return &NodeTypeSpeaker; 1040 else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE) 1041 return &NodeTypeHeadphonesSpeaker; 1042 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE) 1043 return &NodeTypeHMDA; 1044 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE) 1045 return &NodeTypeDesktopSpeaker; 1046 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE) 1047 return &NodeTypeRoomSpeaker; 1048 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE) 1049 return &NodeTypeCommunicationSpeaker; 1050 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE) 1051 return &NodeTypeSubwoofer; 1052 1053 if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) 1054 { 1055 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL) 1056 return &NodeTypeCapture; 1057 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL) 1058 return &NodeTypePlayback; 1059 1060 } 1061 return NULL; 1062 } 1063 1064 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR 1065 UsbAudioGetStreamingTerminalDescriptorByIndex( 1066 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 1067 IN ULONG Index) 1068 { 1069 PUSB_INTERFACE_DESCRIPTOR Descriptor; 1070 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor; 1071 PUSB_COMMON_DESCRIPTOR CommonDescriptor; 1072 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor; 1073 ULONG TerminalCount = 0; 1074 1075 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); 1076 Descriptor != NULL; 1077 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) 1078 { 1079 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */ 1080 { 1081 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 1082 if (InterfaceHeaderDescriptor != NULL) 1083 { 1084 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 1085 while (CommonDescriptor) 1086 { 1087 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; 1088 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) 1089 { 1090 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE) 1091 { 1092 if (TerminalCount == Index) 1093 { 1094 return InputTerminalDescriptor; 1095 } 1096 TerminalCount++; 1097 } 1098 } 1099 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); 1100 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) 1101 break; 1102 } 1103 } 1104 } 1105 } 1106 return NULL; 1107 } 1108 1109 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR 1110 UsbAudioGetNonStreamingTerminalDescriptorByIndex( 1111 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 1112 IN ULONG Index) 1113 { 1114 1115 PUSB_INTERFACE_DESCRIPTOR Descriptor; 1116 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor; 1117 PUSB_COMMON_DESCRIPTOR CommonDescriptor; 1118 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor; 1119 ULONG TerminalCount = 0; 1120 1121 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); 1122 Descriptor != NULL; 1123 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) 1124 { 1125 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */ 1126 { 1127 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 1128 if (InterfaceHeaderDescriptor != NULL) 1129 { 1130 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 1131 while (CommonDescriptor) 1132 { 1133 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor; 1134 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/) 1135 { 1136 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE) 1137 { 1138 if (TerminalCount == Index) 1139 { 1140 return InputTerminalDescriptor; 1141 } 1142 TerminalCount++; 1143 } 1144 } 1145 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); 1146 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength)) 1147 break; 1148 } 1149 } 1150 } 1151 } 1152 return NULL; 1153 } 1154 1155 VOID 1156 UsbAudioGetDataRanges( 1157 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 1158 IN UCHAR bTerminalID, 1159 OUT PKSDATARANGE** OutDataRanges, 1160 OUT PULONG OutDataRangesCount) 1161 { 1162 PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR StreamingInterfaceDescriptor; 1163 PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR StreamingFormatDescriptor; 1164 PUSB_INTERFACE_DESCRIPTOR Descriptor; 1165 PKSDATARANGE_AUDIO DataRangeAudio; 1166 PKSDATARANGE *DataRangeAudioArray; 1167 ULONG NumFrequency, DataRangeCount, DataRangeIndex, Index; 1168 1169 /* count all data ranges */ 1170 DataRangeCount = 0; 1171 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); 1172 Descriptor != NULL; 1173 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) 1174 { 1175 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */ 1176 { 1177 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 1178 if (StreamingInterfaceDescriptor != NULL) 1179 { 1180 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01); 1181 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM); 1182 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID) 1183 { 1184 DataRangeCount++; 1185 DPRINT1("StreamingInterfaceDescriptor %p TerminalID %x\n", StreamingInterfaceDescriptor, bTerminalID); 1186 } 1187 } 1188 Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor; 1189 } 1190 } 1191 1192 DataRangeAudioArray = AllocFunction(sizeof(PVOID) * DataRangeCount); 1193 if (DataRangeAudioArray == NULL) 1194 { 1195 /* no memory */ 1196 return; 1197 } 1198 1199 DataRangeIndex = 0; 1200 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); 1201 Descriptor != NULL; 1202 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1)) 1203 { 1204 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */ 1205 { 1206 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE); 1207 if (StreamingInterfaceDescriptor != NULL) 1208 { 1209 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01); 1210 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM); 1211 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID) 1212 { 1213 StreamingFormatDescriptor = (PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR)((ULONG_PTR)StreamingInterfaceDescriptor + StreamingInterfaceDescriptor->bLength); 1214 ASSERT(StreamingFormatDescriptor->bDescriptorType == 0x24); 1215 ASSERT(StreamingFormatDescriptor->bDescriptorSubtype == 0x02); 1216 ASSERT(StreamingFormatDescriptor->bFormatType == 0x01); 1217 1218 DataRangeAudio = AllocFunction(sizeof(KSDATARANGE_AUDIO)); 1219 if (DataRangeAudio == NULL) 1220 { 1221 /* no memory*/ 1222 return; 1223 } 1224 1225 DataRangeAudio->DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO); 1226 DataRangeAudio->DataRange.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; 1227 DataRangeAudio->DataRange.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 1228 DataRangeAudio->DataRange.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; 1229 DataRangeAudio->MaximumChannels = StreamingFormatDescriptor->bNrChannels; 1230 DataRangeAudio->MinimumBitsPerSample = StreamingFormatDescriptor->bBitResolution; 1231 DataRangeAudio->MaximumBitsPerSample = StreamingFormatDescriptor->bBitResolution; 1232 NumFrequency = StreamingFormatDescriptor->bSamFreqType; 1233 DataRangeAudio->MinimumSampleFrequency = MAXULONG; 1234 DataRangeAudio->MaximumSampleFrequency = 0; 1235 for (Index = 0; Index < NumFrequency; Index++) 1236 { 1237 DataRangeAudio->MinimumSampleFrequency = min(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MinimumSampleFrequency); 1238 DataRangeAudio->MaximumSampleFrequency = max(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MaximumSampleFrequency); 1239 } 1240 DataRangeAudioArray[DataRangeIndex] = (PKSDATARANGE)DataRangeAudio; 1241 DataRangeIndex++; 1242 } 1243 } 1244 Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor; 1245 } 1246 } 1247 1248 *OutDataRanges = DataRangeAudioArray; 1249 *OutDataRangesCount = DataRangeCount; 1250 } 1251 1252 1253 NTSTATUS 1254 USBAudioPinBuildDescriptors( 1255 PKSDEVICE Device, 1256 PKSPIN_DESCRIPTOR_EX *PinDescriptors, 1257 PULONG PinDescriptorsCount, 1258 PULONG PinDescriptorSize) 1259 { 1260 PDEVICE_EXTENSION DeviceExtension; 1261 PKSPIN_DESCRIPTOR_EX Pins; 1262 ULONG TotalTerminalDescriptorCount = 0; 1263 ULONG NonStreamingTerminalDescriptorCount = 0; 1264 ULONG Index = 0; 1265 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor = NULL; 1266 1267 /* get device extension */ 1268 DeviceExtension = Device->Context; 1269 1270 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount); 1271 DPRINT("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu\n", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount); 1272 1273 /* allocate pins */ 1274 Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount); 1275 if (!Pins) 1276 { 1277 /* no memory*/ 1278 return STATUS_INSUFFICIENT_RESOURCES; 1279 } 1280 1281 for (Index = 0; Index < TotalTerminalDescriptorCount; Index++) 1282 { 1283 if (Index < (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount)) 1284 { 1285 /* irp sink pins*/ 1286 TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index); 1287 ASSERT(TerminalDescriptor != NULL); 1288 1289 Pins[Index].Dispatch = &UsbAudioPinDispatch; 1290 Pins[Index].PinDescriptor.InterfacesCount = 1; 1291 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface; 1292 Pins[Index].PinDescriptor.MediumsCount = 1; 1293 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium; 1294 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor); 1295 UsbAudioGetDataRanges(DeviceExtension->ConfigurationDescriptor, TerminalDescriptor->bTerminalID, (PKSDATARANGE**)&Pins[Index].PinDescriptor.DataRanges, &Pins[Index].PinDescriptor.DataRangesCount); 1296 1297 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL) 1298 { 1299 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BOTH; 1300 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT; 1301 1302 /* pin flags */ 1303 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSFILTER_FLAG_CRITICAL_PROCESSING; 1304 } 1305 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL) 1306 { 1307 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK; 1308 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN; 1309 1310 /* pin flags */ 1311 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSPIN_FLAG_GENERATE_EOS_EVENTS; 1312 } 1313 1314 /* data intersect handler */ 1315 Pins[Index].IntersectHandler = UsbAudioPinDataIntersect; 1316 1317 /* irp sinks / sources can be instantiated */ 1318 Pins[Index].InstancesPossible = 1; 1319 } 1320 else 1321 { 1322 /* bridge pins */ 1323 TerminalDescriptor = UsbAudioGetNonStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index - (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount)); 1324 Pins[Index].PinDescriptor.InterfacesCount = 1; 1325 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface; 1326 Pins[Index].PinDescriptor.MediumsCount = 1; 1327 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium; 1328 Pins[Index].PinDescriptor.DataRanges = BridgePinAudioFormats; 1329 Pins[Index].PinDescriptor.DataRangesCount = 1; 1330 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE; 1331 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor); 1332 1333 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL) 1334 { 1335 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN; 1336 } 1337 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL) 1338 { 1339 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT; 1340 } 1341 } 1342 1343 } 1344 1345 *PinDescriptors = Pins; 1346 *PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX); 1347 *PinDescriptorsCount = TotalTerminalDescriptorCount; 1348 1349 return STATUS_SUCCESS; 1350 } 1351 1352 NTSTATUS 1353 NTAPI 1354 USBAudioGetDescriptor( 1355 IN PDEVICE_OBJECT DeviceObject, 1356 IN UCHAR DescriptorType, 1357 IN ULONG DescriptorLength, 1358 IN UCHAR DescriptorIndex, 1359 IN LANGID LanguageId, 1360 OUT PVOID *OutDescriptor) 1361 { 1362 PURB Urb; 1363 NTSTATUS Status; 1364 PVOID Descriptor; 1365 1366 /* sanity checks */ 1367 ASSERT(DeviceObject); 1368 ASSERT(OutDescriptor); 1369 ASSERT(DescriptorLength); 1370 1371 // 1372 // first allocate descriptor buffer 1373 // 1374 Descriptor = AllocFunction(DescriptorLength); 1375 if (!Descriptor) 1376 { 1377 /* no memory */ 1378 return STATUS_INSUFFICIENT_RESOURCES; 1379 } 1380 1381 /* allocate urb */ 1382 Urb = (PURB)AllocFunction(sizeof(URB)); 1383 if (!Urb) 1384 { 1385 /* no memory */ 1386 FreeFunction(Descriptor); 1387 return STATUS_INSUFFICIENT_RESOURCES; 1388 } 1389 1390 /* initialize urb */ 1391 UsbBuildGetDescriptorRequest(Urb, 1392 sizeof(Urb->UrbControlDescriptorRequest), 1393 DescriptorType, 1394 DescriptorIndex, 1395 LanguageId, 1396 Descriptor, 1397 NULL, 1398 DescriptorLength, 1399 NULL); 1400 1401 /* submit urb */ 1402 Status = SubmitUrbSync(DeviceObject, Urb); 1403 1404 /* free urb */ 1405 FreeFunction(Urb); 1406 1407 if (NT_SUCCESS(Status)) 1408 { 1409 /* store result */ 1410 *OutDescriptor = Descriptor; 1411 } 1412 else 1413 { 1414 /* failed */ 1415 FreeFunction(Descriptor); 1416 } 1417 1418 /* done */ 1419 return Status; 1420 } 1421 1422 NTSTATUS 1423 NTAPI 1424 USBAudioGetStringDescriptor( 1425 IN PDEVICE_OBJECT DeviceObject, 1426 IN ULONG DescriptorLength, 1427 IN UCHAR DescriptorIndex, 1428 IN LANGID LanguageId, 1429 OUT PVOID *OutDescriptor) 1430 { 1431 NTSTATUS Status; 1432 1433 /* retrieve descriptor */ 1434 Status = USBAudioGetDescriptor(DeviceObject, USB_STRING_DESCRIPTOR_TYPE, DescriptorLength, DescriptorIndex, LanguageId, OutDescriptor); 1435 if (!NT_SUCCESS(Status)) 1436 { 1437 // failed 1438 return Status; 1439 } 1440 return STATUS_SUCCESS; 1441 } 1442 1443 NTSTATUS 1444 USBAudioRegCreateMediaCategoriesKey( 1445 IN PUNICODE_STRING Name, 1446 OUT PHANDLE OutHandle) 1447 { 1448 NTSTATUS Status; 1449 OBJECT_ATTRIBUTES ObjectAttributes; 1450 UNICODE_STRING DestinationString; 1451 HANDLE Handle; 1452 1453 /* initialize root name*/ 1454 RtlInitUnicodeString(&DestinationString, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\"); 1455 1456 /* initialize object attributes */ 1457 InitializeObjectAttributes(&ObjectAttributes, &DestinationString, OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_KERNEL_HANDLE, NULL, NULL); 1458 1459 /* create the key */ 1460 Status = ZwOpenKey(&Handle, KEY_ALL_ACCESS, &ObjectAttributes); 1461 if (NT_SUCCESS(Status)) 1462 { 1463 /* initialize object attributes */ 1464 InitializeObjectAttributes(&ObjectAttributes, Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, Handle, NULL); 1465 1466 Status = ZwCreateKey(OutHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL); 1467 ZwClose(Handle); 1468 1469 } 1470 return Status; 1471 } 1472 1473 1474 NTSTATUS 1475 USBAudioInitComponentId( 1476 PKSDEVICE Device, 1477 IN PKSCOMPONENTID ComponentId) 1478 { 1479 PDEVICE_EXTENSION DeviceExtension; 1480 NTSTATUS Status; 1481 LPWSTR DescriptionBuffer; 1482 UNICODE_STRING GuidString; 1483 UNICODE_STRING Name; 1484 HANDLE hKey; 1485 GUID TempGuid; 1486 1487 /* get device extension */ 1488 DeviceExtension = Device->Context; 1489 1490 /* init component id */ 1491 ComponentId->Component = KSCOMPONENTID_USBAUDIO; 1492 ComponentId->Version = HIBYTE(DeviceExtension->DeviceDescriptor->bcdDevice); 1493 ComponentId->Revision = LOBYTE(DeviceExtension->DeviceDescriptor->bcdDevice); 1494 1495 INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor); 1496 INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct); 1497 INIT_USBAUDIO_PRODUCT_NAME(&TempGuid, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0); 1498 1499 if (DeviceExtension->DeviceDescriptor->iProduct) 1500 { 1501 Status = USBAudioGetStringDescriptor(DeviceExtension->LowerDevice, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iProduct, 0x0409 /* FIXME */, (PVOID*)&DescriptionBuffer); 1502 if (NT_SUCCESS(Status)) 1503 { 1504 Status = RtlStringFromGUID(&TempGuid, &GuidString); 1505 if (NT_SUCCESS(Status)) 1506 { 1507 Status = USBAudioRegCreateMediaCategoriesKey(&GuidString, &hKey); 1508 if (NT_SUCCESS(Status)) 1509 { 1510 RtlInitUnicodeString(&Name, L"Name"); 1511 ZwSetValueKey(hKey, &Name, 0, REG_SZ, DescriptionBuffer, (wcslen(DescriptionBuffer) + 1) * sizeof(WCHAR)); 1512 ZwClose(hKey); 1513 1514 INIT_USBAUDIO_PRODUCT_NAME(&ComponentId->Name, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0); 1515 } 1516 RtlFreeUnicodeString(&GuidString); 1517 } 1518 FreeFunction(DescriptionBuffer); 1519 } 1520 } 1521 return STATUS_SUCCESS; 1522 } 1523 1524 1525 NTSTATUS 1526 NTAPI 1527 USBAudioCreateFilterContext( 1528 PKSDEVICE Device) 1529 { 1530 PKSFILTER_DESCRIPTOR FilterDescriptor; 1531 PKSCOMPONENTID ComponentId; 1532 NTSTATUS Status; 1533 1534 /* allocate descriptor */ 1535 FilterDescriptor = AllocFunction(sizeof(KSFILTER_DESCRIPTOR)); 1536 if (!FilterDescriptor) 1537 { 1538 /* no memory */ 1539 return USBD_STATUS_INSUFFICIENT_RESOURCES; 1540 } 1541 1542 /* init filter descriptor*/ 1543 FilterDescriptor->Version = KSFILTER_DESCRIPTOR_VERSION; 1544 FilterDescriptor->Flags = 0; 1545 FilterDescriptor->ReferenceGuid = &KSNAME_Filter; 1546 FilterDescriptor->Dispatch = &USBAudioFilterDispatch; 1547 FilterDescriptor->CategoriesCount = 1; 1548 FilterDescriptor->Categories = &GUID_KSCATEGORY_AUDIO; 1549 1550 /* init component id*/ 1551 ComponentId = AllocFunction(sizeof(KSCOMPONENTID)); 1552 if (!ComponentId) 1553 { 1554 /* no memory */ 1555 return STATUS_INSUFFICIENT_RESOURCES; 1556 } 1557 Status = USBAudioInitComponentId(Device, ComponentId); 1558 if (!NT_SUCCESS(Status)) 1559 { 1560 /* failed*/ 1561 FreeFunction(ComponentId); 1562 return Status; 1563 } 1564 FilterDescriptor->ComponentId = ComponentId; 1565 1566 /* build pin descriptors */ 1567 Status = USBAudioPinBuildDescriptors(Device, (PKSPIN_DESCRIPTOR_EX *)&FilterDescriptor->PinDescriptors, &FilterDescriptor->PinDescriptorsCount, &FilterDescriptor->PinDescriptorSize); 1568 if (!NT_SUCCESS(Status)) 1569 { 1570 /* failed*/ 1571 FreeFunction(ComponentId); 1572 return Status; 1573 } 1574 1575 /* build topology */ 1576 Status = BuildUSBAudioFilterTopology(Device, FilterDescriptor); 1577 if (!NT_SUCCESS(Status)) 1578 { 1579 /* failed*/ 1580 FreeFunction(ComponentId); 1581 return Status; 1582 } 1583 1584 /* lets create the filter */ 1585 Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL); 1586 DPRINT("KsCreateFilterFactory: %x\n", Status); 1587 1588 return Status; 1589 } 1590 1591 1592