ReactOS 0.4.15-dev-8058-ga7cbb60
filter.c
Go to the documentation of this file.
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
28
30{
33 0
34};
35
37{
40 0
41};
42
44{
45 {
46 {
47 sizeof(KSDATAFORMAT),
48 0,
49 0,
50 0,
54 }
55 }
56};
57
59{
61};
62
63static LPWSTR ReferenceString = L"global";
64
68 PKSFILTER Filter,
69 PIRP Irp);
70
71static KSFILTER_DISPATCH USBAudioFilterDispatch =
72{
74 NULL,
75 NULL,
76 NULL
77};
78
79static KSPIN_DISPATCH UsbAudioPinDispatch =
80{
87 NULL,
88 NULL,
89 NULL,
90 NULL
91};
92
95
98
99
100static KSPROPERTY_SET FilterAudioVolumePropertySetArray[] =
101{
102 {
104 sizeof(FilterAudioVolumePropertySet) / sizeof(KSPROPERTY_ITEM),
105 (const KSPROPERTY_ITEM*)&FilterAudioVolumePropertySet,
106 0,
107 NULL
108 }
109};
110
111static KSPROPERTY_SET FilterAudioMutePropertySetArray[] =
112{
113 {
115 sizeof(FilterAudioMutePropertySet) / sizeof(KSPROPERTY_ITEM),
116 (const KSPROPERTY_ITEM*)&FilterAudioMutePropertySet,
117 0,
118 NULL
119 }
120};
121
128 IN PVOID TransferBuffer,
129 IN ULONG TransferBufferLength,
130 IN ULONG TransferFlags)
131{
132 PURB Urb;
134
135 /* allocate urb */
137 if (!Urb)
138 {
139 /* no memory */
141 }
142
143 /* format urb */
147 TransferFlags,
148 0,
149 Request,
150 Value,
151 Index,
152 TransferBuffer,
153 NULL,
154 TransferBufferLength,
155 NULL);
156
157 /* submit urb */
159
160 FreeFunction(Urb);
161 return Status;
162}
163
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
186NTAPI
188 IN PIRP Irp,
191{
193 PKSFILTER Filter;
195 PNODE_CONTEXT NodeContext;
196 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
198
199 /* get filter from irp */
201
202 if (Filter)
203 {
204 /* get property */
206
207 /* get filter context */
209
210 /* search for node context */
211 NodeContext = FindNodeContextWithNode(FilterContext->DeviceExtension->NodeContext, FilterContext->DeviceExtension->NodeContextCount, Property->NodeProperty.NodeId);
212 if (NodeContext)
213 {
214 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)NodeContext->Descriptor;
215 if (Property->NodeProperty.Property.Flags & KSPROPERTY_TYPE_GET)
216 {
217 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x81, 0x1 << 8, FeatureUnitDescriptor->bUnitID << 8, Data, 1, USBD_TRANSFER_DIRECTION_IN);
218 Irp->IoStatus.Information = sizeof(BOOL);
219 }
220 else
221 {
222 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x01, 0x1 << 8, FeatureUnitDescriptor->bUnitID << 8, Data, 1, USBD_TRANSFER_DIRECTION_OUT);
223 }
224 }
225 }
226 return Status;
227}
228
230NTAPI
232 IN PIRP Irp,
235{
237 PKSFILTER Filter;
239 PNODE_CONTEXT NodeContext;
240 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
241 PSHORT TransferBuffer;
242 LONG Value;
244
245
246 /* get filter from irp */
248
249 if (Filter)
250 {
251 /* get property */
253
254 /* get filter context */
256
257 TransferBuffer = AllocFunction(sizeof(USHORT) * 3);
258 ASSERT(TransferBuffer);
259
260 Value = *(PLONG)Data;
261
262 /* search for node context */
263 NodeContext = FindNodeContextWithNode(FilterContext->DeviceExtension->NodeContext, FilterContext->DeviceExtension->NodeContextCount, Property->NodeProperty.NodeId);
264 if (NodeContext)
265 {
266 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)NodeContext->Descriptor;
267 if (Property->NodeProperty.Property.Flags & KSPROPERTY_TYPE_GET)
268 {
269 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x81, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[0], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
270 Value = (LONG)TransferBuffer[0] * 256;
271
272 *(PLONG)Data = Value;
273 Irp->IoStatus.Information = sizeof(BOOL);
274 }
275 else
276 {
277 /* downscale value */
278 Value /= 256;
279
280 /* get minimum value */
281 UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x82, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[0], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
282
283 /* get maximum value */
284 UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x83, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[1], sizeof(USHORT), USBD_TRANSFER_DIRECTION_IN);
285
286 if (TransferBuffer[0] > Value)
287 {
288 /* use minimum value */
289 Value = TransferBuffer[0];
290 }
291
292 if (TransferBuffer[1] < Value)
293 {
294 /* use maximum value */
295 Value = TransferBuffer[1];
296 }
297
298 /* store value */
299 TransferBuffer[2] = Value;
300
301 /* set volume request */
302 Status = UsbAudioGetSetProperty(FilterContext->DeviceExtension->LowerDevice, 0x01, 0x2 << 8, FeatureUnitDescriptor->bUnitID << 8, &TransferBuffer[2], sizeof(USHORT), USBD_TRANSFER_DIRECTION_OUT);
303 if (NT_SUCCESS(Status))
304 {
305 /* store number of bytes transferred*/
306 Irp->IoStatus.Information = sizeof(LONG);
307 }
308 }
309 }
310
311 /* free transfer buffer */
312 FreeFunction(TransferBuffer);
313 }
314 return Status;
315}
316
317
318ULONG
320 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
321 OUT PULONG OutDescriptorCount)
322{
324 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
325 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
326 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
327 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
329 ULONG NodeCount = 0, Length, Index;
330 ULONG DescriptorCount = 0;
331 UCHAR Value;
332
333 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
334 Descriptor != NULL;
335 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
336 {
337 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
338 {
339 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
340 if (InterfaceHeaderDescriptor != NULL)
341 {
342 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
343 while (CommonDescriptor)
344 {
345 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
346 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
347 {
348 NodeCount++;
349 DescriptorCount++;
350 }
351 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
352 {
353 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
354 DescriptorCount++;
355
356 /* get controls from all channels*/
357 Value = 0;
358 Length = FeatureUnitDescriptor->bLength - 7;
359 for (Index = 0; Index < Length; Index++)
360 {
361 Value |= FeatureUnitDescriptor->bmaControls[Index];
362 }
363
364 if (Value & 0x01) /* MUTE*/
365 NodeCount++;
366 if (Value & 0x02) /* VOLUME */
367 NodeCount++;
368 if (Value & 0x04) /* BASS */
369 NodeCount++;
370 if (Value & 0x08) /* MID */
371 NodeCount++;
372 if (Value & 0x10) /* TREBLE */
373 NodeCount++;
374 if (Value & 0x20) /* GRAPHIC EQUALIZER */
375 NodeCount++;
376 if (Value & 0x40) /* AUTOMATIC GAIN */
377 NodeCount++;
378 if (Value & 0x80) /* DELAY */
379 NodeCount++;
380 }
381 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
382 {
383 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
384 DescriptorCount++;
385 NodeCount += MixerUnitDescriptor->bNrInPins + 1; /* KSNODETYPE_SUPERMIX for each source pin and KSNODETYPE_SUM for target */
386 }
387 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR_UNIT */)
388 {
389 DescriptorCount++;
390 NodeCount++;
391 }
392 else
393 {
395 }
396 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
397 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
398 break;
399 }
400 }
401 }
402 }
403 *OutDescriptorCount = DescriptorCount;
404 return NodeCount;
405}
406
409 IN PNODE_CONTEXT NodeContext,
410 IN ULONG NodeContextCount,
411 IN UCHAR TerminalId)
412{
413 ULONG Index;
415
416 for (Index = 0; Index < NodeContextCount; Index++)
417 {
418 TerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)NodeContext[Index].Descriptor;
419 if (TerminalDescriptor->bTerminalID == TerminalId)
420 return &NodeContext[Index];
421 }
422 return NULL;
423}
424
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;
434 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
435 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
436 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
437 PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
439 PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR OutputTerminalDescriptor;
440 PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR SelectorUnitDescriptor;
441 PKSNODE_DESCRIPTOR NodeDescriptors;
442 PNODE_CONTEXT NodeContext, PreviousNodeContext;
444 PKSAUTOMATION_TABLE AutomationTable;
445
446 /* get device extension */
447 DeviceExtension = Device->Context;
448
449 /* count topology nodes */
450 NodeCount = CountTopologyComponents(DeviceExtension->ConfigurationDescriptor, &ControlDescriptorCount);
451
452 /* init node descriptors*/
453 FilterDescriptor->NodeDescriptors = NodeDescriptors = AllocFunction(NodeCount * sizeof(KSNODE_DESCRIPTOR));
454 if (FilterDescriptor->NodeDescriptors == NULL)
455 {
456 /* no memory */
458 }
459 FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR);
460
461 DeviceExtension->NodeContext = NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount);
462 if (!NodeContext)
463 {
464 /* no memory */
466 }
467 DeviceExtension->NodeContextCount = ControlDescriptorCount;
468 DescriptorCount = 0;
469
470 /* first enumerate all topology nodes */
471 for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
472 Descriptor != NULL;
473 Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
474 {
475 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
476 {
477 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
478 if (InterfaceHeaderDescriptor != NULL)
479 {
480 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
481 while (CommonDescriptor)
482 {
483 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
484 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/)
485 {
486 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
487 {
488 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC;
489 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC;
490 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
491
492 /* insert into node context*/
493 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
494 NodeContext[DescriptorCount].NodeCount = 1;
495 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
496 DescriptorCount++;
497
498 FilterDescriptor->NodeDescriptorsCount++;
499 }
500 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x200)
501 {
502 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_ADC;
503 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_ADC;
504 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
505
506 /* insert into node context*/
507 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
508 NodeContext[DescriptorCount].NodeCount = 1;
509 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
510 DescriptorCount++;
511
512
513 FilterDescriptor->NodeDescriptorsCount++;
514 }
515 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300)
516 {
517 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC;
518 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC;
519 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
520
521 /* insert into node context*/
522 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
523 NodeContext[DescriptorCount].NodeCount = 1;
524 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
525 DescriptorCount++;
526
527 FilterDescriptor->NodeDescriptorsCount++;
528 }
529 else
530 {
531 DPRINT1("Unexpected input terminal type %x\n", InputTerminalDescriptor->wTerminalType);
532 }
533 }
534 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
535 {
536 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
537 {
538 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC;
539 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC;
540 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
541
542 /* insert into node context*/
543 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
544 NodeContext[DescriptorCount].NodeCount = 1;
545 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
546 DescriptorCount++;
547
548 FilterDescriptor->NodeDescriptorsCount++;
549 }
550 else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300)
551 {
552 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC;
553 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC;
554 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
555
556 /* insert into node context*/
557 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
558 NodeContext[DescriptorCount].NodeCount = 1;
559 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
560 DescriptorCount++;
561
562 FilterDescriptor->NodeDescriptorsCount++;
563 }
564 else
565 {
566 DPRINT1("Unexpected output terminal type %x\n", InputTerminalDescriptor->wTerminalType);
567 }
568 }
569
570 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
571 {
572 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)CommonDescriptor;
573
574 /* get controls from all channels*/
575 Value = 0;
576 Length = FeatureUnitDescriptor->bLength - 7;
577 for (Index = 0; Index < Length; Index++)
578 {
579 Value |= FeatureUnitDescriptor->bmaControls[Index];
580 }
581
582
583 if (Value & 0x01) /* MUTE*/
584 {
585 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUTE;
586 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUTE;
587 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
588 if (AutomationTable)
589 {
590 AutomationTable->PropertySets = FilterAudioMutePropertySetArray;
591 AutomationTable->PropertySetsCount = 1;
592 AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM);
593 }
594
595 /* insert into node context*/
596 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
597 NodeContext[DescriptorCount].NodeCount++;
598
599 FilterDescriptor->NodeDescriptorsCount++;
600 }
601 if (Value & 0x02) /* VOLUME */
602 {
603 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_VOLUME;
604 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_VOLUME;
605 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
606 if (AutomationTable)
607 {
608 AutomationTable->PropertySets = FilterAudioVolumePropertySetArray;
609 AutomationTable->PropertySetsCount = 1;
610 AutomationTable->PropertyItemSize = sizeof(KSPROPERTY_ITEM);
611 }
612
613 /* insert into node context*/
614 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
615 NodeContext[DescriptorCount].NodeCount++;
616
617 FilterDescriptor->NodeDescriptorsCount++;
618 }
619
620 if (Value & 0x04) /* BASS */
621 {
622 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
623 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
624 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
625
626 /* insert into node context*/
627 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
628 NodeContext[DescriptorCount].NodeCount++;
629
630 FilterDescriptor->NodeDescriptorsCount++;
631 }
632
633 if (Value & 0x08) /* MID */
634 {
635 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
636 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
637 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
638
639 /* insert into node context*/
640 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
641 NodeContext[DescriptorCount].NodeCount++;
642
643 FilterDescriptor->NodeDescriptorsCount++;
644 }
645
646 if (Value & 0x10) /* TREBLE */
647 {
648 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
649 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
650 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
651
652 /* insert into node context*/
653 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
654 NodeContext[DescriptorCount].NodeCount++;
655
656
657 FilterDescriptor->NodeDescriptorsCount++;
658 }
659
660 if (Value & 0x20) /* GRAPHIC EQUALIZER */
661 {
662 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
663 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
664 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
665
666 /* insert into node context*/
667 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
668 NodeContext[DescriptorCount].NodeCount++;
669
670 FilterDescriptor->NodeDescriptorsCount++;
671 }
672
673 if (Value & 0x40) /* AUTOMATIC GAIN */
674 {
675 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_AGC;
676 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_AGC;
677 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
678
679 /* insert into node context*/
680 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
681 NodeContext[DescriptorCount].NodeCount++;
682
683
684 FilterDescriptor->NodeDescriptorsCount++;
685 }
686
687 if (Value & 0x80) /* DELAY */
688 {
689 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
690 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
691 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
692
693 /* insert into node context*/
694 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
695 NodeContext[DescriptorCount].NodeCount++;
696
697 FilterDescriptor->NodeDescriptorsCount++;
698 }
699 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
700 DescriptorCount++;
701
702 }
703 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
704 {
705 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)CommonDescriptor;
706 for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++)
707 {
708 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUPERMIX;
709 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUPERMIX;
710 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
711
712 /* insert into node context*/
713 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
714 NodeContext[DescriptorCount].NodeCount++;
715
716 FilterDescriptor->NodeDescriptorsCount++;
717 }
718
719 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUM;
720 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUM;
721 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
722
723 /* insert into node context*/
724 NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
725 NodeContext[DescriptorCount].NodeCount++;
726 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
727 DescriptorCount++;
728
729 FilterDescriptor->NodeDescriptorsCount++;
730 }
731 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR UNIT */)
732 {
733 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUX;
734 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUX;
735 NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
736
737 /* insert into node context*/
738 NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
739 NodeContext[DescriptorCount].NodeCount = 1;
740 NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
741 DescriptorCount++;
742 FilterDescriptor->NodeDescriptorsCount++;
743 }
744 else
745 {
747 }
748 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
749 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
750 break;
751 }
752 }
753 }
754 }
755
756 /* FIXME determine connections count*/
757 FilterDescriptor->Connections = Connections = AllocFunction(sizeof(KSTOPOLOGY_CONNECTION) * FilterDescriptor->NodeDescriptorsCount * 2);
758 if (!FilterDescriptor->Connections)
759 {
760 /* no memory */
762 }
763 FilterDescriptor->ConnectionsCount = 0;
764
765 /* now build connections array */
766 DescriptorCount = 0;
767 StreamingTerminalIndex = 0;
768 NodeCount = 0;
769
770 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
771 StreamingTerminalPinOffset = TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount;
772
773 for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
774 Descriptor != NULL;
775 Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
776 {
777 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
778 {
779 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
780 if (InterfaceHeaderDescriptor != NULL)
781 {
782 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
783 while (CommonDescriptor)
784 {
785 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
786 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/)
787 {
788 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
789 {
790 Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE;
791 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalIndex;
792 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
793 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
794 FilterDescriptor->ConnectionsCount++;
795 StreamingTerminalIndex++;
796
797 }
798 else
799 {
800 Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE;
801 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalPinOffset;
802 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
803 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
804 FilterDescriptor->ConnectionsCount++;
805 StreamingTerminalPinOffset++;
806 }
807 DescriptorCount++;
808 }
809 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
810 {
811 OutputTerminalDescriptor = (PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
812 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, OutputTerminalDescriptor->bSourceID);
813 if (PreviousNodeContext)
814 {
815 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
816 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
817 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
818 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
819 FilterDescriptor->ConnectionsCount++;
820 }
821
822 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
823 {
824 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0];
825 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
826 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalIndex;
827 Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE;
828 FilterDescriptor->ConnectionsCount++;
829 StreamingTerminalIndex++;
830 }
831 else
832 {
833 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0];
834 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
835 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalPinOffset;
836 Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE;
837 FilterDescriptor->ConnectionsCount++;
838
839 StreamingTerminalPinOffset++;
840 }
841 DescriptorCount++;
842 }
843 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
844 {
845 FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
846 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, FeatureUnitDescriptor->bSourceID);
847 if (PreviousNodeContext)
848 {
849 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount-1];
850 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
851 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
852 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
853 FilterDescriptor->ConnectionsCount++;
854 }
855 for (Index = 1; Index < NodeContext[DescriptorCount].NodeCount; Index++)
856 {
857 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index - 1];
858 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
859 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
860 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index];
861 FilterDescriptor->ConnectionsCount++;
862 }
863
864 DescriptorCount++;
865 }
866 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
867 {
868 MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
869 for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++)
870 {
871 Value = MixerUnitDescriptor->baSourceID[Index];
872 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value);
873 if (PreviousNodeContext)
874 {
875 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
876 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
877 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
878 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index];
879 FilterDescriptor->ConnectionsCount++;
880 }
881
882 Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index];
883 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
884 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1 + Index;
885 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount-1];
886 FilterDescriptor->ConnectionsCount++;
887 }
888 DescriptorCount++;
889 }
890 else if (InputTerminalDescriptor->bDescriptorSubtype == 0x05 /* SELECTOR_UNIT */)
891 {
892 SelectorUnitDescriptor = (PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR)InputTerminalDescriptor;
893 for (Index = 0; Index < SelectorUnitDescriptor->bNrInPins; Index++)
894 {
895 Value = SelectorUnitDescriptor->baSourceID[Index];
896 PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value);
897 if (PreviousNodeContext)
898 {
899 Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
900 Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
901 Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
902 Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
903 FilterDescriptor->ConnectionsCount++;
904 }
905 }
906 DescriptorCount++;
907 }
908 else
909 {
911 }
912 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
913 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
914 break;
915 }
916 }
917 }
918 }
919
920
921
922 return STATUS_SUCCESS;
923}
924
926NTAPI
928 PKSFILTER Filter,
929 PIRP Irp)
930{
931 PKSFILTERFACTORY FilterFactory;
932 PKSDEVICE Device;
934
935 FilterFactory = KsGetParent(Filter);
936 if (FilterFactory == NULL)
937 {
938 /* invalid parameter */
940 }
941
942 Device = KsGetParent(FilterFactory);
943 if (Device == NULL)
944 {
945 /* invalid parameter */
947 }
948
949 /* alloc filter context */
951 if (FilterContext == NULL)
952 {
953 /* no memory */
955 }
956
957 /* init context */
958 FilterContext->DeviceExtension = Device->Context;
959 FilterContext->LowerDevice = Device->NextDeviceObject;
960 Filter->Context = FilterContext;
961
962 DPRINT("USBAudioFilterCreate FilterContext %p LowerDevice %p DeviceExtension %p\n", FilterContext, FilterContext->LowerDevice, FilterContext->DeviceExtension);
964 return STATUS_SUCCESS;
965}
966
967
968VOID
969NTAPI
971 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
972 OUT PULONG NonStreamingTerminalDescriptorCount,
973 OUT PULONG TotalTerminalDescriptorCount)
974{
976 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
977 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
978 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
979 ULONG NonStreamingTerminalCount = 0;
980 ULONG TotalTerminalCount = 0;
981
982 for(Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
983 Descriptor != NULL;
984 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
985 {
986 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
987 {
988 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
989 if (InterfaceHeaderDescriptor != NULL)
990 {
991 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
992 while (CommonDescriptor)
993 {
994 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
995 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
996 {
997 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
998 {
999 NonStreamingTerminalCount++;
1000 }
1001 TotalTerminalCount++;
1002 }
1003 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1004 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1005 break;
1006 }
1007 }
1008 }
1009 else if (Descriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING */
1010 {
1012 }
1013 }
1014 *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount;
1015 *TotalTerminalDescriptorCount = TotalTerminalCount;
1016}
1017
1018LPGUID
1021{
1022 if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE)
1023 return &NodeTypeMicrophone;
1024 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE)
1026 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE)
1028 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE)
1030 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE)
1032 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE)
1034
1035 /* playback types */
1036 if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE)
1037 return &NodeTypeSpeaker;
1038 else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE)
1040 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE)
1041 return &NodeTypeHMDA;
1042 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE)
1043 return &NodeTypeDesktopSpeaker;
1044 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE)
1045 return &NodeTypeRoomSpeaker;
1046 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE)
1048 else if (TerminalDescriptor->wTerminalType == USB_AUDIO_SUBWOOFER_TERMINAL_TYPE)
1049 return &NodeTypeSubwoofer;
1050
1051 if (TerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
1052 {
1053 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1054 return &NodeTypeCapture;
1055 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1056 return &NodeTypePlayback;
1057
1058 }
1059 return NULL;
1060}
1061
1064 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
1065 IN ULONG Index)
1066{
1068 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
1069 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
1070 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
1071 ULONG TerminalCount = 0;
1072
1073 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1074 Descriptor != NULL;
1075 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1076 {
1077 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
1078 {
1079 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1080 if (InterfaceHeaderDescriptor != NULL)
1081 {
1082 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1083 while (CommonDescriptor)
1084 {
1085 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
1086 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
1087 {
1088 if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
1089 {
1090 if (TerminalCount == Index)
1091 {
1092 return InputTerminalDescriptor;
1093 }
1094 TerminalCount++;
1095 }
1096 }
1097 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1098 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1099 break;
1100 }
1101 }
1102 }
1103 }
1104 return NULL;
1105}
1106
1109 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
1110 IN ULONG Index)
1111{
1112
1114 PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
1115 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
1116 PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
1117 ULONG TerminalCount = 0;
1118
1119 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1120 Descriptor != NULL;
1121 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1122 {
1123 if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
1124 {
1125 InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1126 if (InterfaceHeaderDescriptor != NULL)
1127 {
1128 CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1129 while (CommonDescriptor)
1130 {
1131 InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
1132 if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
1133 {
1134 if (InputTerminalDescriptor->wTerminalType != USB_AUDIO_STREAMING_TERMINAL_TYPE)
1135 {
1136 if (TerminalCount == Index)
1137 {
1138 return InputTerminalDescriptor;
1139 }
1140 TerminalCount++;
1141 }
1142 }
1143 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
1144 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
1145 break;
1146 }
1147 }
1148 }
1149 }
1150 return NULL;
1151}
1152
1153VOID
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;
1163 PKSDATARANGE_AUDIO DataRangeAudio;
1164 PKSDATARANGE *DataRangeAudioArray;
1165 ULONG NumFrequency, DataRangeCount, DataRangeIndex, Index;
1166
1167 /* count all data ranges */
1168 DataRangeCount = 0;
1169 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1170 Descriptor != NULL;
1171 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1172 {
1173 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */
1174 {
1175 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1176 if (StreamingInterfaceDescriptor != NULL)
1177 {
1178 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
1179 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
1180 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID)
1181 {
1182 DataRangeCount++;
1183 DPRINT1("StreamingInterfaceDescriptor %p TerminalID %x\n", StreamingInterfaceDescriptor, bTerminalID);
1184 }
1185 }
1186 Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor;
1187 }
1188 }
1189
1190 DataRangeAudioArray = AllocFunction(sizeof(PVOID) * DataRangeCount);
1191 if (DataRangeAudioArray == NULL)
1192 {
1193 /* no memory */
1194 return;
1195 }
1196
1197 DataRangeIndex = 0;
1198 for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
1199 Descriptor != NULL;
1200 Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
1201 {
1202 if (Descriptor->bInterfaceSubClass == 0x02) /* AUDIO_STREAMING */
1203 {
1204 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
1205 if (StreamingInterfaceDescriptor != NULL)
1206 {
1207 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
1208 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
1209 if (StreamingInterfaceDescriptor->bTerminalLink == bTerminalID)
1210 {
1211 StreamingFormatDescriptor = (PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR)((ULONG_PTR)StreamingInterfaceDescriptor + StreamingInterfaceDescriptor->bLength);
1212 ASSERT(StreamingFormatDescriptor->bDescriptorType == 0x24);
1213 ASSERT(StreamingFormatDescriptor->bDescriptorSubtype == 0x02);
1214 ASSERT(StreamingFormatDescriptor->bFormatType == 0x01);
1215
1216 DataRangeAudio = AllocFunction(sizeof(KSDATARANGE_AUDIO));
1217 if (DataRangeAudio == NULL)
1218 {
1219 /* no memory*/
1220 return;
1221 }
1222
1223 DataRangeAudio->DataRange.FormatSize = sizeof(KSDATARANGE_AUDIO);
1227 DataRangeAudio->MaximumChannels = StreamingFormatDescriptor->bNrChannels;
1228 DataRangeAudio->MinimumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
1229 DataRangeAudio->MaximumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
1230 NumFrequency = StreamingFormatDescriptor->bSamFreqType;
1231 DataRangeAudio->MinimumSampleFrequency = MAXULONG;
1232 DataRangeAudio->MaximumSampleFrequency = 0;
1233 for (Index = 0; Index < NumFrequency; Index++)
1234 {
1235 DataRangeAudio->MinimumSampleFrequency = min(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MinimumSampleFrequency);
1236 DataRangeAudio->MaximumSampleFrequency = max(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MaximumSampleFrequency);
1237 }
1238 DataRangeAudioArray[DataRangeIndex] = (PKSDATARANGE)DataRangeAudio;
1239 DataRangeIndex++;
1240 }
1241 }
1242 Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor;
1243 }
1244 }
1245
1246 *OutDataRanges = DataRangeAudioArray;
1247 *OutDataRangesCount = DataRangeCount;
1248}
1249
1250
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;
1264
1265 /* get device extension */
1266 DeviceExtension = Device->Context;
1267
1268 CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
1269 DPRINT("TotalTerminalDescriptorCount %lu NonStreamingTerminalDescriptorCount %lu\n", TotalTerminalDescriptorCount, NonStreamingTerminalDescriptorCount);
1270
1271 /* allocate pins */
1272 Pins = AllocFunction(sizeof(KSPIN_DESCRIPTOR_EX) * TotalTerminalDescriptorCount);
1273 if (!Pins)
1274 {
1275 /* no memory*/
1277 }
1278
1279 for (Index = 0; Index < TotalTerminalDescriptorCount; Index++)
1280 {
1281 if (Index < (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount))
1282 {
1283 /* irp sink pins*/
1284 TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index);
1285 ASSERT(TerminalDescriptor != NULL);
1286
1287 Pins[Index].Dispatch = &UsbAudioPinDispatch;
1288 Pins[Index].PinDescriptor.InterfacesCount = 1;
1289 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
1290 Pins[Index].PinDescriptor.MediumsCount = 1;
1291 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
1292 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
1293 UsbAudioGetDataRanges(DeviceExtension->ConfigurationDescriptor, TerminalDescriptor->bTerminalID, (PKSDATARANGE**)&Pins[Index].PinDescriptor.DataRanges, &Pins[Index].PinDescriptor.DataRangesCount);
1294
1295 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1296 {
1297 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BOTH;
1298 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
1299
1300 /* pin flags */
1301 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSFILTER_FLAG_CRITICAL_PROCESSING;
1302 }
1303 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1304 {
1305 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_SINK;
1306 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
1307
1308 /* pin flags */
1309 Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSPIN_FLAG_GENERATE_EOS_EVENTS;
1310 }
1311
1312 /* data intersect handler */
1313 Pins[Index].IntersectHandler = UsbAudioPinDataIntersect;
1314
1315 /* irp sinks / sources can be instantiated */
1316 Pins[Index].InstancesPossible = 1;
1317 }
1318 else
1319 {
1320 /* bridge pins */
1321 TerminalDescriptor = UsbAudioGetNonStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Index - (TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount));
1322 Pins[Index].PinDescriptor.InterfacesCount = 1;
1323 Pins[Index].PinDescriptor.Interfaces = &StandardPinInterface;
1324 Pins[Index].PinDescriptor.MediumsCount = 1;
1325 Pins[Index].PinDescriptor.Mediums = &StandardPinMedium;
1326 Pins[Index].PinDescriptor.DataRanges = BridgePinAudioFormats;
1327 Pins[Index].PinDescriptor.DataRangesCount = 1;
1328 Pins[Index].PinDescriptor.Communication = KSPIN_COMMUNICATION_BRIDGE;
1329 Pins[Index].PinDescriptor.Category = UsbAudioGetPinCategoryFromTerminalDescriptor(TerminalDescriptor);
1330
1331 if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_INPUT_TERMINAL)
1332 {
1333 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
1334 }
1335 else if (TerminalDescriptor->bDescriptorSubtype == USB_AUDIO_OUTPUT_TERMINAL)
1336 {
1337 Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
1338 }
1339 }
1340
1341 }
1342
1343 *PinDescriptors = Pins;
1344 *PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR_EX);
1345 *PinDescriptorsCount = TotalTerminalDescriptorCount;
1346
1347 return STATUS_SUCCESS;
1348}
1349
1351NTAPI
1355 IN ULONG DescriptorLength,
1356 IN UCHAR DescriptorIndex,
1357 IN LANGID LanguageId,
1358 OUT PVOID *OutDescriptor)
1359{
1360 PURB Urb;
1363
1364 /* sanity checks */
1366 ASSERT(OutDescriptor);
1367 ASSERT(DescriptorLength);
1368
1369 //
1370 // first allocate descriptor buffer
1371 //
1372 Descriptor = AllocFunction(DescriptorLength);
1373 if (!Descriptor)
1374 {
1375 /* no memory */
1377 }
1378
1379 /* allocate urb */
1380 Urb = (PURB)AllocFunction(sizeof(URB));
1381 if (!Urb)
1382 {
1383 /* no memory */
1386 }
1387
1388 /* initialize urb */
1390 sizeof(Urb->UrbControlDescriptorRequest),
1392 DescriptorIndex,
1393 LanguageId,
1394 Descriptor,
1395 NULL,
1396 DescriptorLength,
1397 NULL);
1398
1399 /* submit urb */
1401
1402 /* free urb */
1403 FreeFunction(Urb);
1404
1405 if (NT_SUCCESS(Status))
1406 {
1407 /* store result */
1408 *OutDescriptor = Descriptor;
1409 }
1410 else
1411 {
1412 /* failed */
1414 }
1415
1416 /* done */
1417 return Status;
1418}
1419
1421NTAPI
1424 IN ULONG DescriptorLength,
1425 IN UCHAR DescriptorIndex,
1426 IN LANGID LanguageId,
1427 OUT PVOID *OutDescriptor)
1428{
1430
1431 /* retrieve descriptor */
1432 Status = USBAudioGetDescriptor(DeviceObject, USB_STRING_DESCRIPTOR_TYPE, DescriptorLength, DescriptorIndex, LanguageId, OutDescriptor);
1433 if (!NT_SUCCESS(Status))
1434 {
1435 // failed
1436 return Status;
1437 }
1438 return STATUS_SUCCESS;
1439}
1440
1444 OUT PHANDLE OutHandle)
1445{
1449 HANDLE Handle;
1450
1451 /* initialize root name*/
1452 RtlInitUnicodeString(&DestinationString, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
1453
1454 /* initialize object attributes */
1456
1457 /* create the key */
1459 if (NT_SUCCESS(Status))
1460 {
1461 /* initialize object attributes */
1463
1464 Status = ZwCreateKey(OutHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL);
1465 ZwClose(Handle);
1466
1467 }
1468 return Status;
1469}
1470
1471
1474 PKSDEVICE Device,
1476{
1477 PDEVICE_EXTENSION DeviceExtension;
1479 LPWSTR DescriptionBuffer;
1482 HANDLE hKey;
1483 GUID TempGuid;
1484
1485 /* get device extension */
1486 DeviceExtension = Device->Context;
1487
1488 /* init component id */
1490 ComponentId->Version = HIBYTE(DeviceExtension->DeviceDescriptor->bcdDevice);
1491 ComponentId->Revision = LOBYTE(DeviceExtension->DeviceDescriptor->bcdDevice);
1492
1493 INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor);
1494 INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
1495 INIT_USBAUDIO_PRODUCT_NAME(&TempGuid, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0);
1496
1497 if (DeviceExtension->DeviceDescriptor->iProduct)
1498 {
1499 Status = USBAudioGetStringDescriptor(DeviceExtension->LowerDevice, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iProduct, 0x0409 /* FIXME */, (PVOID*)&DescriptionBuffer);
1500 if (NT_SUCCESS(Status))
1501 {
1502 Status = RtlStringFromGUID(&TempGuid, &GuidString);
1503 if (NT_SUCCESS(Status))
1504 {
1506 if (NT_SUCCESS(Status))
1507 {
1508 RtlInitUnicodeString(&Name, L"Name");
1509 ZwSetValueKey(hKey, &Name, 0, REG_SZ, DescriptionBuffer, (wcslen(DescriptionBuffer) + 1) * sizeof(WCHAR));
1510 ZwClose(hKey);
1511
1512 INIT_USBAUDIO_PRODUCT_NAME(&ComponentId->Name, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0);
1513 }
1515 }
1516 FreeFunction(DescriptionBuffer);
1517 }
1518 }
1519 return STATUS_SUCCESS;
1520}
1521
1522
1524NTAPI
1526 PKSDEVICE Device)
1527{
1528 PKSFILTER_DESCRIPTOR FilterDescriptor;
1531
1532 /* allocate descriptor */
1533 FilterDescriptor = AllocFunction(sizeof(KSFILTER_DESCRIPTOR));
1534 if (!FilterDescriptor)
1535 {
1536 /* no memory */
1538 }
1539
1540 /* init filter descriptor*/
1541 FilterDescriptor->Version = KSFILTER_DESCRIPTOR_VERSION;
1542 FilterDescriptor->Flags = 0;
1543 FilterDescriptor->ReferenceGuid = &KSNAME_Filter;
1545 FilterDescriptor->CategoriesCount = 1;
1547
1548 /* init component id*/
1550 if (!ComponentId)
1551 {
1552 /* no memory */
1554 }
1556 if (!NT_SUCCESS(Status))
1557 {
1558 /* failed*/
1560 return Status;
1561 }
1562 FilterDescriptor->ComponentId = ComponentId;
1563
1564 /* build pin descriptors */
1565 Status = USBAudioPinBuildDescriptors(Device, (PKSPIN_DESCRIPTOR_EX *)&FilterDescriptor->PinDescriptors, &FilterDescriptor->PinDescriptorsCount, &FilterDescriptor->PinDescriptorSize);
1566 if (!NT_SUCCESS(Status))
1567 {
1568 /* failed*/
1570 return Status;
1571 }
1572
1573 /* build topology */
1575 if (!NT_SUCCESS(Status))
1576 {
1577 /* failed*/
1579 return Status;
1580 }
1581
1582 /* lets create the filter */
1583 Status = KsCreateFilterFactory(Device->FunctionalDeviceObject, FilterDescriptor, ReferenceString, NULL, KSCREATE_ITEM_FREEONSTOP, NULL, NULL, NULL);
1584 DPRINT("KsCreateFilterFactory: %x\n", Status);
1585
1586 return Status;
1587}
1588
1589
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char UINT32 ComponentId
Definition: acpixf.h:1281
struct NameRec_ * Name
Definition: cdprocs.h:460
NTSTATUS NTAPI KsAddItemToObjectBag(IN KSOBJECT_BAG ObjectBag, IN PVOID Item, IN PFNKSFREE Free OPTIONAL)
Definition: bag.c:86
LONG NTSTATUS
Definition: precomp.h:26
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:118
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR Connections[]
Definition: session.c:1502
KSDDKAPI PKSFILTER NTAPI KsGetFilterFromIrp(IN PIRP Irp)
Definition: filter.c:2106
KSDDKAPI PVOID NTAPI KsGetParent(IN PVOID Object)
Definition: misc.c:160
#define ULONG_PTR
Definition: config.h:101
GUID NodeTypeCommunicationSpeaker
Definition: filter.c:23
static KSFILTER_DISPATCH USBAudioFilterDispatch
Definition: filter.c:71
NTSTATUS BuildUSBAudioFilterTopology(PKSDEVICE Device, PKSFILTER_DESCRIPTOR FilterDescriptor)
Definition: filter.c:426
GUID NodeTypeCapture
Definition: filter.c:25
GUID NodeTypeSpeaker
Definition: filter.c:18
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetStreamingTerminalDescriptorByIndex(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
Definition: filter.c:1063
GUID NodeTypePersonalMicrophone
Definition: filter.c:14
VOID NTAPI CountTerminalUnits(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PULONG NonStreamingTerminalDescriptorCount, OUT PULONG TotalTerminalDescriptorCount)
Definition: filter.c:970
GUID NodeTypeHeadphonesSpeaker
Definition: filter.c:19
PNODE_CONTEXT FindNodeContextWithNode(IN PNODE_CONTEXT NodeContext, IN ULONG NodeContextCount, IN ULONG NodeId)
Definition: filter.c:165
GUID NodeTypeDesktopSpeaker
Definition: filter.c:21
NTSTATUS USBAudioRegCreateMediaCategoriesKey(IN PUNICODE_STRING Name, OUT PHANDLE OutHandle)
Definition: filter.c:1442
GUID NodeTypeRoomSpeaker
Definition: filter.c:22
PNODE_CONTEXT FindNodeContextWithId(IN PNODE_CONTEXT NodeContext, IN ULONG NodeContextCount, IN UCHAR TerminalId)
Definition: filter.c:408
GUID NodeTypeHMDA
Definition: filter.c:20
GUID NodeTypeOmmniMicrophone
Definition: filter.c:15
NTSTATUS NTAPI USBAudioFilterCreate(PKSFILTER Filter, PIRP Irp)
Definition: filter.c:927
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetNonStreamingTerminalDescriptorByIndex(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
Definition: filter.c:1108
GUID NodeTypeSubwoofer
Definition: filter.c:24
KSDATARANGE BridgePinAudioFormat[]
Definition: filter.c:43
static KSPROPERTY_SET FilterAudioVolumePropertySetArray[]
Definition: filter.c:100
GUID NodeTypePlayback
Definition: filter.c:26
static PKSDATARANGE BridgePinAudioFormats[]
Definition: filter.c:58
GUID NodeTypeDesktopMicrophone
Definition: filter.c:13
KSPIN_MEDIUM StandardPinMedium
Definition: filter.c:36
NTSTATUS NTAPI USBAudioGetStringDescriptor(IN PDEVICE_OBJECT DeviceObject, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: filter.c:1422
GUID NodeTypeMicrophone
Definition: filter.c:12
GUID GUID_KSCATEGORY_AUDIO
Definition: filter.c:27
NTSTATUS USBAudioPinBuildDescriptors(PKSDEVICE Device, PKSPIN_DESCRIPTOR_EX *PinDescriptors, PULONG PinDescriptorsCount, PULONG PinDescriptorSize)
Definition: filter.c:1252
static KSPIN_DISPATCH UsbAudioPinDispatch
Definition: filter.c:79
static KSPROPERTY_SET FilterAudioMutePropertySetArray[]
Definition: filter.c:111
GUID NodeTypeArrayMicrophone
Definition: filter.c:16
NTSTATUS USBAudioInitComponentId(PKSDEVICE Device, IN PKSCOMPONENTID ComponentId)
Definition: filter.c:1473
NTSTATUS NTAPI FilterAudioVolumeHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: filter.c:231
KSPIN_INTERFACE StandardPinInterface
Definition: filter.c:29
NTSTATUS UsbAudioGetSetProperty(IN PDEVICE_OBJECT DeviceObject, IN UCHAR Request, IN USHORT Value, IN USHORT Index, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN ULONG TransferFlags)
Definition: filter.c:123
ULONG CountTopologyComponents(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PULONG OutDescriptorCount)
Definition: filter.c:319
GUID NodeTypeProcessingArrayMicrophone
Definition: filter.c:17
NTSTATUS NTAPI USBAudioGetDescriptor(IN PDEVICE_OBJECT DeviceObject, IN UCHAR DescriptorType, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: filter.c:1352
NTSTATUS NTAPI USBAudioCreateFilterContext(PKSDEVICE Device)
Definition: filter.c:1525
VOID UsbAudioGetDataRanges(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN UCHAR bTerminalID, OUT PKSDATARANGE **OutDataRanges, OUT PULONG OutDataRangesCount)
Definition: filter.c:1154
LPGUID UsbAudioGetPinCategoryFromTerminalDescriptor(IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
Definition: filter.c:1019
NTSTATUS NTAPI FilterAudioMuteHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: filter.c:187
NTSTATUS NTAPI USBAudioPinCreate(_In_ PKSPIN Pin, _In_ PIRP Irp)
Definition: pin.c:764
VOID NTAPI USBAudioPinReset(_In_ PKSPIN Pin)
Definition: pin.c:1290
NTSTATUS NTAPI USBAudioPinProcess(_In_ PKSPIN Pin)
Definition: pin.c:1270
NTSTATUS NTAPI USBAudioPinClose(_In_ PKSPIN Pin, _In_ PIRP Irp)
Definition: pin.c:843
NTSTATUS NTAPI UsbAudioPinDataIntersect(_In_ PVOID Context, _In_ PIRP Irp, _In_ PKSP_PIN Pin, _In_ PKSDATARANGE DataRange, _In_ PKSDATARANGE MatchingDataRange, _In_ ULONG DataBufferSize, _Out_ PVOID Data, _Out_ PULONG DataSize)
Definition: pin.c:1416
NTSTATUS NTAPI USBAudioPinSetDeviceState(_In_ PKSPIN Pin, _In_ KSSTATE ToState, _In_ KSSTATE FromState)
Definition: pin.c:1392
NTSTATUS NTAPI USBAudioPinSetDataFormat(_In_ PKSPIN Pin, _In_opt_ PKSDATAFORMAT OldFormat, _In_opt_ PKSMULTIPLE_ITEM OldAttributeList, _In_ const KSDATARANGE *DataRange, _In_opt_ const KSATTRIBUTE_LIST *AttributeRange)
Definition: pin.c:1298
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
KSDDKAPI NTSTATUS NTAPI KsCreateFilterFactory(IN PDEVICE_OBJECT DeviceObject, IN const KSFILTER_DESCRIPTOR *Descriptor, IN PWSTR RefString OPTIONAL, IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN ULONG CreateItemFlags, IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL, IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL, OUT PKSFILTERFACTORY *FilterFactory OPTIONAL)
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG _In_opt_ PVOID _In_opt_ PVOID FilterContext
Definition: fsrtlfuncs.h:746
FxAutoRegKey hKey
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define KSNAME_Filter
Definition: ks.h:111
#define STATIC_KSINTERFACESETID_Standard
Definition: ks.h:277
#define KSFILTER_NODE
Definition: ks.h:44
#define KSMEDIUM_TYPE_ANYINSTANCE
Definition: ks.h:301
#define STATIC_KSDATAFORMAT_SPECIFIER_NONE
Definition: ks.h:1154
#define STATIC_KSMEDIUMSETID_Standard
Definition: ks.h:303
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
@ KSPIN_COMMUNICATION_BRIDGE
Definition: ks.h:1258
@ KSPIN_COMMUNICATION_BOTH
Definition: ks.h:1257
@ KSPIN_COMMUNICATION_SINK
Definition: ks.h:1255
@ KSINTERFACE_STANDARD_STREAMING
Definition: ks.h:283
union KSDATAFORMAT * PKSDATARANGE
#define STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY
Definition: ksmedia.h:476
#define KSNODETYPE_TONE
Definition: ksmedia.h:453
#define STATIC_KSNODETYPE_SPEAKER
Definition: ksmedia.h:325
#define INIT_USBAUDIO_PRODUCT_NAME(guid, vid, pid, strIndex)
Definition: ksmedia.h:99
#define STATIC_KSNODETYPE_HEADPHONES
Definition: ksmedia.h:481
#define KSNODETYPE_SUM
Definition: ksmedia.h:363
#define INIT_USBAUDIO_PID(guid, id)
Definition: ksmedia.h:62
#define STATIC_KSNODETYPE_MICROPHONE_ARRAY
Definition: ksmedia.h:471
#define STATIC_KSNODETYPE_MICROPHONE
Definition: ksmedia.h:294
#define KSNODETYPE_MUX
Definition: ksmedia.h:433
#define STATIC_KSNODETYPE_DESKTOP_SPEAKER
Definition: ksmedia.h:491
#define STATIC_KSNODETYPE_COMMUNICATION_SPEAKER
Definition: ksmedia.h:501
struct KSNODEPROPERTY_AUDIO_CHANNEL * PKSNODEPROPERTY_AUDIO_CHANNEL
#define KSNODETYPE_SRC
Definition: ksmedia.h:282
#define KSDATAFORMAT_SUBTYPE_PCM
Definition: ksmedia.h:1021
#define KSNODETYPE_VOLUME
Definition: ksmedia.h:338
#define STATIC_KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:980
#define KSNODETYPE_MUTE
Definition: ksmedia.h:348
#define KSNODETYPE_ADC
Definition: ksmedia.h:262
#define STATIC_KSNODETYPE_PERSONAL_MICROPHONE
Definition: ksmedia.h:461
#define STATIC_KSCATEGORY_AUDIO
Definition: ksmedia.h:169
#define KSNODETYPE_AGC
Definition: ksmedia.h:267
#define KSNODETYPE_DAC
Definition: ksmedia.h:287
#define KSNODETYPE_SUPERMIX
Definition: ksmedia.h:277
#define KSCOMPONENTID_USBAUDIO
Definition: ksmedia.h:123
#define STATIC_PINNAME_CAPTURE
Definition: ksmedia.h:144
#define KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:983
#define STATIC_KSDATAFORMAT_SUBTYPE_ANALOG
Definition: ksmedia.h:990
#define INIT_USBAUDIO_MID(guid, id)
Definition: ksmedia.h:25
#define STATIC_KSNODETYPE_DESKTOP_MICROPHONE
Definition: ksmedia.h:456
#define STATIC_KSNODETYPE_ROOM_SPEAKER
Definition: ksmedia.h:496
#define STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO
Definition: ksmedia.h:486
#define STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER
Definition: ksmedia.h:506
#define KSPROPSETID_Audio
Definition: ksmedia.h:1051
#define STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE
Definition: ksmedia.h:466
#define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
Definition: ksmedia.h:1031
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
static PWSTR GuidString
Definition: apphelp.c:93
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define min(a, b)
Definition: monoChain.cc:55
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1909
#define BOOL
Definition: nt_native.h:43
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
const KSFILTER_DESCRIPTOR FilterDescriptor
Definition: splitter.c:229
const KSPIN_DESCRIPTOR_EX PinDescriptors[]
Definition: splitter.c:154
ULONG MaximumChannels
Definition: ksmedia.h:680
ULONG MinimumBitsPerSample
Definition: ksmedia.h:681
ULONG MaximumBitsPerSample
Definition: ksmedia.h:682
ULONG MaximumSampleFrequency
Definition: ksmedia.h:684
KSDATARANGE DataRange
Definition: ksmedia.h:679
ULONG MinimumSampleFrequency
Definition: ksmedia.h:683
ULONG Nodes[20]
Definition: usbaudio.h:173
ULONG NodeCount
Definition: usbaudio.h:172
PUSB_COMMON_DESCRIPTOR Descriptor
Definition: usbaudio.h:171
Property(long _type, long _tag, INREAL _value)
Definition: reader.h:125
Definition: usb.h:529
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
#define max(a, b)
Definition: svc.c:63
#define MAXULONG
Definition: typedefs.h:251
uint32_t * PULONG
Definition: typedefs.h:59
int16_t * PSHORT
Definition: typedefs.h:55
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
#define USB_DEVICE_CLASS_AUDIO
Definition: usb100.h:91
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
struct _URB * PURB
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define USBD_STATUS_INSUFFICIENT_RESOURCES
Definition: usb.h:204
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
NTSTATUS SubmitUrbSync(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: usbaudio.c:37
#define USB_AUDIO_OUTPUT_TERMINAL
Definition: usbaudio.h:36
struct USB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR * PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR
#define USB_AUDIO_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:19
#define USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:23
#define USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:31
#define USB_AUDIO_HMDA_TERMINAL_TYPE
Definition: usbaudio.h:28
struct USB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR
#define USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:20
struct FILTER_CONTEXT * PFILTER_CONTEXT
#define USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:21
struct USB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR
#define USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:29
struct USB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR * PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR
#define USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:22
struct USB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR * PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
#define USB_AUDIO_STREAMING_TERMINAL_TYPE
Definition: usbaudio.h:17
#define USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
Definition: usbaudio.h:14
#define USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:30
#define DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME(TopologySet, Handler)
Definition: usbaudio.h:47
struct USB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR
#define DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE(TopologySet, Handler)
Definition: usbaudio.h:60
#define USB_AUDIO_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:26
#define USB_HEADPHONES_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:27
#define USB_AUDIO_INPUT_TERMINAL
Definition: usbaudio.h:35
struct USB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR * PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR
struct USB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR * PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR
#define USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:24
#define USB_AUDIO_SUBWOOFER_TERMINAL_TYPE
Definition: usbaudio.h:32
PUSB_COMMON_DESCRIPTOR NTAPI USBD_ParseDescriptors(PVOID DescriptorBuffer, ULONG TotalLength, PVOID StartPosition, LONG DescriptorType)
Definition: usbd.c:445
PUSB_INTERFACE_DESCRIPTOR NTAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PVOID StartPosition, LONG InterfaceNumber, LONG AlternateSetting, LONG InterfaceClass, LONG InterfaceSubClass, LONG InterfaceProtocol)
Definition: usbd.c:496
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
#define UsbBuildVendorRequest(urb, cmd, length, transferFlags, reservedbits, request, value, index, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:68
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:160
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ CONST GUID _In_opt_ PCUNICODE_STRING ReferenceString
Definition: wdfdevice.h:3630
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184