ReactOS 0.4.15-dev-7842-g558ab78
usbaudio.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/usbaudio.c
5* PURPOSE: USB Audio device driver.
6* PROGRAMMERS:
7* Johannes Anderwald (johannes.anderwald@reactos.org)
8*/
9
10#include "usbaudio.h"
11
12static KSDEVICE_DISPATCH KsDeviceDispatch = {
15 NULL,
26};
27
28static KSDEVICE_DESCRIPTOR KsDeviceDescriptor = {
30 0,
31 NULL,
32 0x100, //KSDEVICE_DESCRIPTOR_VERSION,
33 0
34};
35
39 IN PURB Urb)
40{
41 PIRP Irp;
44 PIO_STACK_LOCATION IoStack;
46
47 // init event
49
50 // build irp
53 NULL,
54 0,
55 NULL,
56 0,
57 TRUE,
58 &Event,
59 &IoStatus);
60
61 if (!Irp)
62 {
63 //
64 // no memory
65 //
67 }
68
69 // get next stack location
71
72 // store urb
73 IoStack->Parameters.Others.Argument1 = Urb;
74
75 // call driver
77
78 // wait for the request to finish
80 {
82 Status = IoStatus.Status;
83 }
84
85 // done
86 return Status;
87}
88
92 IN PKSDEVICE Device,
93 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
94{
95 PDEVICE_EXTENSION DeviceExtension;
98 PURB Urb;
100 ULONG InterfaceDescriptorCount;
101
102 /* alloc item for configuration request */
103 InterfaceList = AllocFunction(sizeof(USBD_INTERFACE_LIST_ENTRY) * (ConfigurationDescriptor->bNumInterfaces + 1));
104 if (!InterfaceList)
105 {
106 /* insufficient resources*/
108 }
109
110 /* grab interface descriptor */
111 InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
113 {
114 /* no such interface */
116 }
117
118 /* lets enumerate the interfaces */
119 InterfaceDescriptorCount = 0;
120 while (InterfaceDescriptor != NULL)
121 {
122 if (InterfaceDescriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL*/
123 {
124 InterfaceList[InterfaceDescriptorCount++].InterfaceDescriptor = InterfaceDescriptor;
125 }
126 else if (InterfaceDescriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING*/
127 {
128 InterfaceList[InterfaceDescriptorCount++].InterfaceDescriptor = InterfaceDescriptor;
129 }
130
132 }
133
134 /* build urb */
135 Urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor, InterfaceList);
136 if (!Urb)
137 {
138 /* no memory */
141 }
142
143 /* device extension */
144 DeviceExtension = Device->Context;
145
146 /* submit configuration urb */
147 Status = SubmitUrbSync(DeviceExtension->LowerDevice, Urb);
148 if (!NT_SUCCESS(Status))
149 {
150 /* free resources */
151 ExFreePool(Urb);
153 return Status;
154 }
155
156 /* store configuration handle */
157 DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
158
159 /* alloc interface info */
160 DeviceExtension->InterfaceInfo = AllocFunction(Urb->UrbSelectConfiguration.Interface.Length);
161 if (DeviceExtension->InterfaceInfo)
162 {
163 /* copy interface info */
164 RtlCopyMemory(DeviceExtension->InterfaceInfo, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length);
165 }
166 return STATUS_SUCCESS;
167}
168
170NTAPI
172 IN PKSDEVICE Device)
173{
174 PURB Urb;
176 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
177 PDEVICE_EXTENSION DeviceExtension;
180
181 /* get device extension */
182 DeviceExtension = Device->Context;
183
184 /* allocate urb */
186 if (!Urb)
187 {
188 /* no memory */
190 }
191
192 /* alloc buffer for device descriptor */
194 if (!DeviceDescriptor)
195 {
196 /* insufficient resources */
197 FreeFunction(Urb);
199 }
200
201 /* build descriptor request */
203
204 /* submit urb */
205 Status = SubmitUrbSync(DeviceExtension->LowerDevice, Urb);
206 if (!NT_SUCCESS(Status))
207 {
208 /* free resources */
209 FreeFunction(Urb);
211 return Status;
212 }
213
214 /* now allocate some space for partial configuration descriptor */
215 ConfigurationDescriptor = AllocFunction(sizeof(USB_CONFIGURATION_DESCRIPTOR));
216 if (!ConfigurationDescriptor)
217 {
218 /* free resources */
219 FreeFunction(Urb);
221 return Status;
222 }
223
224 /* build descriptor request */
226
227 /* submit urb */
228 Status = SubmitUrbSync(DeviceExtension->LowerDevice, Urb);
229 if (!NT_SUCCESS(Status))
230 {
231 /* free resources */
232 FreeFunction(Urb);
234 FreeFunction(ConfigurationDescriptor);
235 return Status;
236 }
237
238 /* backup length */
239 Length = ConfigurationDescriptor->wTotalLength;
240
241 /* free old descriptor */
242 FreeFunction(ConfigurationDescriptor);
243
244 /* now allocate some space for full configuration descriptor */
245 ConfigurationDescriptor = AllocFunction(Length);
246 if (!ConfigurationDescriptor)
247 {
248 /* free resources */
249 FreeFunction(Urb);
251 return Status;
252 }
253
254 /* build descriptor request */
256
257 /* submit urb */
258 Status = SubmitUrbSync(DeviceExtension->LowerDevice, Urb);
259
260 /* free urb */
261 FreeFunction(Urb);
262 if (!NT_SUCCESS(Status))
263 {
264 /* free resources */
266 FreeFunction(ConfigurationDescriptor);
267 return Status;
268 }
269
270 /* lets add to object bag */
272 KsAddItemToObjectBag(Device->Bag, ConfigurationDescriptor, ExFreePool);
273
274 Status = USBAudioSelectConfiguration(Device, ConfigurationDescriptor);
275 if (NT_SUCCESS(Status))
276 {
277
278 DeviceExtension->ConfigurationDescriptor = ConfigurationDescriptor;
279 DeviceExtension->DeviceDescriptor = DeviceDescriptor;
280 }
281 return Status;
282}
283
284
286NTAPI
288 _In_ PKSDEVICE Device)
289{
290 /* no op */
291 DPRINT1("USBAudioAddDevice\n");
292 return STATUS_SUCCESS;
293}
294
296NTAPI
298 _In_ PKSDEVICE Device,
299 _In_ PIRP Irp,
300 _In_opt_ PCM_RESOURCE_LIST TranslatedResourceList,
301 _In_opt_ PCM_RESOURCE_LIST UntranslatedResourceList)
302{
304 PDEVICE_EXTENSION DeviceExtension;
305
306 if (!Device->Started)
307 {
308 /* alloc context */
309 DeviceExtension = AllocFunction(sizeof(DEVICE_EXTENSION));
310 if (DeviceExtension == NULL)
311 {
312 /* insufficient resources */
314 }
315
316 /* init context */
317 Device->Context = DeviceExtension;
318 DeviceExtension->LowerDevice = Device->NextDeviceObject;
319
320 /* add to object bag*/
322
323 /* init device*/
325 if (NT_SUCCESS(Status))
326 {
327 /* TODO retrieve interface */
329 }
330 }
331
332 return Status;
333}
334
336NTAPI
338 _In_ PKSDEVICE Device,
339 _In_ PIRP Irp)
340{
341 /* no op */
342 return STATUS_SUCCESS;
343}
344
345VOID
346NTAPI
348 _In_ PKSDEVICE Device,
349 _In_ PIRP Irp)
350{
351 /* no op */
352}
353
354VOID
355NTAPI
357 _In_ PKSDEVICE Device,
358 _In_ PIRP Irp)
359{
360 /* TODO: stop device */
362}
363
365NTAPI
367 _In_ PKSDEVICE Device,
368 _In_ PIRP Irp)
369{
370 /* no op */
371 return STATUS_SUCCESS;
372}
373
374
375VOID
376NTAPI
378 _In_ PKSDEVICE Device,
379 _In_ PIRP Irp)
380{
381 /* no op */
382}
383
384VOID
385NTAPI
387 _In_ PKSDEVICE Device,
388 _In_ PIRP Irp)
389{
390 /* TODO: stop device */
392}
393
395NTAPI
397 _In_ PKSDEVICE Device,
398 _In_ PIRP Irp,
400{
401 /* TODO: set caps */
403 return STATUS_SUCCESS;
404}
405
406VOID
407NTAPI
409 _In_ PKSDEVICE Device,
410 _In_ PIRP Irp)
411{
412 /* TODO: stop streams */
414}
415
417NTAPI
419 _In_ PKSDEVICE Device,
420 _In_ PIRP Irp,
421 _In_ DEVICE_POWER_STATE DeviceTo,
422 _In_ DEVICE_POWER_STATE DeviceFrom,
423 _In_ SYSTEM_POWER_STATE SystemTo,
424 _In_ SYSTEM_POWER_STATE SystemFrom,
426{
427 /* no op */
428 return STATUS_SUCCESS;
429}
430
431VOID
432NTAPI
434 _In_ PKSDEVICE Device,
435 _In_ PIRP Irp,
438{
439 /* TODO: stop streams */
441}
442
444NTAPI
448{
450
451 // initialize driver
453 if (!NT_SUCCESS(Status))
454 {
455 // failed to initialize driver
456 DPRINT1("Failed to initialize driver with %x\n", Status);
457 return Status;
458 }
459 return Status;
460}
NTSTATUS NTAPI KsAddItemToObjectBag(IN KSOBJECT_BAG ObjectBag, IN PVOID Item, IN PFNKSFREE Free OPTIONAL)
Definition: bag.c:86
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:115
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
KSDDKAPI NTSTATUS NTAPI KsInitializeDriver(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath, IN const KSDEVICE_DESCRIPTOR *Descriptor OPTIONAL)
Definition: driver.c:155
NTSTATUS NTAPI USBAudioCreateFilterContext(PKSDEVICE Device)
Definition: filter.c:1525
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Status
Definition: gdiplustypes.h:25
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
POWER_ACTION
Definition: ntpoapi.h:122
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
enum _SYSTEM_POWER_STATE SYSTEM_POWER_STATE
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_SUCCESS
Definition: shellext.h:65
const KSDEVICE_DESCRIPTOR DeviceDescriptor
Definition: splitter.c:257
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: usb.h:529
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:533
Definition: usbdlib.h:7
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbdlib.h:8
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
#define USB_DEVICE_CLASS_AUDIO
Definition: usb100.h:91
#define USBD_STATUS_INSUFFICIENT_RESOURCES
Definition: usb.h:204
NTSTATUS NTAPI USBAudioPnPStart(_In_ PKSDEVICE Device, _In_ PIRP Irp, _In_opt_ PCM_RESOURCE_LIST TranslatedResourceList, _In_opt_ PCM_RESOURCE_LIST UntranslatedResourceList)
Definition: usbaudio.c:297
static KSDEVICE_DESCRIPTOR KsDeviceDescriptor
Definition: usbaudio.c:28
NTSTATUS NTAPI USBAudioStartDevice(IN PKSDEVICE Device)
Definition: usbaudio.c:171
NTSTATUS NTAPI USBAudioSelectConfiguration(IN PKSDEVICE Device, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
Definition: usbaudio.c:91
NTSTATUS NTAPI USBAudioPnPQueryStop(_In_ PKSDEVICE Device, _In_ PIRP Irp)
Definition: usbaudio.c:337
NTSTATUS NTAPI USBAudioPnPQueryRemove(_In_ PKSDEVICE Device, _In_ PIRP Irp)
Definition: usbaudio.c:366
NTSTATUS NTAPI USBAudioPnPQueryPower(_In_ PKSDEVICE Device, _In_ PIRP Irp, _In_ DEVICE_POWER_STATE DeviceTo, _In_ DEVICE_POWER_STATE DeviceFrom, _In_ SYSTEM_POWER_STATE SystemTo, _In_ SYSTEM_POWER_STATE SystemFrom, _In_ POWER_ACTION Action)
Definition: usbaudio.c:418
VOID NTAPI USBAudioPnPStop(_In_ PKSDEVICE Device, _In_ PIRP Irp)
Definition: usbaudio.c:356
NTSTATUS SubmitUrbSync(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: usbaudio.c:37
VOID NTAPI USBAudioPnPCancelRemove(_In_ PKSDEVICE Device, _In_ PIRP Irp)
Definition: usbaudio.c:377
static KSDEVICE_DISPATCH KsDeviceDispatch
Definition: usbaudio.c:12
NTSTATUS NTAPI USBAudioAddDevice(_In_ PKSDEVICE Device)
Definition: usbaudio.c:287
VOID NTAPI USBAudioPnPSurpriseRemoval(_In_ PKSDEVICE Device, _In_ PIRP Irp)
Definition: usbaudio.c:408
NTSTATUS NTAPI USBAudioPnPQueryCapabilities(_In_ PKSDEVICE Device, _In_ PIRP Irp, _Inout_ PDEVICE_CAPABILITIES Capabilities)
Definition: usbaudio.c:396
VOID NTAPI USBAudioPnPCancelStop(_In_ PKSDEVICE Device, _In_ PIRP Irp)
Definition: usbaudio.c:347
VOID NTAPI USBAudioPnPSetPower(_In_ PKSDEVICE Device, _In_ PIRP Irp, _In_ DEVICE_POWER_STATE To, _In_ DEVICE_POWER_STATE From)
Definition: usbaudio.c:433
VOID NTAPI USBAudioPnPRemove(_In_ PKSDEVICE Device, _In_ PIRP Irp)
Definition: usbaudio.c:386
PURB NTAPI USBD_CreateConfigurationRequestEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSBD_INTERFACE_LIST_ENTRY InterfaceList)
Definition: usbd.c:329
PUSB_INTERFACE_DESCRIPTOR NTAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PVOID StartPosition, LONG InterfaceNumber, LONG AlternateSetting, LONG InterfaceClass, LONG InterfaceSubClass, LONG InterfaceProtocol)
Definition: usbd.c:496
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:181
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: wdfusb.h:2334
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
@ Executive
Definition: ketypes.h:415