ReactOS  0.4.13-dev-464-g6b95727
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 
63 static LPWSTR ReferenceString = L"global";
64 
66 NTAPI
68  PKSFILTER Filter,
69  PIRP Irp);
70 
71 static KSFILTER_DISPATCH USBAudioFilterDispatch =
72 {
74  NULL,
75  NULL,
76  NULL
77 };
78 
79 static KSPIN_DISPATCH UsbAudioPinDispatch =
80 {
87  NULL,
88  NULL,
89  NULL,
90  NULL
91 };
92 
95 
98 
99 
100 static KSPROPERTY_SET FilterAudioVolumePropertySetArray[] =
101 {
102  {
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  {
115  sizeof(FilterAudioMutePropertySet) / sizeof(KSPROPERTY_ITEM),
116  (const KSPROPERTY_ITEM*)&FilterAudioMutePropertySet,
117  0,
118  NULL
119  }
120 };
121 
122 NTSTATUS
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;
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 
185 NTSTATUS
186 NTAPI
188  IN PIRP Irp,
190  IN OUT PVOID Data)
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 
229 NTSTATUS
230 NTAPI
232  IN PIRP Irp,
234  IN OUT PVOID Data)
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 
318 ULONG
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;
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  {
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 
411  IN PNODE_CONTEXT NodeContext,
412  IN ULONG NodeContextCount,
413  IN UCHAR TerminalId)
414 {
415  ULONG Index;
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
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;
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;
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 */
460  }
461  FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR);
462 
463  DeviceExtension->NodeContext = NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount);
464  if (!NodeContext)
465  {
466  /* no memory */
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  {
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 */
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  {
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
930  PKSFILTER Filter,
931  PIRP Irp)
932 {
933  PKSFILTERFACTORY FilterFactory;
934  PKSDEVICE Device;
936 
937  FilterFactory = KsGetParent(Filter);
938  if (FilterFactory == NULL)
939  {
940  /* invalid parameter */
942  }
943 
944  Device = KsGetParent(FilterFactory);
945  if (Device == NULL)
946  {
947  /* invalid parameter */
949  }
950 
951  /* alloc filter context */
953  if (FilterContext == NULL)
954  {
955  /* no memory */
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);
966  return STATUS_SUCCESS;
967 }
968 
969 
970 VOID
971 NTAPI
973  IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
974  OUT PULONG NonStreamingTerminalDescriptorCount,
975  OUT PULONG TotalTerminalDescriptorCount)
976 {
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
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)
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)
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)
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 
1066  IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
1067  IN ULONG Index)
1068 {
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 
1111  IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
1112  IN ULONG Index)
1113 {
1114 
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
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;
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;
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
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;
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*/
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
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 */
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 */
1379  }
1380 
1381  /* allocate urb */
1382  Urb = (PURB)AllocFunction(sizeof(URB));
1383  if (!Urb)
1384  {
1385  /* no memory */
1388  }
1389 
1390  /* initialize urb */
1392  sizeof(Urb->UrbControlDescriptorRequest),
1394  DescriptorIndex,
1395  LanguageId,
1396  Descriptor,
1397  NULL,
1398  DescriptorLength,
1399  NULL);
1400 
1401  /* submit 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 */
1416  }
1417 
1418  /* done */
1419  return Status;
1420 }
1421 
1422 NTSTATUS
1423 NTAPI
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
1446  OUT PHANDLE OutHandle)
1447 {
1448  NTSTATUS Status;
1451  HANDLE Handle;
1452 
1453  /* initialize root name*/
1454  RtlInitUnicodeString(&DestinationString, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
1455 
1456  /* initialize object attributes */
1458 
1459  /* create the key */
1460  Status = ZwOpenKey(&Handle, KEY_ALL_ACCESS, &ObjectAttributes);
1461  if (NT_SUCCESS(Status))
1462  {
1463  /* initialize object attributes */
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
1476  PKSDEVICE Device,
1478 {
1479  PDEVICE_EXTENSION DeviceExtension;
1480  NTSTATUS Status;
1481  LPWSTR DescriptionBuffer;
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  {
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  }
1517  }
1518  FreeFunction(DescriptionBuffer);
1519  }
1520  }
1521  return STATUS_SUCCESS;
1522 }
1523 
1524 
1525 NTSTATUS
1526 NTAPI
1528  PKSDEVICE Device)
1529 {
1530  PKSFILTER_DESCRIPTOR FilterDescriptor;
1532  NTSTATUS Status;
1533 
1534  /* allocate descriptor */
1535  FilterDescriptor = AllocFunction(sizeof(KSFILTER_DESCRIPTOR));
1536  if (!FilterDescriptor)
1537  {
1538  /* no memory */
1540  }
1541 
1542  /* init filter descriptor*/
1543  FilterDescriptor->Version = KSFILTER_DESCRIPTOR_VERSION;
1544  FilterDescriptor->Flags = 0;
1545  FilterDescriptor->ReferenceGuid = &KSNAME_Filter;
1547  FilterDescriptor->CategoriesCount = 1;
1548  FilterDescriptor->Categories = &GUID_KSCATEGORY_AUDIO;
1549 
1550  /* init component id*/
1552  if (!ComponentId)
1553  {
1554  /* no memory */
1556  }
1558  if (!NT_SUCCESS(Status))
1559  {
1560  /* failed*/
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*/
1572  return Status;
1573  }
1574 
1575  /* build topology */
1577  if (!NT_SUCCESS(Status))
1578  {
1579  /* failed*/
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 
GUID NodeTypeRoomSpeaker
Definition: filter.c:22
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
const GUID KSNODETYPE_TONE
Definition: sup.c:20
#define STATIC_KSNODETYPE_PERSONAL_MICROPHONE
Definition: ksmedia.h:461
GUID NodeTypeHeadphonesSpeaker
Definition: filter.c:19
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static PWSTR GuidString
Definition: apphelp.c:91
NTSTATUS NTAPI USBAudioPinProcess(_In_ PKSPIN Pin)
Definition: pin.c:1270
#define IN
Definition: typedefs.h:38
struct USB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR
#define max(a, b)
Definition: svc.c:63
const KSFILTER_DESCRIPTOR FilterDescriptor
Definition: splitter.c:229
struct KSNODEPROPERTY_AUDIO_CHANNEL * PKSNODEPROPERTY_AUDIO_CHANNEL
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KSDATAFORMAT_SUBTYPE_PCM
Definition: ksmedia.h:921
NTSTATUS NTAPI KsAddItemToObjectBag(IN KSOBJECT_BAG ObjectBag, IN PVOID Item, IN PFNKSFREE Free OPTIONAL)
Definition: bag.c:86
VOID NTAPI CountTerminalUnits(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PULONG NonStreamingTerminalDescriptorCount, OUT PULONG TotalTerminalDescriptorCount)
Definition: filter.c:972
KSDDKAPI PVOID NTAPI KsGetParent(IN PVOID Object)
Definition: misc.c:217
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
_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:738
GUID NodeTypeDesktopSpeaker
Definition: filter.c:21
#define STATIC_KSCATEGORY_AUDIO
Definition: ksmedia.h:169
const GUID KSNAME_Filter
Definition: splitter.c:14
#define LOBYTE(W)
Definition: jmemdos.c:487
signed short * PSHORT
Definition: retypes.h:6
GUID NodeTypeMicrophone
Definition: filter.c:12
GUID NodeTypeDesktopMicrophone
Definition: filter.c:13
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI USBAudioCreateFilterContext(PKSDEVICE Device)
Definition: filter.c:1527
struct USB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR * PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define STATIC_KSNODETYPE_MICROPHONE_ARRAY
Definition: ksmedia.h:471
struct USB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR * PUSB_AUDIO_STREAMING_FORMAT_TYPE_DESCRIPTOR
static const WCHAR Connections[]
Definition: session.c:1468
#define KSPROPSETID_Audio
Definition: ksmedia.h:951
GUID NodeTypeSpeaker
Definition: filter.c:18
ULONG MaximumBitsPerSample
Definition: ksmedia.h:582
DEFINE_KSPROPERTY_TABLE_AUDIO_VOLUME(FilterAudioVolumePropertySet, FilterAudioVolumeHandler)
ULONG Nodes[20]
Definition: usbaudio.h:173
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
const GUID KSNODETYPE_MUTE
Definition: sup.c:19
LONG NTSTATUS
Definition: precomp.h:26
struct USB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define HIBYTE(W)
Definition: jmemdos.c:486
#define STATIC_KSMEDIUMSETID_Standard
Definition: ks.h:333
#define STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER
Definition: ksmedia.h:506
const GUID KSNODETYPE_VOLUME
Definition: sup.c:21
NTSTATUS NTAPI USBAudioFilterCreate(PKSFILTER Filter, PIRP Irp)
Definition: filter.c:929
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:1252
KSDATARANGE BridgePinAudioFormat[]
Definition: filter.c:43
const GUID KSNODETYPE_MUX
Definition: sup.c:23
WORD LANGID
Definition: typedefs.h:79
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
#define STATIC_KSNODETYPE_HEADPHONES
Definition: ksmedia.h:481
#define USB_AUDIO_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:19
#define USB_AUDIO_INPUT_TERMINAL
Definition: usbaudio.h:35
GUID NodeTypeSubwoofer
Definition: filter.c:24
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
#define BOOL
Definition: nt_native.h:43
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
static PKSDATARANGE BridgePinAudioFormats[]
Definition: filter.c:58
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
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
VOID UsbAudioGetDataRanges(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN UCHAR bTerminalID, OUT PKSDATARANGE **OutDataRanges, OUT PULONG OutDataRangesCount)
Definition: filter.c:1156
#define USB_DEVICE_CLASS_AUDIO
Definition: usb100.h:91
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 UsbBuildVendorRequest(urb, cmd, length, transferFlags, reservedbits, request, value, index, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:68
#define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
Definition: ksmedia.h:931
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define STATIC_KSNODETYPE_SPEAKER
Definition: ksmedia.h:325
#define USB_AUDIO_SUBWOOFER_TERMINAL_TYPE
Definition: usbaudio.h:32
#define USBD_STATUS_INSUFFICIENT_RESOURCES
Definition: usb.h:204
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
static KSPROPERTY_SET FilterAudioMutePropertySetArray[]
Definition: filter.c:111
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
#define OBJ_OPENIF
Definition: winternl.h:229
#define KSCOMPONENTID_USBAUDIO
Definition: ksmedia.h:123
#define USB_AUDIO_STREAMING_TERMINAL_TYPE
Definition: usbaudio.h:17
GUID NodeTypePlayback
Definition: filter.c:26
#define WAVE_FORMAT_PCM
Definition: constants.h:425
GUID NodeTypeHMDA
Definition: filter.c:20
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetStreamingTerminalDescriptorByIndex(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
Definition: filter.c:1065
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
const GUID KSNODETYPE_SUPERMIX
Definition: sup.c:27
GUID NodeTypeCapture
Definition: filter.c:25
NTSTATUS NTAPI USBAudioPinSetDeviceState(_In_ PKSPIN Pin, _In_ KSSTATE ToState, _In_ KSSTATE FromState)
Definition: pin.c:1392
long LONG
Definition: pedump.c:60
#define USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:20
#define INIT_USBAUDIO_PRODUCT_NAME(guid, vid, pid, strIndex)
Definition: ksmedia.h:99
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1802
struct NameRec_ * Name
Definition: cdprocs.h:464
#define KSFILTER_NODE
Definition: ks.h:44
KSDATARANGE DataRange
Definition: ksmedia.h:579
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
NTSTATUS NTAPI FilterAudioVolumeHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: filter.c:231
#define STATIC_KSDATAFORMAT_SPECIFIER_NONE
Definition: ks.h:1184
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1869
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI USBAudioGetStringDescriptor(IN PDEVICE_OBJECT DeviceObject, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: filter.c:1424
void DPRINT(...)
Definition: polytest.cpp:61
#define USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:23
struct FILTER_CONTEXT * PFILTER_CONTEXT
static KSPIN_DISPATCH UsbAudioPinDispatch
Definition: filter.c:79
#define USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:24
struct USB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR * PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR
GUID NodeTypeArrayMicrophone
Definition: filter.c:16
static LPWSTR ReferenceString
Definition: filter.c:63
_In_ HANDLE Handle
Definition: extypes.h:390
NTSTATUS USBAudioPinBuildDescriptors(PKSDEVICE Device, PKSPIN_DESCRIPTOR_EX *PinDescriptors, PULONG PinDescriptorsCount, PULONG PinDescriptorSize)
Definition: filter.c:1254
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
GUID NodeTypeCommunicationSpeaker
Definition: filter.c:23
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
static KSFILTER_DISPATCH USBAudioFilterDispatch
Definition: filter.c:71
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
KSPIN_INTERFACE StandardPinInterface
Definition: filter.c:29
const GUID KSNODETYPE_AGC
Definition: sup.c:17
PUSB_COMMON_DESCRIPTOR Descriptor
Definition: usbaudio.h:171
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
ULONG MinimumSampleFrequency
Definition: ksmedia.h:583
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:1354
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTATUS USBAudioInitComponentId(PKSDEVICE Device, IN PKSCOMPONENTID ComponentId)
Definition: filter.c:1475
ULONG MaximumChannels
Definition: ksmedia.h:580
#define STATIC_KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:880
const GUID KSNODETYPE_DAC
Definition: sup.c:15
const GUID KSNODETYPE_SUM
Definition: sup.c:14
KSPIN_MEDIUM StandardPinMedium
Definition: filter.c:36
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
PUSB_COMMON_DESCRIPTOR NTAPI USBD_ParseDescriptors(PVOID DescriptorBuffer, ULONG TotalLength, PVOID StartPosition, LONG DescriptorType)
Definition: usbd.c:445
#define STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE
Definition: ksmedia.h:466
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI FilterAudioMuteHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: filter.c:187
GUID NodeTypeProcessingArrayMicrophone
Definition: filter.c:17
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
GUID NodeTypePersonalMicrophone
Definition: filter.c:14
struct USB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR * PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR
NTSTATUS NTAPI USBAudioPinClose(_In_ PKSPIN Pin, _In_ PIRP Irp)
Definition: pin.c:843
unsigned char UCHAR
Definition: xmlstorage.h:181
#define USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:31
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS USBAudioRegCreateMediaCategoriesKey(IN PUNICODE_STRING Name, OUT PHANDLE OutHandle)
Definition: filter.c:1444
#define KSNODETYPE_SRC
Definition: ksmedia.h:282
KSDDKAPI NTSTATUS NTAPI KsCreateFilterFactory(IN PDEVICE_OBJECT DeviceObject, IN const KSFILTER_DESCRIPTOR *Descriptor, IN PWSTR RefString OPTIONAL, IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN ULONG CreateItemFlags, IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL, IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL, OUT PKSFILTERFACTORY *FilterFactory OPTIONAL)
#define STATIC_KSNODETYPE_DESKTOP_SPEAKER
Definition: ksmedia.h:491
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define STATIC_KSDATAFORMAT_SUBTYPE_ANALOG
Definition: ksmedia.h:890
#define STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO
Definition: ksmedia.h:486
NTSTATUS SubmitUrbSync(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: usbaudio.c:37
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetNonStreamingTerminalDescriptorByIndex(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
Definition: filter.c:1110
ULONG NodeCount
Definition: usbaudio.h:172
#define KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:883
#define INIT_USBAUDIO_MID(guid, id)
Definition: ksmedia.h:25
#define STATIC_KSNODETYPE_ROOM_SPEAKER
Definition: ksmedia.h:496
#define USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:21
struct _URB * PURB
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
union KSDATAFORMAT * PKSDATARANGE
_In_ DWORD Property
Definition: setupapi.h:1545
struct USB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR * PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR
GUID NodeTypeOmmniMicrophone
Definition: filter.c:15
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define STATIC_PINNAME_CAPTURE
Definition: ksmedia.h:144
const GUID KSNODETYPE_ADC
Definition: sup.c:16
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
Definition: usb.h:529
#define KSMEDIUM_TYPE_ANYINSTANCE
Definition: ks.h:331
ULONG MaximumSampleFrequency
Definition: ksmedia.h:584
unsigned short USHORT
Definition: pedump.c:61
#define USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:30
#define USB_AUDIO_HMDA_TERMINAL_TYPE
Definition: usbaudio.h:28
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
#define USB_AUDIO_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:26
#define USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE
Definition: usbaudio.h:22
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define STATIC_KSINTERFACESETID_Standard
Definition: ks.h:307
KSDDKAPI PKSFILTER NTAPI KsGetFilterFromIrp(IN PIRP Irp)
Definition: filter.c:2106
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
#define DPRINT1
Definition: precomp.h:8
ULONG MinimumBitsPerSample
Definition: ksmedia.h:581
struct USB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR * PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR
PNODE_CONTEXT FindNodeContextWithNode(IN PNODE_CONTEXT NodeContext, IN ULONG NodeContextCount, IN ULONG NodeId)
Definition: filter.c:165
NTSTATUS BuildUSBAudioFilterTopology(PKSDEVICE Device, PKSFILTER_DESCRIPTOR FilterDescriptor)
Definition: filter.c:428
#define INIT_USBAUDIO_PID(guid, id)
Definition: ksmedia.h:62
VOID NTAPI USBAudioPinReset(_In_ PKSPIN Pin)
Definition: pin.c:1290
#define STATIC_KSNODETYPE_MICROPHONE
Definition: ksmedia.h:294
#define OUT
Definition: typedefs.h:39
static KSPROPERTY_SET FilterAudioVolumePropertySetArray[]
Definition: filter.c:100
DEFINE_KSPROPERTY_TABLE_AUDIO_MUTE(FilterAudioMutePropertySet, FilterAudioMuteHandler)
unsigned int ULONG
Definition: retypes.h:1
const KSPIN_DESCRIPTOR_EX PinDescriptors[]
Definition: splitter.c:154
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
#define USB_AUDIO_OUTPUT_TERMINAL
Definition: usbaudio.h:36
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
PNODE_CONTEXT FindNodeContextWithId(IN PNODE_CONTEXT NodeContext, IN ULONG NodeContextCount, IN UCHAR TerminalId)
Definition: filter.c:410
#define USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:29
ULONG CountTopologyComponents(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PULONG OutDescriptorCount)
Definition: filter.c:319
GUID GUID_KSCATEGORY_AUDIO
Definition: filter.c:27
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
Definition: usbaudio.h:14
return STATUS_SUCCESS
Definition: btrfs.c:2777
signed int * PLONG
Definition: retypes.h:5
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:145
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
Property(long _type, long _tag, INREAL _value)
Definition: reader.h:125
LPGUID UsbAudioGetPinCategoryFromTerminalDescriptor(IN PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor)
Definition: filter.c:1021
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define USB_HEADPHONES_SPEAKER_TERMINAL_TYPE
Definition: usbaudio.h:27
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
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
NTSTATUS NTAPI USBAudioPinCreate(_In_ PKSPIN Pin, _In_ PIRP Irp)
Definition: pin.c:764
#define STATIC_KSNODETYPE_DESKTOP_MICROPHONE
Definition: ksmedia.h:456
#define STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY
Definition: ksmedia.h:476
#define STATIC_KSNODETYPE_COMMUNICATION_SPEAKER
Definition: ksmedia.h:501
#define REG_SZ
Definition: layer.c:22
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966