ReactOS  0.4.14-dev-77-gd9e7c48
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  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 
425 NTSTATUS
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;
438  PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor;
439  PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR OutputTerminalDescriptor;
440  PUSB_AUDIO_CONTROL_SELECTOR_UNIT_DESCRIPTOR SelectorUnitDescriptor;
441  PKSNODE_DESCRIPTOR NodeDescriptors;
442  PNODE_CONTEXT NodeContext, PreviousNodeContext;
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 
925 NTSTATUS
926 NTAPI
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 
968 VOID
969 NTAPI
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  {
1011  UNIMPLEMENTED;
1012  }
1013  }
1014  *NonStreamingTerminalDescriptorCount = NonStreamingTerminalCount;
1015  *TotalTerminalDescriptorCount = TotalTerminalCount;
1016 }
1017 
1018 LPGUID
1021 {
1022  if (TerminalDescriptor->wTerminalType == USB_AUDIO_MICROPHONE_TERMINAL_TYPE)
1023  return &NodeTypeMicrophone;
1024  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_MICROPHONE_TERMINAL_TYPE)
1025  return &NodeTypeDesktopMicrophone;
1026  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_PERSONAL_MICROPHONE_TERMINAL_TYPE)
1028  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_OMMNI_MICROPHONE_TERMINAL_TYPE)
1029  return &NodeTypeOmmniMicrophone;
1030  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_MICROPHONE_TERMINAL_TYPE)
1031  return &NodeTypeArrayMicrophone;
1032  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ARRAY_PROCESSING_MICROPHONE_TERMINAL_TYPE)
1034 
1035  /* playback types */
1036  if (TerminalDescriptor->wTerminalType == USB_AUDIO_SPEAKER_TERMINAL_TYPE)
1037  return &NodeTypeSpeaker;
1038  else if (TerminalDescriptor->wTerminalType == USB_HEADPHONES_SPEAKER_TERMINAL_TYPE)
1039  return &NodeTypeHeadphonesSpeaker;
1040  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_HMDA_TERMINAL_TYPE)
1041  return &NodeTypeHMDA;
1042  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_DESKTOP_SPEAKER_TERMINAL_TYPE)
1043  return &NodeTypeDesktopSpeaker;
1044  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_ROOM_SPEAKER_TERMINAL_TYPE)
1045  return &NodeTypeRoomSpeaker;
1046  else if (TerminalDescriptor->wTerminalType == USB_AUDIO_COMMUNICATION_SPEAKER_TERMINAL_TYPE)
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 
1153 VOID
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);
1224  DataRangeAudio->DataRange.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
1225  DataRangeAudio->DataRange.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
1227  DataRangeAudio->MaximumChannels = StreamingFormatDescriptor->bNrChannels;
1228  DataRangeAudio->MinimumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
1229  DataRangeAudio->MaximumBitsPerSample = StreamingFormatDescriptor->bBitResolution;
1230  NumFrequency = StreamingFormatDescriptor->bSamFreqType;
1231  DataRangeAudio->MinimumSampleFrequency = MAXULONG;
1232  DataRangeAudio->MaximumSampleFrequency = 0;
1233  for (Index = 0; Index < NumFrequency; Index++)
1234  {
1235  DataRangeAudio->MinimumSampleFrequency = min(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MinimumSampleFrequency);
1236  DataRangeAudio->MaximumSampleFrequency = max(StreamingFormatDescriptor->tSamFreq[Index * 3] | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 1] << 8 | StreamingFormatDescriptor->tSamFreq[(Index * 3) + 2] << 16, DataRangeAudio->MaximumSampleFrequency);
1237  }
1238  DataRangeAudioArray[DataRangeIndex] = (PKSDATARANGE)DataRangeAudio;
1239  DataRangeIndex++;
1240  }
1241  }
1242  Descriptor = (PUSB_INTERFACE_DESCRIPTOR)StreamingInterfaceDescriptor;
1243  }
1244  }
1245 
1246  *OutDataRanges = DataRangeAudioArray;
1247  *OutDataRangesCount = DataRangeCount;
1248 }
1249 
1250 
1251 NTSTATUS
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 
1350 NTSTATUS
1351 NTAPI
1355  IN ULONG DescriptorLength,
1356  IN UCHAR DescriptorIndex,
1357  IN LANGID LanguageId,
1358  OUT PVOID *OutDescriptor)
1359 {
1360  PURB Urb;
1361  NTSTATUS Status;
1362  PVOID Descriptor;
1363 
1364  /* sanity checks */
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 
1420 NTSTATUS
1421 NTAPI
1424  IN ULONG DescriptorLength,
1425  IN UCHAR DescriptorIndex,
1426  IN LANGID LanguageId,
1427  OUT PVOID *OutDescriptor)
1428 {
1429  NTSTATUS Status;
1430 
1431  /* retrieve descriptor */
1432  Status = USBAudioGetDescriptor(DeviceObject, USB_STRING_DESCRIPTOR_TYPE, DescriptorLength, DescriptorIndex, LanguageId, OutDescriptor);
1433  if (!NT_SUCCESS(Status))
1434  {
1435  // failed
1436  return Status;
1437  }
1438  return STATUS_SUCCESS;
1439 }
1440 
1441 NTSTATUS
1444  OUT PHANDLE OutHandle)
1445 {
1446  NTSTATUS Status;
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 */
1458  Status = ZwOpenKey(&Handle, KEY_ALL_ACCESS, &ObjectAttributes);
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 
1472 NTSTATUS
1474  PKSDEVICE Device,
1476 {
1477  PDEVICE_EXTENSION DeviceExtension;
1478  NTSTATUS Status;
1479  LPWSTR DescriptionBuffer;
1482  HANDLE hKey;
1483  GUID TempGuid;
1484 
1485  /* get device extension */
1486  DeviceExtension = Device->Context;
1487 
1488  /* init component id */
1489  ComponentId->Component = KSCOMPONENTID_USBAUDIO;
1490  ComponentId->Version = HIBYTE(DeviceExtension->DeviceDescriptor->bcdDevice);
1491  ComponentId->Revision = LOBYTE(DeviceExtension->DeviceDescriptor->bcdDevice);
1492 
1493  INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor);
1494  INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
1495  INIT_USBAUDIO_PRODUCT_NAME(&TempGuid, DeviceExtension->DeviceDescriptor->idVendor, DeviceExtension->DeviceDescriptor->idProduct, 0);
1496 
1497  if (DeviceExtension->DeviceDescriptor->iProduct)
1498  {
1499  Status = USBAudioGetStringDescriptor(DeviceExtension->LowerDevice, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iProduct, 0x0409 /* FIXME */, (PVOID*)&DescriptionBuffer);
1500  if (NT_SUCCESS(Status))
1501  {
1502  Status = RtlStringFromGUID(&TempGuid, &GuidString);
1503  if (NT_SUCCESS(Status))
1504  {
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 
1523 NTSTATUS
1524 NTAPI
1526  PKSDEVICE Device)
1527 {
1528  PKSFILTER_DESCRIPTOR FilterDescriptor;
1530  NTSTATUS Status;
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;
1546  FilterDescriptor->Categories = &GUID_KSCATEGORY_AUDIO;
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 
GUID NodeTypeRoomSpeaker
Definition: filter.c:22
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
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:970
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:1525
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:303
#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:927
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:1264
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:1154
#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:1063
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:1154
_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:1422
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:1252
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:1352
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTATUS USBAudioInitComponentId(PKSDEVICE Device, IN PKSCOMPONENTID ComponentId)
Definition: filter.c:1473
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:1442
#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:1108
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:301
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:277
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:426
#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:408
#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:2966
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:1019
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