ReactOS 0.4.16-dev-334-g4d9f67c
entry.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/legacy/wdmaud/main.c
5 * PURPOSE: System Audio graph builder
6 * PROGRAMMER: Andrew Greenwood
7 * Johannes Anderwald
8 */
9
10#include "wdmaud.h"
11
12#define NDEBUG
13#include <debug.h>
14
15const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
16const GUID KSCATEGORY_WDMAUD = {0x3E227E76L, 0x690D, 0x11D2, {0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1}};
17
18IO_WORKITEM_ROUTINE WdmAudInitWorkerRoutine;
19IO_TIMER_ROUTINE WdmAudTimerRoutine;
20
21VOID
26{
28 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
30
31 /* get device extension */
32 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
33
34
35 if (DeviceExtension->FileObject == NULL)
36 {
37 /* find available sysaudio devices */
39 if (!NT_SUCCESS(Status))
40 {
41 DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
42 return;
43 }
44 }
45
46
47 /* get device count */
49
50 DPRINT("WdmAudInitWorkerRoutine SysAudioDeviceCount %ld\n", DeviceCount);
51
52 /* was a device added / removed */
53 if (DeviceCount != DeviceExtension->SysAudioDeviceCount)
54 {
55 /* init mmixer library */
57 DPRINT("WdmAudMixerInitialize Status %x WaveIn %lu WaveOut %lu Mixer %lu\n", Status, WdmAudGetWaveInDeviceCount(), WdmAudGetWaveOutDeviceCount(), WdmAudGetMixerDeviceCount());
58
59 /* store sysaudio device count */
60 DeviceExtension->SysAudioDeviceCount = DeviceCount;
61 }
62
63 /* signal completion */
65
66 /* reset work item status indicator */
67 InterlockedDecrement((volatile long *)&DeviceExtension->WorkItemActive);
68}
69
70VOID
75{
76 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
77
78 /* get device extension */
79 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
80
81 if (InterlockedCompareExchange((volatile long *)&DeviceExtension->WorkItemActive, 1, 0) == 0)
82 {
83 /* queue work item */
84 IoQueueWorkItem(DeviceExtension->WorkItem, WdmAudInitWorkerRoutine, DelayedWorkQueue, (PVOID)DeviceExtension);
85 }
86}
87
93{
96 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
97
98 DPRINT("WdmaudAddDevice called\n");
99
102 NULL,
104 0,
105 FALSE,
106 &DeviceObject);
107
108 if (!NT_SUCCESS(Status))
109 {
110 DPRINT1("IoCreateDevice failed with %x\n", Status);
111 return Status;
112 }
113
114 /* get device extension */
115 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
116 RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));
117
118 /* allocate work item */
119 DeviceExtension->WorkItem = IoAllocateWorkItem(DeviceObject);
120 if (!DeviceExtension->WorkItem)
121 {
122 /* failed to allocate work item */
125 }
126
127 /* register device interfaces */
129 if (!NT_SUCCESS(Status))
130 {
131 DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
133 return Status;
134 }
135
136 /* initialize sysaudio device list */
137 InitializeListHead(&DeviceExtension->SysAudioDeviceList);
138
139 /* initialize client context device list */
140 InitializeListHead(&DeviceExtension->WdmAudClientList);
141
142 /* initialize spinlock */
143 KeInitializeSpinLock(&DeviceExtension->Lock);
144
145 /* initialization completion event */
147
148 /* initialize timer */
150
151 /* allocate ks device header */
152 Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
153 if (!NT_SUCCESS(Status))
154 {
155 DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
157 return Status;
158 }
159
160 /* attach to device stack */
162 KsSetDevicePnpAndBaseObject(DeviceExtension->DeviceHeader, DeviceExtension->NextDeviceObject, DeviceObject);
163
164
165 /* start the timer */
167
169 DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
170
171 return STATUS_SUCCESS;
172}
173
174VOID
175NTAPI
178{
179 DPRINT("WdmAudUnload called\n");
180}
181
183NTAPI
186 IN PIRP Irp)
187{
188 PIO_STACK_LOCATION IrpStack;
189
190 DPRINT("WdmAudPnp called\n");
191
193
195 {
196 Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
198 }
200}
201
202
204NTAPI
207 IN PIRP Irp)
208{
210 PIO_STACK_LOCATION IoStack;
211 PWDMAUD_CLIENT pClient;
212 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
213
214 /* get device extension */
215 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
216
217#if KS_IMPLEMENTED
219 if (!NT_SUCCESS(Status))
220 {
221 DPRINT1("KsReferenceSoftwareBusObject failed with %x\n", Status);
222 return Status;
223 }
224#endif
225
226 if (DeviceExtension->FileObject == NULL)
227 {
228 /* initialize */
230 }
231
232
234 if (!NT_SUCCESS(Status))
235 {
236 DPRINT1("Failed to open sysaudio!\n");
237
238 /* complete and forget */
239 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
241 /* done */
242 return STATUS_UNSUCCESSFUL;
243 }
244
246 ASSERT(IoStack->FileObject);
247
248 /* store client context in file object */
249 IoStack->FileObject->FsContext = pClient;
251
252 Irp->IoStatus.Status = Status;
253 Irp->IoStatus.Information = 0;
255
256 return Status;
257}
258
260NTAPI
263 IN PIRP Irp)
264{
265 /* nothing to do complete request */
266#if KS_IMPLEMENTED
267 Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
268
269 if (NT_SUCCESS(Status))
270 {
271 if (DeviceExtension->SysAudioNotification)
272 Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
273 }
274#endif
275
276 Irp->IoStatus.Status = STATUS_SUCCESS;
277 Irp->IoStatus.Information = 0;
279
280 /* done */
281 return STATUS_SUCCESS;
282}
283
285NTAPI
288 IN PIRP Irp)
289{
290 PIO_STACK_LOCATION IoStack;
291 PWDMAUD_CLIENT pClient;
292 PWDMAUD_DEVICE_EXTENSION DeviceExtension;
293 ULONG Index;
295
296 /* get device extension */
297 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
298
299 /* get current irp stack location */
301
302 /* sanity check */
303 ASSERT(IoStack->FileObject);
304
305 /* get client context struct */
306 pClient = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
307
308 /* sanity check */
309 ASSERT(pClient);
310
311 /* acquire client context list lock */
312 KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
313
314 /* remove entry */
315 RemoveEntryList(&pClient->Entry);
316
317 /* release lock */
318 KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
319
320 /* check if all audio pins have been closed */
321 for (Index = 0; Index < pClient->NumPins; Index++)
322 {
323 DPRINT("Index %u Pin %p Type %x\n", Index, pClient->hPins[Index].Handle, pClient->hPins[Index].Type);
324 if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE)
325 {
326 /* found an still open audio pin */
327 ZwClose(pClient->hPins[Index].Handle);
328 }
330 }
331
332 /* free pin array */
333 if (pClient->hPins)
334 FreeItem(pClient->hPins);
335
336 /* free client context struct */
337 FreeItem(pClient);
338
339 /* clear old client pointer */
340 IoStack->FileObject->FsContext = NULL;
341
342 /* complete request */
343 Irp->IoStatus.Status = STATUS_SUCCESS;
344 Irp->IoStatus.Information = 0;
346
347 /* done */
348 return STATUS_SUCCESS;
349}
350
352NTAPI
355 IN PUNICODE_STRING Registry_path
356)
357{
358 DPRINT("Wdmaud.sys loaded\n");
359
360 Driver->DriverUnload = WdmAudUnload;
361
362 Driver->MajorFunction[IRP_MJ_CREATE] = WdmAudCreate;
363 Driver->MajorFunction[IRP_MJ_CLOSE] = WdmAudClose;
364 Driver->MajorFunction[IRP_MJ_PNP] = WdmAudPnp;
366 Driver->MajorFunction[IRP_MJ_CLEANUP] = WdmAudCleanup;
368 Driver->MajorFunction[IRP_MJ_WRITE] = WdmAudReadWrite;
369 Driver->MajorFunction[IRP_MJ_READ] = WdmAudReadWrite;
371 Driver->DriverExtension->AddDevice = WdmaudAddDevice;
372
373 return STATUS_SUCCESS;
374}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
KSDDKAPI NTSTATUS NTAPI KsDefaultDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: api.c:110
KSDDKAPI VOID NTAPI KsSetDevicePnpAndBaseObject(IN KSDEVICE_HEADER Header, IN PDEVICE_OBJECT PnpDeviceObject, IN PDEVICE_OBJECT BaseDevice)
Definition: api.c:257
KSDDKAPI NTSTATUS NTAPI KsAllocateDeviceHeader(OUT KSDEVICE_HEADER *OutHeader, IN ULONG ItemsCount, IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL)
Definition: api.c:522
KSDDKAPI NTSTATUS NTAPI KsDefaultForwardIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: api.c:227
KSDDKAPI NTSTATUS NTAPI KsDefaultDispatchPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: api.c:166
KSDDKAPI NTSTATUS NTAPI KsReferenceSoftwareBusObject(IN KSDEVICE_HEADER Header)
Definition: device.c:780
KSDDKAPI VOID NTAPI KsDereferenceSoftwareBusObject(IN KSDEVICE_HEADER Header)
Definition: device.c:851
NTSTATUS NTAPI WdmAudDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: control.c:302
NTSTATUS NTAPI WdmAudReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: control.c:437
NTSTATUS WdmAudRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
Definition: deviface.c:186
NTSTATUS WdmAudOpenSysaudio(IN PDEVICE_OBJECT DeviceObject, IN PWDMAUD_CLIENT *pClient)
Definition: deviface.c:206
NTSTATUS WdmAudOpenSysAudioDevices(IN PDEVICE_OBJECT DeviceObject, IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
Definition: deviface.c:93
IO_WORKITEM_ROUTINE WdmAudInitWorkerRoutine
Definition: entry.c:18
NTSTATUS NTAPI WdmAudPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: entry.c:184
NTSTATUS NTAPI WdmAudCleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: entry.c:286
IO_TIMER_ROUTINE WdmAudTimerRoutine
Definition: entry.c:19
VOID NTAPI WdmAudUnload(IN PDRIVER_OBJECT driver)
Definition: entry.c:176
NTSTATUS NTAPI WdmAudCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: entry.c:205
const GUID KSCATEGORY_WDMAUD
Definition: entry.c:16
const GUID KSCATEGORY_SYSAUDIO
Definition: entry.c:15
NTSTATUS NTAPI WdmAudClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: entry.c:261
NTSTATUS NTAPI WdmaudAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: entry.c:90
NTSTATUS WdmAudMixerInitialize(IN PDEVICE_OBJECT DeviceObject)
Definition: mmixer.c:380
ULONG WdmAudGetWaveInDeviceCount()
Definition: mmixer.c:669
VOID WdmAudCloseAllMixers(IN PDEVICE_OBJECT DeviceObject, IN PWDMAUD_CLIENT ClientInfo, IN ULONG Index)
Definition: mmixer.c:501
ULONG WdmAudGetWaveOutDeviceCount()
Definition: mmixer.c:675
ULONG WdmAudGetMixerDeviceCount()
Definition: mmixer.c:663
ULONG GetSysAudioDeviceCount(IN PDEVICE_OBJECT DeviceObject)
Definition: sup.c:35
struct WDMAUD_CLIENT * PWDMAUD_CLIENT
struct WDMAUD_DEVICE_EXTENSION * PWDMAUD_DEVICE_EXTENSION
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:25
#define InterlockedCompareExchange
Definition: interlocked.h:104
NTSTATUS NTAPI IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context)
Definition: iotimer.c:92
VOID NTAPI IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:133
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
ULONG DeviceCount
Definition: mpu401.c:26
struct @1679::@1680 driver
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ NotificationEvent
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:480
#define FILE_DEVICE_KS
Definition: winioctl.h:92
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
@ MIXER_DEVICE_TYPE
Definition: sndtypes.h:33
#define DPRINT
Definition: sndvol32.h:73
WDMAUD_HANDLE * hPins
Definition: wdmaud.h:32
ULONG NumPins
Definition: wdmaud.h:31
LIST_ENTRY Entry
Definition: wdmaud.h:29
LIST_ENTRY SysAudioDeviceList
Definition: wdmaud.h:60
PFILE_OBJECT FileObject
Definition: wdmaud.h:62
LIST_ENTRY WdmAudClientList
Definition: wdmaud.h:63
KSPIN_LOCK Lock
Definition: wdmaud.h:58
KEVENT InitializationCompletionEvent
Definition: wdmaud.h:67
PIO_WORKITEM WorkItem
Definition: wdmaud.h:66
KSDEVICE_HEADER DeviceHeader
Definition: wdmaud.h:53
ULONG SysAudioDeviceCount
Definition: wdmaud.h:65
PDEVICE_OBJECT NextDeviceObject
Definition: wdmaud.h:70
SOUND_DEVICE_TYPE Type
Definition: wdmaud.h:21
HANDLE Handle
Definition: wdmaud.h:20
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
@ DelayedWorkQueue
Definition: extypes.h:190
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:1006
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define DO_POWER_PAGABLE
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MJ_POWER
#define IRP_MJ_CLEANUP
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778