ReactOS  r76032
pin.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/pin.c
5 * PURPOSE: USB Audio device driver.
6 * PROGRAMMERS:
7 * Johannes Anderwald (johannes.anderwald@reactos.org)
8 */
9 
10 #include "usbaudio.h"
11 
12 #define PACKET_COUNT 10
13 
14 
17  IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
18  IN PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
20 {
21  PUSB_COMMON_DESCRIPTOR CommonDescriptor;
22  PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
23 
24  /* loop descriptors */
25  CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
26  ASSERT(InterfaceDescriptor->bNumEndpoints > 0);
27  while (CommonDescriptor)
28  {
29  if (CommonDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
30  {
31  EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CommonDescriptor;
32  return EndpointDescriptor->wMaxPacketSize;
33  }
34 
35  if (CommonDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
36  {
37  /* reached next interface descriptor */
38  break;
39  }
40 
41  if ((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
42  break;
43 
44  CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
45  }
46 
47  /* default to 100 */
48  return 100;
49 }
50 
54  IN ULONG MaxPacketSize,
55  IN PVOID Buffer,
57  OUT PURB * OutUrb)
58 {
59  PURB Urb;
60  ULONG UrbSize;
61  ULONG Index;
62 
63  /* calculate urb size*/
64  UrbSize = GET_ISO_URB_SIZE(PACKET_COUNT);
65 
66  /* allocate urb */
67  Urb = AllocFunction(UrbSize);
68  if (!Urb)
69  {
70  /* no memory */
72  }
73 
74  /* init urb */
75  Urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
76  Urb->UrbIsochronousTransfer.Hdr.Length = UrbSize;
77  Urb->UrbIsochronousTransfer.PipeHandle = PipeHandle;
78  Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_START_ISO_TRANSFER_ASAP;
79  Urb->UrbIsochronousTransfer.TransferBufferLength = BufferLength;
80  Urb->UrbIsochronousTransfer.TransferBuffer = Buffer;
81  Urb->UrbIsochronousTransfer.NumberOfPackets = PACKET_COUNT;
82 
83  for (Index = 0; Index < PACKET_COUNT; Index++)
84  {
85  Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * MaxPacketSize;
86  }
87 
88  *OutUrb = Urb;
89  return STATUS_SUCCESS;
90 
91 }
92 
95  IN PKSPIN Pin)
96 {
97  PURB Urb;
98  PUCHAR SampleRateBuffer;
99  PPIN_CONTEXT PinContext;
101  PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx;
102 
103  /* allocate sample rate buffer */
104  SampleRateBuffer = AllocFunction(sizeof(ULONG));
105  if (!SampleRateBuffer)
106  {
107  /* no memory */
109  }
110 
111  if (IsEqualGUIDAligned(&Pin->ConnectionFormat->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) &&
112  IsEqualGUIDAligned(&Pin->ConnectionFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) &&
113  IsEqualGUIDAligned(&Pin->ConnectionFormat->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
114  {
115  WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat;
116  SampleRateBuffer[2] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 16) & 0xFF;
117  SampleRateBuffer[1] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 8) & 0xFF;
118  SampleRateBuffer[0] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 0) & 0xFF;
119 
120  /* TODO: verify connection format */
121  }
122  else
123  {
124  /* not supported yet*/
126  FreeFunction(SampleRateBuffer);
128  }
129 
130  /* allocate urb */
132  if (!Urb)
133  {
134  /* no memory */
135  FreeFunction(SampleRateBuffer);
137  }
138 
139  /* get pin context */
140  PinContext = Pin->Context;
141 
142  /* FIXME: determine controls and format urb */
147  0,
148  0x01, // SET_CUR
149  0x100,
150  PinContext->DeviceExtension->InterfaceInfo->Pipes[0].EndpointAddress,
151  SampleRateBuffer,
152  NULL,
153  3,
154  NULL);
155 
156 
157 
158  /* submit urb */
159  Status = SubmitUrbSync(PinContext->LowerDevice, Urb);
160 
161  DPRINT1("USBAudioPinSetDataFormat Pin %p Status %x\n", Pin, Status);
162  FreeFunction(Urb);
163  FreeFunction(SampleRateBuffer);
164  return Status;
165 }
166 
167 NTSTATUS
169  IN PKSPIN Pin,
170  IN PPIN_CONTEXT PinContext,
171  IN PDEVICE_EXTENSION DeviceExtension,
172  IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
173  IN ULONG FormatDescriptorIndex)
174 {
175  PURB Urb;
176  PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
178  ULONG Found, Index;
179 
180  PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR StreamingInterfaceDescriptor;
182 
183  /* search for terminal descriptor of that irp sink / irp source */
184  TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Pin->Id);
185  ASSERT(TerminalDescriptor != NULL);
186 
187  /* grab interface descriptor */
188  InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
189  if (!InterfaceDescriptor)
190  {
191  /* no such interface */
193  }
194 
195  Found = FALSE;
196  Index = 0;
197 
198  /* selects the interface which has an audio streaming interface descriptor associated to the input / output terminal at the given format index */
199  while (InterfaceDescriptor != NULL)
200  {
201  if (InterfaceDescriptor->bInterfaceSubClass == 0x02 /* AUDIO_STREAMING */ && InterfaceDescriptor->bNumEndpoints > 0)
202  {
203  StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, InterfaceDescriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
204  if (StreamingInterfaceDescriptor != NULL)
205  {
206  ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
207  ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
208  if (StreamingInterfaceDescriptor->bTerminalLink == TerminalDescriptor->bTerminalID)
209  {
210  if (FormatDescriptorIndex == Index)
211  {
212  Found = TRUE;
213  break;
214  }
215  Index++;
216  }
217  }
218  }
219  InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
220  }
221 
222  if (!Found)
223  {
224  /* no such interface */
225  DPRINT1("No Interface found\n");
227  }
228 
230  if (!Urb)
231  {
232  /* no memory */
234  }
235 
236  /* now prepare interface urb */
237  UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting);
238 
239  /* now select the interface */
240  Status = SubmitUrbSync(DeviceExtension->LowerDevice, Urb);
241 
242  DPRINT1("USBAudioSelectAudioStreamingInterface Status %x UrbStatus %x InterfaceNumber %x AlternateSetting %x\n", Status, Urb->UrbSelectInterface.Hdr.Status, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting);
243 
244  /* did it succeeed */
245  if (NT_SUCCESS(Status))
246  {
247  /* free old interface info */
248  if (DeviceExtension->InterfaceInfo)
249  {
250  /* free old info */
251  FreeFunction(DeviceExtension->InterfaceInfo);
252  }
253 
254  /* alloc interface info */
255  DeviceExtension->InterfaceInfo = AllocFunction(Urb->UrbSelectInterface.Interface.Length);
256  if (DeviceExtension->InterfaceInfo == NULL)
257  {
258  /* no memory */
259  FreeFunction(Urb);
261  }
262 
263  /* copy interface info */
264  RtlCopyMemory(DeviceExtension->InterfaceInfo, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
265  PinContext->InterfaceDescriptor = InterfaceDescriptor;
266  }
267 
268  /* free urb */
269  FreeFunction(Urb);
270  return Status;
271 }
272 
273 VOID
274 NTAPI
277 {
278  PKSPIN Pin;
279  PPIN_CONTEXT PinContext;
280  PKSGATE Gate;
281  ULONG Count;
282 
283  /* get pin */
284  Pin = Context;
285 
286  /* get pin context */
287  PinContext = Pin->Context;
288 
289  do
290  {
291  /* acquire processing mutex */
293 
294  /* get pin control gate */
295  Gate = KsPinGetAndGate(Pin);
296 
297  /* turn input on */
298  KsGateTurnInputOn(Gate);
299 
300  /* schedule processing */
302 
303  /* release processing mutex */
305 
306  /* decrement worker count */
307  Count = KsDecrementCountedWorker(PinContext->CaptureWorker);
308  } while (Count);
309 }
310 
311 NTSTATUS
313  IN PKSPIN Pin,
314  IN PPIN_CONTEXT PinContext,
315  IN OUT PIRP Irp,
316  IN PVOID TransferBuffer,
317  IN ULONG TransferBufferSize,
319 {
320  ULONG Index, PacketCount;
321  PURB Urb;
322  PIO_STACK_LOCATION IoStack;
323 
324  /* initialize irp */
325  IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize);
326 
327  /* set irp members */
328  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
329  Irp->IoStatus.Information = 0;
330  Irp->Flags = 0;
331  Irp->UserBuffer = NULL;
332 
333  /* init stack location */
334  IoStack = IoGetNextIrpStackLocation(Irp);
335  IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
336  IoStack->Parameters.Others.Argument2 = NULL;
339 
340  /* set completion routine */
342 
343  /* calculate packet count */
344  PacketCount = TransferBufferSize / PacketSize;
345  ASSERT(TransferBufferSize % PacketSize == 0);
346 
347  /* lets allocate urb */
348  Urb = (PURB)AllocFunction(GET_ISO_URB_SIZE(PacketCount));
349  if (!Urb)
350  {
351  /* no memory */
353  }
354 
355  /* init urb */
356  Urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
357  Urb->UrbIsochronousTransfer.Hdr.Length = GET_ISO_URB_SIZE(PacketCount);
358  Urb->UrbIsochronousTransfer.PipeHandle = PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle;
359  Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_OUT | USBD_START_ISO_TRANSFER_ASAP;
360  Urb->UrbIsochronousTransfer.TransferBufferLength = TransferBufferSize;
361  Urb->UrbIsochronousTransfer.TransferBuffer = TransferBuffer;
362  Urb->UrbIsochronousTransfer.NumberOfPackets = PacketCount;
363  Urb->UrbIsochronousTransfer.StartFrame = 0;
364 
365  for (Index = 0; Index < PacketCount; Index++)
366  {
367  Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * PacketSize;
368  }
369 
370  /* store urb */
371  IoStack->Parameters.Others.Argument1 = Urb;
372  Irp->Tail.Overlay.DriverContext[0] = Urb;
373 
374 
375  /* done */
376  return STATUS_SUCCESS;
377 }
378 
379 VOID
381  IN PKSPIN Pin,
382  IN PIRP Irp)
383 {
384  PIO_STACK_LOCATION IoStack;
385  PURB Urb;
386  PUCHAR TransferBuffer;
387  ULONG Index;
388  PPIN_CONTEXT PinContext;
389 
390  /* get pin context */
391  PinContext = Pin->Context;
392 
393  /* backup urb and transferbuffer */
394  Urb = Irp->Tail.Overlay.DriverContext[0];
395  TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
396 
397  /* initialize irp */
398  IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize);
399 
400  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
401  Irp->IoStatus.Information = 0;
402  Irp->Flags = 0;
403  Irp->UserBuffer = NULL;
404  Irp->Tail.Overlay.DriverContext[0] = Urb;
405  Irp->Tail.Overlay.DriverContext[1] = NULL;
406 
407  /* init stack location */
408  IoStack = IoGetNextIrpStackLocation(Irp);
409  IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
410  IoStack->Parameters.Others.Argument1 = Urb;
411  IoStack->Parameters.Others.Argument2 = NULL;
414 
416 
418 
419  /* init urb */
420  Urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
421  Urb->UrbIsochronousTransfer.Hdr.Length = GET_ISO_URB_SIZE(10);
422  Urb->UrbIsochronousTransfer.PipeHandle = PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle;
423  Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_START_ISO_TRANSFER_ASAP;
424  Urb->UrbIsochronousTransfer.TransferBufferLength = PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize * 10;
425  Urb->UrbIsochronousTransfer.TransferBuffer = TransferBuffer;
426  Urb->UrbIsochronousTransfer.NumberOfPackets = PACKET_COUNT;
427  Urb->UrbIsochronousTransfer.StartFrame = 0;
428 
429  for (Index = 0; Index < PACKET_COUNT; Index++)
430  {
431  Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize;
432  }
433 }
434 
435 
436 VOID
437 NTAPI
440 {
441  PKSPIN Pin;
442  PPIN_CONTEXT PinContext;
443  KIRQL OldLevel;
444  PLIST_ENTRY CurEntry;
445  PIRP Irp;
446 
447  /* get pin */
448  Pin = Context;
449 
450  /* get pin context */
451  PinContext = Pin->Context;
452 
453  /* acquire spin lock */
454  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
455 
456  if (!IsListEmpty(&PinContext->IrpListHead))
457  {
458  /* sanity check */
459  ASSERT(!IsListEmpty(&PinContext->IrpListHead));
460 
461  /* remove entry from list */
462  CurEntry = RemoveHeadList(&PinContext->IrpListHead);
463 
464  /* release lock */
465  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
466 
467  /* get irp offset */
468  Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
469 
470  /* reinitialize irp and urb */
471  CaptureInitializeUrbAndIrp(Pin, Irp);
472 
474 
475  /* call driver */
476  IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
477  }
478  else
479  {
480  /* release lock */
481  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
482 
484  }
485 }
486 
487 
488 
489 NTSTATUS
491  IN PKSPIN Pin)
492 {
494  ULONG Index;
496  ULONG MaximumPacketSize;
497  PIRP Irp;
498  PURB Urb;
499  PPIN_CONTEXT PinContext;
500  PIO_STACK_LOCATION IoStack;
501  PKSALLOCATOR_FRAMING_EX Framing;
502  PKSGATE Gate;
503 
504 
505  /* set sample rate */
506  Status = UsbAudioSetFormat(Pin);
507  if (!NT_SUCCESS(Status))
508  {
509  /* failed */
510  return Status;
511  }
512 
513  /* get pin context */
514  PinContext = Pin->Context;
515 
516  /* lets get maximum packet size */
517  MaximumPacketSize = GetMaxPacketSizeForInterface(PinContext->DeviceExtension->ConfigurationDescriptor, PinContext->InterfaceDescriptor, Pin->DataFlow);
518 
519  /* initialize work item for capture worker */
521 
522  /* register worker */
523  Status = KsRegisterCountedWorker(CriticalWorkQueue, &PinContext->CaptureWorkItem, &PinContext->CaptureWorker);
524  if (!NT_SUCCESS(Status))
525  {
526  /* failed */
527  return Status;
528  }
529 
530  /* initialize work item */
532 
533  /* register worker */
535  if (!NT_SUCCESS(Status))
536  {
537  /* failed */
538  KsUnregisterWorker(PinContext->CaptureWorker);
539  }
540 
541  /* lets edit framing struct */
542  Framing = (PKSALLOCATOR_FRAMING_EX)Pin->Descriptor->AllocatorFraming;
547  MaximumPacketSize;
548 
549  /* calculate buffer size 8 irps * 10 iso packets * max packet size */
550  BufferSize = 8 * PACKET_COUNT * MaximumPacketSize;
551 
552  /* allocate pin capture buffer */
553  PinContext->BufferSize = BufferSize;
554  PinContext->Buffer = AllocFunction(BufferSize);
555  if (!PinContext->Buffer)
556  {
557  /* no memory */
559  }
560  KsAddItemToObjectBag(Pin->Bag, PinContext->Buffer, ExFreePool);
561 
562  /* init irps */
563  for (Index = 0; Index < 8; Index++)
564  {
565  /* allocate irp */
566  Irp = AllocFunction(IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize));
567  if (!Irp)
568  {
569  /* no memory */
571  }
572 
573  /* initialize irp */
574  IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize);
575 
576  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
577  Irp->IoStatus.Information = 0;
578  Irp->Flags = 0;
579  Irp->UserBuffer = NULL;
580 
581  IoStack = IoGetNextIrpStackLocation(Irp);
582  IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
583  IoStack->Parameters.Others.Argument2 = NULL;
586 
588 
589  /* insert into irp list */
590  InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
591 
592  /* add to object bag*/
593  KsAddItemToObjectBag(Pin->Bag, Irp, ExFreePool);
594 
595  /* FIXME select correct pipe handle */
596  Status = UsbAudioAllocCaptureUrbIso(PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle,
597  MaximumPacketSize,
598  &PinContext->Buffer[MaximumPacketSize * PACKET_COUNT * Index],
599  MaximumPacketSize * PACKET_COUNT,
600  &Urb);
601 
602  DPRINT1("InitCapturePin Irp %p Urb %p\n", Irp, Urb);
603 
604  if (NT_SUCCESS(Status))
605  {
606  /* get next stack location */
607  IoStack = IoGetNextIrpStackLocation(Irp);
608 
609  /* store urb */
610  IoStack->Parameters.Others.Argument1 = Urb;
611  Irp->Tail.Overlay.DriverContext[0] = Urb;
612  }
613  else
614  {
615  /* failed */
616  return Status;
617  }
618  }
619 
620  /* get process control gate */
621  Gate = KsPinGetAndGate(Pin);
622 
623  /* turn input off */
624  KsGateTurnInputOff(Gate);
625 
626  return Status;
627 }
628 
629 NTSTATUS
631  IN PKSPIN Pin)
632 {
633  ULONG Index;
634  PIRP Irp;
635  PPIN_CONTEXT PinContext;
636  PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx;
637  PIO_STACK_LOCATION IoStack;
638 
639  DPRINT1("InitStreamPin\n");
640 
641  /* get pin context */
642  PinContext = Pin->Context;
643 
644  /* allocate 1 sec buffer */
645  WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat;
646  PinContext->Buffer = AllocFunction(WaveFormatEx->WaveFormatEx.nAvgBytesPerSec);
647  if (!PinContext->Buffer)
648  {
649  /* no memory */
651  }
652 
653  /* init buffer size*/
654  PinContext->BufferSize = WaveFormatEx->WaveFormatEx.nAvgBytesPerSec;
655  PinContext->BufferOffset = 0;
656  PinContext->BufferLength = 0;
657 
658  /* init irps */
659  for (Index = 0; Index < 12; Index++)
660  {
661  /* allocate irp */
662  Irp = AllocFunction(IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize));
663  if (!Irp)
664  {
665  /* no memory */
667  }
668 
669  DPRINT1("InitStreamPin Irp %p\n", Irp);
670 
671  /* initialize irp */
672  IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize);
673 
674  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
675  Irp->IoStatus.Information = 0;
676  Irp->Flags = 0;
677  Irp->UserBuffer = NULL;
678 
679  IoStack = IoGetNextIrpStackLocation(Irp);
680  IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
681  IoStack->Parameters.Others.Argument2 = NULL;
684 
686 
687  /* insert into irp list */
688  InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
689 
690  /* add to object bag*/
691  KsAddItemToObjectBag(Pin->Bag, Irp, ExFreePool);
692  }
693 
694  return STATUS_SUCCESS;
695 }
696 
697 ULONG
699  IN PKSDATARANGE ConnectionFormat,
700  IN PKSDATARANGE * DataRanges,
701  IN ULONG DataRangesCount)
702 {
703  ULONG Index;
704  PKSDATARANGE CurrentDataRange;
705  PKSDATARANGE_AUDIO CurrentAudioDataRange;
706  PKSDATAFORMAT_WAVEFORMATEX ConnectionDataFormat;
707 
708  if (ConnectionFormat->FormatSize != sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX))
709  {
710  /* unsupported connection format */
711  DPRINT1("GetDataRangeIndexForFormat expected KSDATARANGE_AUDIO\n");
712  return MAXULONG;
713  }
714 
715  /* cast to right type */
716  ConnectionDataFormat = (PKSDATAFORMAT_WAVEFORMATEX)ConnectionFormat;
717 
718  for (Index = 0; Index < DataRangesCount; Index++)
719  {
720  /* get current data range */
721  CurrentDataRange = DataRanges[Index];
722 
723  /* compare guids */
724  if (!IsEqualGUIDAligned(&CurrentDataRange->MajorFormat, &ConnectionFormat->MajorFormat) ||
725  !IsEqualGUIDAligned(&CurrentDataRange->SubFormat, &ConnectionFormat->SubFormat) ||
726  !IsEqualGUIDAligned(&CurrentDataRange->Specifier, &ConnectionFormat->Specifier))
727  {
728  /* no match */
729  continue;
730  }
731 
732  /* all pin data ranges are KSDATARANGE_AUDIO */
733  CurrentAudioDataRange = (PKSDATARANGE_AUDIO)CurrentDataRange;
734 
735  /* check if number of channel match */
736  if (CurrentAudioDataRange->MaximumChannels != ConnectionDataFormat->WaveFormatEx.nChannels)
737  {
738  /* number of channels mismatch */
739  continue;
740  }
741 
742  if (CurrentAudioDataRange->MinimumSampleFrequency > ConnectionDataFormat->WaveFormatEx.nSamplesPerSec)
743  {
744  /* channel frequency too low */
745  continue;
746  }
747 
748  if (CurrentAudioDataRange->MaximumSampleFrequency < ConnectionDataFormat->WaveFormatEx.nSamplesPerSec)
749  {
750  /* channel frequency too high */
751  continue;
752  }
753 
754  /* FIXME add checks for bitrate / sample size etc */
755  return Index;
756  }
757 
758  /* no datarange found */
759  return MAXULONG;
760 }
761 
762 NTSTATUS
763 NTAPI
765  _In_ PKSPIN Pin,
766  _In_ PIRP Irp)
767 {
768  PKSFILTER Filter;
770  PPIN_CONTEXT PinContext;
772  ULONG FormatIndex;
773 
774  Filter = KsPinGetParentFilter(Pin);
775  if (Filter == NULL)
776  {
777  /* invalid parameter */
779  }
780 
781  /* get filter context */
782  FilterContext = Filter->Context;
783 
784  /* allocate pin context */
785  PinContext = AllocFunction(sizeof(PIN_CONTEXT));
786  if (!PinContext)
787  {
788  /* no memory*/
790  }
791 
792  /* init pin context */
793  PinContext->DeviceExtension = FilterContext->DeviceExtension;
794  PinContext->LowerDevice = FilterContext->LowerDevice;
795  InitializeListHead(&PinContext->IrpListHead);
796  InitializeListHead(&PinContext->DoneIrpListHead);
797  KeInitializeSpinLock(&PinContext->IrpListLock);
798 
799  /* store pin context*/
800  Pin->Context = PinContext;
801 
802  /* lets edit allocator framing struct */
803  Status = _KsEdit(Pin->Bag, (PVOID*)&Pin->Descriptor, sizeof(KSPIN_DESCRIPTOR_EX), sizeof(KSPIN_DESCRIPTOR_EX), USBAUDIO_TAG);
804  if (NT_SUCCESS(Status))
805  {
806  Status = _KsEdit(Pin->Bag, (PVOID*)&Pin->Descriptor->AllocatorFraming, sizeof(KSALLOCATOR_FRAMING_EX), sizeof(KSALLOCATOR_FRAMING_EX), USBAUDIO_TAG);
807  ASSERT(Status == STATUS_SUCCESS);
808  }
809 
810  /* choose correct dataformat */
811  FormatIndex = GetDataRangeIndexForFormat(Pin->ConnectionFormat, Pin->Descriptor->PinDescriptor.DataRanges, Pin->Descriptor->PinDescriptor.DataRangesCount);
812  if (FormatIndex == MAXULONG)
813  {
814  /* no format match */
815  return STATUS_NO_MATCH;
816  }
817 
818  /* select streaming interface */
819  Status = USBAudioSelectAudioStreamingInterface(Pin, PinContext, PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor, FormatIndex);
820  if (!NT_SUCCESS(Status))
821  {
822  /* failed */
823  DPRINT1("USBAudioSelectAudioStreamingInterface failed with %x\n", Status);
824  return Status;
825  }
826 
827  if (Pin->DataFlow == KSPIN_DATAFLOW_OUT)
828  {
829  /* init capture pin */
830  Status = InitCapturePin(Pin);
831  }
832  else
833  {
834  /* audio streaming pin*/
835  Status = InitStreamPin(Pin);
836  }
837 
838  return Status;
839 }
840 
841 NTSTATUS
842 NTAPI
844  _In_ PKSPIN Pin,
845  _In_ PIRP Irp)
846 {
848  return STATUS_NOT_IMPLEMENTED;
849 }
850 
851 NTSTATUS
852 NTAPI
855  IN PIRP Irp,
856  IN PVOID Context)
857 {
858  PKSPIN Pin;
859  PPIN_CONTEXT PinContext;
860  KIRQL OldLevel;
861  PKSSTREAM_POINTER StreamPointerClone;
863  PURB Urb;
864 
865  /* get pin context */
866  Pin = Context;
867  PinContext = Pin->Context;
868 
869  /* get status */
870  Status = Irp->IoStatus.Status;
871 
872  /* get streampointer */
873  StreamPointerClone = Irp->Tail.Overlay.DriverContext[1];
874 
875  /* get urb */
876  Urb = Irp->Tail.Overlay.DriverContext[0];
877 
878  /* and free it */
879  FreeFunction(Urb);
880 
881  /* acquire lock */
882  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
883 
884  /* insert entry into ready list */
885  InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
886 
887  /* release lock */
888  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
889 
890  if (!NT_SUCCESS(Status) && StreamPointerClone)
891  {
892  /* set status code because it failed */
894  DPRINT1("UsbAudioRenderComplete failed with %x\n", Status);
895  }
896 
897  if (StreamPointerClone)
898  {
899  /* lets delete the stream pointer clone */
900  KsStreamPointerDelete(StreamPointerClone);
901  }
902 
903  /* done */
905 }
906 
907 NTSTATUS
908 NTAPI
911  IN PIRP Irp,
912  IN PVOID Context)
913 {
914  PKSPIN Pin;
915  PPIN_CONTEXT PinContext;
916  KIRQL OldLevel;
917  PURB Urb;
918 
919  /* get pin context */
920  Pin = Context;
921  PinContext = Pin->Context;
922 
923  /* get urb */
924  Urb = Irp->Tail.Overlay.DriverContext[0];
925 
926  /* acquire lock */
927  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
928 
929  if (!NT_SUCCESS(Urb->UrbIsochronousTransfer.Hdr.Status))
930  {
931  //DPRINT("UsbAudioCaptureComplete Irp %p Urb %p Status %x Packet Status %x\n", Irp, Urb, Urb->UrbIsochronousTransfer.Hdr.Status, Urb->UrbIsochronousTransfer.IsoPacket[0].Status);
932 
933  /* insert entry into ready list */
934  InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
935 
936  /* release lock */
937  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
938 
940  }
941  else
942  {
943  /* insert entry into done list */
944  InsertTailList(&PinContext->DoneIrpListHead, &Irp->Tail.Overlay.ListEntry);
945 
946  /* release lock */
947  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
948 
950  }
951 
952  /* done */
954 }
955 
956 PIRP
958  IN PKSPIN Pin)
959 {
960  PPIN_CONTEXT PinContext;
961  PLIST_ENTRY CurEntry;
962  KIRQL OldLevel;
963  PIRP Irp = NULL;
964 
965  /* get pin context */
966  PinContext = Pin->Context;
967 
968  /* acquire spin lock */
969  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
970 
971  if (!IsListEmpty(&PinContext->IrpListHead))
972  {
973  /* remove entry from list */
974  CurEntry = RemoveHeadList(&PinContext->IrpListHead);
975 
976  /* get irp offset */
977  Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
978  }
979 
980  /* release lock */
981  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
982 
983  return Irp;
984 }
985 
986 NTSTATUS
988  IN PKSPIN Pin)
989 {
990  PKSSTREAM_POINTER LeadingStreamPointer;
991  PKSSTREAM_POINTER CloneStreamPointer;
993  PPIN_CONTEXT PinContext;
994  ULONG PacketCount, TotalPacketSize, Offset;
995  PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx;
996  PUCHAR TransferBuffer;
997  PIRP Irp = NULL;
998 
999  //DPRINT1("PinRenderProcess\n");
1000 
1002  if (LeadingStreamPointer == NULL)
1003  {
1004  return STATUS_SUCCESS;
1005  }
1006 
1007  if (NULL == LeadingStreamPointer->StreamHeader->Data)
1008  {
1009  Status = KsStreamPointerAdvance(LeadingStreamPointer);
1010  DPRINT1("Advancing Streampointer\n");
1011  }
1012 
1013 
1014  /* get pin context */
1015  PinContext = Pin->Context;
1016 
1017  /* get irp from ready list */
1018  Irp = PinGetIrpFromReadyList(Pin);
1019 
1020  if (!Irp)
1021  {
1022  /* no irps available */
1023  DPRINT1("No irps available");
1024  KsStreamPointerUnlock(LeadingStreamPointer, TRUE);
1025  return STATUS_SUCCESS;
1026  }
1027 
1028  /* clone stream pointer */
1029  Status = KsStreamPointerClone(LeadingStreamPointer, NULL, 0, &CloneStreamPointer);
1030  if (!NT_SUCCESS(Status))
1031  {
1032  /* failed */
1033  KsStreamPointerUnlock(LeadingStreamPointer, TRUE);
1034  DPRINT1("Leaking Irp %p\n", Irp);
1035  return STATUS_SUCCESS;
1036  }
1037 
1038  /* calculate packet count */
1039  /* FIXME support various sample rates */
1040  WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat;
1041  TotalPacketSize = WaveFormatEx->WaveFormatEx.nAvgBytesPerSec / 1000;
1042 
1043  /* init transfer buffer*/
1044  TransferBuffer = CloneStreamPointer->StreamHeader->Data;
1045 
1046  Offset = 0;
1047 
1048  /* are there bytes from previous request*/
1049  if (PinContext->BufferLength)
1050  {
1051  ASSERT(PinContext->BufferLength < TotalPacketSize);
1052 
1053  /* calculate offset*/
1054  Offset = TotalPacketSize - PinContext->BufferLength;
1055 
1056  if (PinContext->BufferOffset + TotalPacketSize >= PinContext->BufferSize)
1057  {
1058  RtlMoveMemory(PinContext->Buffer, &PinContext->Buffer[PinContext->BufferOffset - PinContext->BufferLength], PinContext->BufferLength);
1059  PinContext->BufferOffset = PinContext->BufferLength;
1060  }
1061 
1062  /* copy audio bytes */
1063  RtlCopyMemory(&PinContext->Buffer[PinContext->BufferOffset], TransferBuffer, Offset);
1064 
1065  /* init irp*/
1066  Status = RenderInitializeUrbAndIrp(Pin, PinContext, Irp, &PinContext->Buffer[PinContext->BufferOffset-PinContext->BufferLength], TotalPacketSize, TotalPacketSize);
1067  if (NT_SUCCESS(Status))
1068  {
1069  /* render audio bytes */
1070  Status = IoCallDriver(PinContext->LowerDevice, Irp);
1071  }
1072  else
1073  {
1074  ASSERT(FALSE);
1075  }
1076 
1077  PinContext->BufferLength = 0;
1078  PinContext->BufferOffset += Offset;
1079 
1080  /* get new irp from ready list */
1081  Irp = PinGetIrpFromReadyList(Pin);
1082  ASSERT(Irp);
1083 
1084  }
1085 
1086  /* FIXME correct MaximumPacketSize ? */
1087  PacketCount = (CloneStreamPointer->OffsetIn.Remaining - Offset) / TotalPacketSize;
1088 
1089  Status = RenderInitializeUrbAndIrp(Pin, PinContext, Irp, &TransferBuffer[Offset], PacketCount * TotalPacketSize, TotalPacketSize);
1090  if (NT_SUCCESS(Status))
1091  {
1092  /* store in irp context */
1093  Irp->Tail.Overlay.DriverContext[1] = CloneStreamPointer;
1094 
1095  if ((PacketCount * TotalPacketSize) + Offset < CloneStreamPointer->OffsetIn.Remaining)
1096  {
1097  /* calculate remaining buffer bytes */
1098  PinContext->BufferLength = CloneStreamPointer->OffsetIn.Remaining - ((PacketCount * TotalPacketSize) + Offset);
1099 
1100  /* check for overflow */
1101  if (PinContext->BufferOffset + TotalPacketSize >= PinContext->BufferSize)
1102  {
1103  /* reset buffer offset*/
1104  PinContext->BufferOffset = 0;
1105  }
1106  RtlCopyMemory(&PinContext->Buffer[PinContext->BufferOffset], &TransferBuffer[(PacketCount * TotalPacketSize) + Offset], PinContext->BufferLength);
1107  PinContext->BufferOffset += PinContext->BufferLength;
1108  }
1109 
1110  /* render audio bytes */
1111  Status = IoCallDriver(PinContext->LowerDevice, Irp);
1112  }
1113 
1114 
1115  /* unlock stream pointer and finish*/
1116  KsStreamPointerUnlock(LeadingStreamPointer, TRUE);
1117  return STATUS_PENDING;
1118 }
1119 
1120 NTSTATUS
1122  IN PKSPIN Pin)
1123 {
1124  PKSSTREAM_POINTER LeadingStreamPointer;
1125  KIRQL OldLevel;
1126  PPIN_CONTEXT PinContext;
1127  PLIST_ENTRY CurEntry;
1128  PIRP Irp;
1129  PURB Urb;
1130  PUCHAR TransferBuffer, OutBuffer;
1131  ULONG Offset, Length;
1132  NTSTATUS Status;
1133  PKSGATE Gate;
1134 
1135  //DPRINT1("PinCaptureProcess\n");
1137  if (LeadingStreamPointer == NULL)
1138  {
1139  /* get process control gate */
1140  Gate = KsPinGetAndGate(Pin);
1141 
1142  /* shutdown processing */
1143  KsGateTurnInputOff(Gate);
1144 
1145  return STATUS_SUCCESS;
1146  }
1147 
1148  /* get pin context */
1149  PinContext = Pin->Context;
1150 
1151  /* acquire spin lock */
1152  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1153 
1154  while (!IsListEmpty(&PinContext->DoneIrpListHead))
1155  {
1156  /* remove entry from list */
1157  CurEntry = RemoveHeadList(&PinContext->DoneIrpListHead);
1158 
1159  /* release lock */
1160  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1161 
1162  /* get irp offset */
1163  Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
1164 
1165  /* get urb from irp */
1166  Urb = (PURB)Irp->Tail.Overlay.DriverContext[0];
1167  ASSERT(Urb);
1168 
1169  Offset = PtrToUlong(Irp->Tail.Overlay.DriverContext[1]);
1170 
1171  /* get transfer buffer */
1172  TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
1173 
1174  /* get target buffer */
1175  OutBuffer = (PUCHAR)LeadingStreamPointer->StreamHeader->Data;
1176 
1177  /* calculate length */
1178  Length = min(LeadingStreamPointer->OffsetOut.Count - LeadingStreamPointer->StreamHeader->DataUsed, Urb->UrbIsochronousTransfer.TransferBufferLength - Offset);
1179 
1180  /* FIXME copy each packet extra */
1181  /* copy audio bytes */
1182  RtlCopyMemory((PUCHAR)&OutBuffer[LeadingStreamPointer->StreamHeader->DataUsed], &TransferBuffer[Offset], Length);
1183 
1184  //DPRINT1("Irp %p Urb %p OutBuffer %p TransferBuffer %p Offset %lu Remaining %lu TransferBufferLength %lu Length %lu\n", Irp, Urb, OutBuffer, TransferBuffer, Offset, LeadingStreamPointer->OffsetOut.Remaining, Urb->UrbIsochronousTransfer.TransferBufferLength, Length);
1185 
1186  /* adjust streampointer */
1187  LeadingStreamPointer->StreamHeader->DataUsed += Length;
1188 
1189  if (Length == LeadingStreamPointer->OffsetOut.Remaining)
1190  {
1191  KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Length, TRUE);
1192 
1193  /* acquire spin lock */
1194  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1195 
1196  /* adjust offset */
1197  Irp->Tail.Overlay.DriverContext[1] = UlongToPtr(Length);
1198 
1199  /* reinsert into processed list */
1200  InsertHeadList(&PinContext->DoneIrpListHead, &Irp->Tail.Overlay.ListEntry);
1201 
1202  /* release lock */
1203  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1204 
1206  if (LeadingStreamPointer == NULL)
1207  {
1208  /* no more work to be done*/
1209  return STATUS_PENDING;
1210  }
1211  else
1212  {
1213  /* resume work on this irp */
1214  continue;
1215  }
1216  }
1217  else
1218  {
1219  Status = KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Length, FALSE);
1220  NT_ASSERT(NT_SUCCESS(Status));
1221  ASSERT(Length == Urb->UrbIsochronousTransfer.TransferBufferLength - Offset);
1222  }
1223 
1224 
1225  /* acquire spin lock */
1226  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1227 
1228  InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
1229  }
1230 
1231  while (!IsListEmpty(&PinContext->IrpListHead))
1232  {
1233  /* remove entry from list */
1234  CurEntry = RemoveHeadList(&PinContext->IrpListHead);
1235 
1236  /* release lock */
1237  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1238 
1239  /* get irp offset */
1240  Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
1241 
1242  /* reinitialize irp and urb */
1243  CaptureInitializeUrbAndIrp(Pin, Irp);
1244 
1245  IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
1246 
1247  /* acquire spin lock */
1248  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1249 
1250  }
1251 
1252  /* release lock */
1253  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1254 
1255  if (LeadingStreamPointer != NULL)
1256  KsStreamPointerUnlock(LeadingStreamPointer, FALSE);
1257 
1258  /* get process control gate */
1259  Gate = KsPinGetAndGate(Pin);
1260 
1261  /* shutdown processing */
1262  KsGateTurnInputOff(Gate);
1263 
1264  return STATUS_PENDING;
1265 }
1266 
1267 
1268 NTSTATUS
1269 NTAPI
1271  _In_ PKSPIN Pin)
1272 {
1273  NTSTATUS Status;
1274 
1275  if (Pin->DataFlow == KSPIN_DATAFLOW_OUT)
1276  {
1277  Status = PinCaptureProcess(Pin);
1278  }
1279  else
1280  {
1281  Status = PinRenderProcess(Pin);
1282  }
1283 
1284  return Status;
1285 }
1286 
1287 
1288 VOID
1289 NTAPI
1291  _In_ PKSPIN Pin)
1292 {
1293  UNIMPLEMENTED;
1294 }
1295 
1296 NTSTATUS
1297 NTAPI
1299  _In_ PKSPIN Pin,
1300  _In_opt_ PKSDATAFORMAT OldFormat,
1301  _In_opt_ PKSMULTIPLE_ITEM OldAttributeList,
1302  _In_ const KSDATARANGE* DataRange,
1303  _In_opt_ const KSATTRIBUTE_LIST* AttributeRange)
1304 {
1305  if (OldFormat == NULL)
1306  {
1307  /* TODO: verify connection format */
1308  UNIMPLEMENTED;
1309  return STATUS_SUCCESS;
1310  }
1311 
1312  return UsbAudioSetFormat(Pin);
1313 }
1314 
1315 NTSTATUS
1317  IN PKSPIN Pin)
1318 {
1319  PPIN_CONTEXT PinContext;
1320  PLIST_ENTRY CurEntry;
1321  PIRP Irp;
1322  KIRQL OldLevel;
1323 
1324  /* get pin context */
1325  PinContext = Pin->Context;
1326 
1327  /* acquire spin lock */
1328  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1329 
1330  while(!IsListEmpty(&PinContext->IrpListHead))
1331  {
1332  /* remove entry from list */
1333  CurEntry = RemoveHeadList(&PinContext->IrpListHead);
1334 
1335  /* get irp offset */
1336  Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
1337 
1338  /* release lock */
1339  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1340 
1341  /* reinitialize irp and urb */
1342  CaptureInitializeUrbAndIrp(Pin, Irp);
1343 
1344  DPRINT("StartCaptureIsocTransfer Irp %p\n", Irp);
1345  IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
1346 
1347  /* acquire spin lock */
1348  KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1349 
1350  }
1351 
1352  /* release lock */
1353  KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1354 
1355  return STATUS_SUCCESS;
1356 }
1357 
1358 NTSTATUS
1360  _In_ PKSPIN Pin,
1361  _In_ KSSTATE ToState,
1362  _In_ KSSTATE FromState)
1363 {
1365 
1366  if (FromState != ToState)
1367  {
1368  if (ToState)
1369  {
1370  if (ToState == KSSTATE_PAUSE)
1371  {
1372  if (FromState == KSSTATE_RUN)
1373  {
1374  /* wait until pin processing is finished*/
1375  }
1376  }
1377  else
1378  {
1379  if (ToState == KSSTATE_RUN)
1380  {
1381  Status = StartCaptureIsocTransfer(Pin);
1382  }
1383  }
1384  }
1385  }
1386  return Status;
1387 }
1388 
1389 
1390 NTSTATUS
1391 NTAPI
1393  _In_ PKSPIN Pin,
1394  _In_ KSSTATE ToState,
1395  _In_ KSSTATE FromState)
1396 {
1397  NTSTATUS Status;
1398 
1399  if (Pin->DataFlow == KSPIN_DATAFLOW_OUT)
1400  {
1401  /* handle capture state changes */
1402  Status = CapturePinStateChange(Pin, ToState, FromState);
1403  }
1404  else
1405  {
1406  UNIMPLEMENTED;
1407  Status = STATUS_SUCCESS;
1408  }
1409 
1410  return Status;
1411 }
1412 
1413 
1414 NTSTATUS
1415 NTAPI
1417  _In_ PVOID Context,
1418  _In_ PIRP Irp,
1419  _In_ PKSP_PIN Pin,
1420  _In_ PKSDATARANGE DataRange,
1421  _In_ PKSDATARANGE MatchingDataRange,
1422  _In_ ULONG DataBufferSize,
1423  _Out_ PVOID Data,
1425 {
1426  PKSFILTER Filter;
1427  PKSPIN_DESCRIPTOR_EX PinDescriptor;
1429  PKSDATARANGE_AUDIO DataRangeAudio;
1430 
1431  /* get filter from irp*/
1432  Filter = KsGetFilterFromIrp(Irp);
1433  if (!Filter)
1434  {
1435  /* no match*/
1436  return STATUS_NO_MATCH;
1437  }
1438 
1439  /* get pin descriptor */
1440  PinDescriptor = (PKSPIN_DESCRIPTOR_EX)&Filter->Descriptor->PinDescriptors[Pin->PinId];
1441 
1442  *DataSize = sizeof(KSDATAFORMAT_WAVEFORMATEX);
1443  if (DataBufferSize == 0)
1444  {
1445  /* buffer too small */
1446  return STATUS_BUFFER_OVERFLOW;
1447  }
1448 
1449  /* sanity checks*/
1450  ASSERT(PinDescriptor->PinDescriptor.DataRangesCount >= 0);
1451  ASSERT(PinDescriptor->PinDescriptor.DataRanges[0]->FormatSize == sizeof(KSDATARANGE_AUDIO));
1452 
1453  DataRangeAudio = (PKSDATARANGE_AUDIO)PinDescriptor->PinDescriptor.DataRanges[0];
1454 
1455  DataFormat = Data;
1456  DataFormat->WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
1457  DataFormat->WaveFormatEx.nChannels = DataRangeAudio->MaximumChannels;
1458  DataFormat->WaveFormatEx.nSamplesPerSec = DataRangeAudio->MaximumSampleFrequency;
1459  DataFormat->WaveFormatEx.nAvgBytesPerSec = DataRangeAudio->MaximumSampleFrequency * (DataRangeAudio->MaximumBitsPerSample / 8) * DataRangeAudio->MaximumChannels;
1460  DataFormat->WaveFormatEx.nBlockAlign = (DataRangeAudio->MaximumBitsPerSample / 8) * DataRangeAudio->MaximumChannels;
1461  DataFormat->WaveFormatEx.wBitsPerSample = DataRangeAudio->MaximumBitsPerSample;
1462  DataFormat->WaveFormatEx.cbSize = 0;
1463 
1464  DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
1465  DataFormat->DataFormat.Flags = 0;
1466  DataFormat->DataFormat.Reserved = 0;
1470  DataFormat->DataFormat.SampleSize = (DataRangeAudio->MaximumBitsPerSample / 8) * DataRangeAudio->MaximumChannels;
1471 
1472  return STATUS_SUCCESS;
1473 }
NTSTATUS GetMaxPacketSizeForInterface(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, KSPIN_DATAFLOW DataFlow)
Definition: pin.c:16
DWORD *typedef PVOID
Definition: winlogon.h:52
KSDDKAPI VOID NTAPI KsStreamPointerDelete(IN PKSSTREAM_POINTER StreamPointer)
Definition: pin.c:1497
NTSTATUS RenderInitializeUrbAndIrp(IN PKSPIN Pin, IN PPIN_CONTEXT PinContext, IN OUT PIRP Irp, IN PVOID TransferBuffer, IN ULONG TransferBufferSize, IN ULONG PacketSize)
Definition: pin.c:312
PKSFILTER NTAPI KsPinGetParentFilter(IN PKSPIN Pin)
Definition: pin.c:1097
NTSTATUS NTAPI USBAudioPinProcess(_In_ PKSPIN Pin)
Definition: pin.c:1270
#define IN
Definition: typedefs.h:38
VOID NTAPI KsPinAcquireProcessingMutex(IN PKSPIN Pin)
Definition: pin.c:933
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS PinRenderProcess(IN PKSPIN Pin)
Definition: pin.c:987
#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
KS_FRAMING_RANGE PhysicalRange
Definition: ks.h:1401
VOID NTAPI KsPinAttemptProcessing(IN PKSPIN Pin, IN BOOLEAN Asynchronous)
Definition: pin.c:993
PKSWORKER CaptureWorker
Definition: usbaudio.h:207
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
#define PACKET_COUNT
Definition: pin.c:12
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:49
KSDDKAPI NTSTATUS NTAPI KsStreamPointerClone(IN PKSSTREAM_POINTER StreamPointer, IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL, IN ULONG ContextSize, OUT PKSSTREAM_POINTER *CloneStreamPointer)
Definition: pin.c:1545
_In_ PIRP Irp
Definition: csq.h:116
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PDEVICE_OBJECT LowerDevice
Definition: usbaudio.h:197
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PKSGATE NTAPI KsPinGetAndGate(IN PKSPIN Pin)
Definition: pin.c:980
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
return STATUS_SUCCESS
Definition: btrfs.c:2664
ULONG MaximumBitsPerSample
Definition: ksmedia.h:582
unsigned char * PUCHAR
Definition: retypes.h:3
#define URB_FUNCTION_CLASS_ENDPOINT
Definition: usb.h:114
KSDDKAPI NTSTATUS NTAPI _KsEdit(IN KSOBJECT_BAG ObjectBag, IN OUT PVOID *PointerToPointerToItem, IN ULONG NewSize, IN ULONG OldSize, IN ULONG Tag)
Definition: bag.c:358
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:104
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hidparse.c:18
KS_FRAMING_ITEM FramingItem[1]
Definition: ks.h:1711
KSDATAFORMAT DataFormat
Definition: ksmedia.h:531
KSDDKAPI NTSTATUS NTAPI KsStreamPointerAdvance(IN PKSSTREAM_POINTER StreamPointer)
Definition: pin.c:1688
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
NTSTATUS UsbAudioSetFormat(IN PKSPIN Pin)
Definition: pin.c:94
_In_ PLARGE_INTEGER _In_ ULONG _In_ BOOLEAN _In_ ULONG _Out_ PVOID _Out_ PIO_STATUS_BLOCK _In_ PDEVICE_OBJECT DeviceObject
Definition: npfs.h:636
NTSTATUS CapturePinStateChange(_In_ PKSPIN Pin, _In_ KSSTATE ToState, _In_ KSSTATE FromState)
Definition: pin.c:1359
IRP
Definition: iotypes.h:2457
ULONG BufferOffset
Definition: usbaudio.h:203
PUCHAR Buffer
Definition: usbaudio.h:201
_Must_inspect_result_ _In_ ULONG Index
Definition: fltkernel.h:1824
#define InsertTailList(ListHead, Entry)
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1777
#define BufferSize
Definition: acefiex.h:377
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
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
PDEVICE_EXTENSION DeviceExtension
Definition: usbaudio.h:196
#define USB_DEVICE_CLASS_AUDIO
Definition: usb100.h:91
#define _In_opt_
Definition: no_sal2.h:213
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
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
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
uint32_t ULONG_PTR
Definition: typedefs.h:63
KSDDKAPI ULONG NTAPI KsIncrementCountedWorker(IN PKSWORKER Worker)
Definition: worker.c:222
LIST_ENTRY IrpListHead
Definition: usbaudio.h:198
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS PinCaptureProcess(IN PKSPIN Pin)
Definition: pin.c:1121
_In_ PVOID FilterContext
Definition: fsrtltypes.h:299
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define GET_ISO_URB_SIZE(n)
Definition: usbdlib.h:112
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
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG MinFrameSize
Definition: ks.h:1381
NTSTATUS NTAPI USBAudioPinSetDeviceState(_In_ PKSPIN Pin, _In_ KSSTATE ToState, _In_ KSSTATE FromState)
Definition: pin.c:1392
#define FALSE
Definition: types.h:117
_In_ ULONG BufferLength
Definition: usbdlib.h:225
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1802
WORD wBitsPerSample
Definition: audioclient.idl:45
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
WORK_QUEUE_ITEM CaptureWorkItem
Definition: usbaudio.h:206
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
smooth NULL
Definition: ftsmooth.c:557
#define _Out_
Definition: no_sal2.h:323
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
struct _USB_ENDPOINT_DESCRIPTOR * PUSB_ENDPOINT_DESCRIPTOR
ULONG BufferSize
Definition: usbaudio.h:202
KSPIN_DATAFLOW
Definition: ks.h:1278
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define PtrToUlong(p)
Definition: basetsd.h:82
PIRP PinGetIrpFromReadyList(IN PKSPIN Pin)
Definition: pin.c:957
#define UlongToPtr(ul)
Definition: basetsd.h:97
KSDDKAPI ULONG NTAPI KsDecrementCountedWorker(IN PKSWORKER Worker)
Definition: worker.c:198
PUSB_INTERFACE_DESCRIPTOR NTAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PVOID StartPosition, LONG InterfaceNumber, LONG AlternateSetting, LONG InterfaceClass, LONG InterfaceSubClass, LONG InterfaceProtocol)
Definition: usbd.c:496
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
Definition: ks.h:672
if(!(yy_init))
Definition: macro.lex.yy.c:704
PDEVICE_OBJECT LowerDevice
Definition: usbaudio.h:190
struct _IO_STACK_LOCATION::@3397::@3411 DeviceIoControl
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbaudio.h:205
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
#define USBAUDIO_TAG
Definition: usbaudio.h:13
ULONG MinimumSampleFrequency
Definition: ksmedia.h:583
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
NTSTATUS NTAPI UsbAudioCaptureComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: pin.c:909
ULONG MaximumChannels
Definition: ksmedia.h:580
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2841
PUSB_COMMON_DESCRIPTOR NTAPI USBD_ParseDescriptors(PVOID DescriptorBuffer, ULONG TotalLength, PVOID StartPosition, LONG DescriptorType)
Definition: usbd.c:445
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
VOID NTAPI CaptureAvoidPipeStarvationWorker(_In_ PVOID Context)
Definition: pin.c:438
UINTN VOID * Buffer
Definition: acefiex.h:370
WAVEFORMATEX WaveFormatEx
Definition: ksmedia.h:532
struct KSDATARANGE_AUDIO * PKSDATARANGE_AUDIO
KSDDKAPI NTSTATUS NTAPI KsRegisterCountedWorker(IN WORK_QUEUE_TYPE WorkQueueType, IN PWORK_QUEUE_ITEM CountedWorkItem, OUT PKSWORKER *Worker)
Definition: worker.c:166
NTSTATUS NTAPI USBAudioPinClose(_In_ PKSPIN Pin, _In_ PIRP Irp)
Definition: pin.c:843
VOID CaptureInitializeUrbAndIrp(IN PKSPIN Pin, IN PIRP Irp)
Definition: pin.c:380
union _IO_STACK_LOCATION::@3397 Parameters
VOID UINTN Length
Definition: acefiex.h:744
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hidparse.c:38
#define USB_ENDPOINT_DESCRIPTOR_TYPE
Definition: usb100.h:53
Definition: typedefs.h:117
NTSTATUS UsbAudioAllocCaptureUrbIso(IN USBD_PIPE_HANDLE PipeHandle, IN ULONG MaxPacketSize, IN PVOID Buffer, IN ULONG BufferLength, OUT PURB *OutUrb)
Definition: pin.c:52
NTSTATUS SubmitUrbSync(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: usbaudio.c:37
ULONG BufferLength
Definition: usbaudio.h:204
#define KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:883
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
VOID NTAPI CaptureGateOnWorkItem(_In_ PVOID Context)
Definition: pin.c:275
UINT64 UINTN DataSize
Definition: acefiex.h:499
PKSPIN Pin
Definition: pin.c:23
NTSTATUS InitCapturePin(IN PKSPIN Pin)
Definition: pin.c:490
NTSTATUS NTAPI UsbAudioRenderComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: pin.c:853
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
#define _In_
Definition: no_sal2.h:204
KSDDKAPI PKSSTREAM_POINTER NTAPI KsPinGetLeadingEdgeStreamPointer(IN PKSPIN Pin, IN KSSTREAM_POINTER_STATE State)
Definition: pin.c:1385
struct KSDATAFORMAT_WAVEFORMATEX * PKSDATAFORMAT_WAVEFORMATEX
LONG NTSTATUS
Definition: DriverTester.h:11
NTSTATUS InitStreamPin(IN PKSPIN Pin)
Definition: pin.c:630
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:47
VOID NTAPI KsPinReleaseProcessingMutex(IN PKSPIN Pin)
Definition: pin.c:1196
KSSTATE
Definition: ks.h:1244
_In_ USHORT PacketSize
Definition: iofuncs.h:1056
ULONG MaximumSampleFrequency
Definition: ksmedia.h:584
#define URB_FUNCTION_ISOCH_TRANSFER
Definition: usb.h:96
#define IoSizeOfIrp(_StackSize)
struct KSALLOCATOR_FRAMING_EX * PKSALLOCATOR_FRAMING_EX
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
#define STATUS_NO_MATCH
Definition: ntstatus.h:737
_Must_inspect_result_ _In_ PURB
Definition: usbbusif.h:20
KSDDKAPI VOID NTAPI KsStreamPointerUnlock(IN PKSSTREAM_POINTER StreamPointer, IN BOOLEAN Eject)
Definition: pin.c:1463
unsigned int * PULONG
Definition: retypes.h:1
static HANDLE PipeHandle
Definition: dhcpcsvc.c:20
#define min(a, b)
Definition: monoChain.cc:55
ULONG GetDataRangeIndexForFormat(IN PKSDATARANGE ConnectionFormat, IN PKSDATARANGE *DataRanges, IN ULONG DataRangesCount)
Definition: pin.c:698
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1155
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _IO_STACK_LOCATION::@3397::@3433 Others
PKSWORKER StarvationWorker
Definition: usbaudio.h:209
KSDDKAPI PKSFILTER NTAPI KsGetFilterFromIrp(IN PIRP Irp)
Definition: filter.c:2106
PDEVICE_EXTENSION DeviceExtension
Definition: usbaudio.h:189
#define DPRINT1
Definition: precomp.h:8
WORK_QUEUE_ITEM StarvationWorkItem
Definition: usbaudio.h:208
struct USB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR * PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR
KSDDKAPI VOID NTAPI KsUnregisterWorker(IN PKSWORKER Worker)
Definition: worker.c:128
#define UsbBuildSelectInterfaceRequest(urb, length, configurationHandle, interfaceNumber, alternateSetting)
Definition: usbdlib.h:59
KSDDKAPI NTSTATUS NTAPI KsStreamPointerAdvanceOffsets(IN PKSSTREAM_POINTER StreamPointer, IN ULONG InUsed, IN ULONG OutUsed, IN BOOLEAN Eject)
Definition: pin.c:1628
KSDDKAPI NTSTATUS NTAPI KsStreamPointerSetStatusCode(IN PKSSTREAM_POINTER StreamPointer, IN NTSTATUS Status)
Definition: pin.c:1436
VOID NTAPI USBAudioPinReset(_In_ PKSPIN Pin)
Definition: pin.c:1290
#define OUT
Definition: typedefs.h:39
NTSTATUS StartCaptureIsocTransfer(IN PKSPIN Pin)
Definition: pin.c:1316
KSPIN_LOCK IrpListLock
Definition: usbaudio.h:200
PVOID PIRP
Definition: usb.h:38
struct tagContext Context
Definition: acpixf.h:1014
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:259
KSDDKAPI VOID NTAPI KsStreamPointerAdvanceOffsetsAndUnlock(IN PKSSTREAM_POINTER StreamPointer, IN ULONG InUsed, IN ULONG OutUsed, IN BOOLEAN Eject)
Definition: pin.c:1480
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
#define USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
Definition: usbaudio.h:14
LIST_ENTRY DoneIrpListHead
Definition: usbaudio.h:199
DataFlow
#define USBD_START_ISO_TRANSFER_ASAP
Definition: usb.h:155
KS_FRAMING_RANGE Range
Definition: ks.h:1387
KS_FRAMING_RANGE_WEIGHTED FramingRange
Definition: ks.h:1402
NTSTATUS USBAudioSelectAudioStreamingInterface(IN PKSPIN Pin, IN PPIN_CONTEXT PinContext, IN PDEVICE_EXTENSION DeviceExtension, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG FormatDescriptorIndex)
Definition: pin.c:168
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS NTAPI USBAudioPinCreate(_In_ PKSPIN Pin, _In_ PIRP Irp)
Definition: pin.c:764
ULONG MaxFrameSize
Definition: ks.h:1382
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
PVOID USBD_PIPE_HANDLE
Definition: usb.h:229
#define NT_ASSERT
Definition: rtlfuncs.h:3312