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
11 const GUID KSCATEGORY_SYSAUDIO
= {0xA7C7A5B1L
, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
12 const GUID KSCATEGORY_WDMAUD
= {0x3E227E76L
, 0x690D, 0x11D2, {0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1}};
17 IN PDRIVER_OBJECT DriverObject
)
19 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\wdmaud");
20 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\DosDevices\\wdmaud");
21 PDEVICE_OBJECT DeviceObject
;
23 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
25 DPRINT1("WdmAudInstallDevice called\n");
27 Status
= IoCreateDevice(DriverObject
,
28 sizeof(WDMAUD_DEVICE_EXTENSION
),
35 if (!NT_SUCCESS(Status
))
37 DPRINT1("IoCreateDevice failed with %x\n", Status
);
41 /* clear device extension */
42 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
43 RtlZeroMemory(DeviceExtension
, sizeof(WDMAUD_DEVICE_EXTENSION
));
45 /* register device interfaces */
46 Status
= WdmAudRegisterDeviceInterface(DeviceObject
, DeviceExtension
);
47 if (!NT_SUCCESS(Status
))
49 DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status
);
50 IoDeleteDevice(DeviceObject
);
54 /* initialize sysaudio device list */
55 InitializeListHead(&DeviceExtension
->SysAudioDeviceList
);
57 /* initialize spinlock */
58 KeInitializeSpinLock(&DeviceExtension
->Lock
);
60 /* find available sysaudio devices */
61 Status
= WdmAudOpenSysAudioDevices(DeviceObject
, DeviceExtension
);
62 if (!NT_SUCCESS(Status
))
64 DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status
);
65 IoDeleteSymbolicLink(&SymlinkName
);
66 IoDeleteDevice(DeviceObject
);
69 /* allocate ks device header */
70 Status
= KsAllocateDeviceHeader(&DeviceExtension
->DeviceHeader
, 0, NULL
);
71 if (!NT_SUCCESS(Status
))
73 DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status
);
74 IoDeleteSymbolicLink(&SymlinkName
);
75 IoDeleteDevice(DeviceObject
);
79 Status
= WdmAudMixerInitialize(DeviceObject
);
80 DPRINT("WdmAudMixerInitialize Status %x\n", Status
);
81 Status
= WdmAudWaveInitialize(DeviceObject
);
82 DPRINT("WdmAudWaveInitialize Status %x\n", Status
);
84 DeviceObject
->Flags
|= DO_DIRECT_IO
| DO_POWER_PAGABLE
;
85 DeviceObject
->Flags
&= ~ DO_DEVICE_INITIALIZING
;
87 return STATUS_SUCCESS
;
93 IN PDRIVER_OBJECT driver
)
95 DPRINT1("WdmAudUnload called\n");
101 IN PDEVICE_OBJECT DeviceObject
,
104 PIO_STACK_LOCATION IrpStack
;
106 DPRINT("WdmAudPnp called\n");
108 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
110 if (IrpStack
->MinorFunction
== IRP_MN_QUERY_PNP_DEVICE_STATE
)
112 Irp
->IoStatus
.Information
|= PNP_DEVICE_NOT_DISABLEABLE
;
113 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
115 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
122 IN PDEVICE_OBJECT DeviceObject
,
127 PIO_STACK_LOCATION IoStack
;
128 PWDMAUD_CLIENT pClient
;
130 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
132 DPRINT("WdmAudCreate\n");
134 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
137 Status
= KsReferenceSoftwareBusObject((KSDEVICE_HEADER
)DeviceObject
->DeviceExtension
);
138 if (!NT_SUCCESS(Status
))
140 DPRINT1("KsReferenceSoftwareBusObject failed with %x\n", Status
);
145 Status
= WdmAudOpenSysaudio(DeviceObject
, &pClient
);
146 if (!NT_SUCCESS(Status
))
148 DPRINT1("Failed to open sysaudio!\n");
153 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
154 ASSERT(IoStack
->FileObject
);
156 /* store client context in file object */
157 IoStack
->FileObject
->FsContext
= pClient
;
158 Status
= STATUS_SUCCESS
;
160 Irp
->IoStatus
.Status
= Status
;
161 Irp
->IoStatus
.Information
= 0;
162 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
170 IN PDEVICE_OBJECT DeviceObject
,
173 DPRINT("WdmAudClose\n");
176 Status
= KsDereferenceSoftwareBusObject(DeviceExtension
->DeviceHeader
);
178 if (NT_SUCCESS(Status
))
180 if (DeviceExtension
->SysAudioNotification
)
181 Status
= IoUnregisterPlugPlayNotification(DeviceExtension
->SysAudioNotification
);
185 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
186 Irp
->IoStatus
.Information
= 0;
187 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
189 return STATUS_SUCCESS
;
195 IN PDEVICE_OBJECT DeviceObject
,
198 PIO_STACK_LOCATION IoStack
;
199 WDMAUD_CLIENT
*pClient
;
202 DPRINT("WdmAudCleanup\n");
204 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
206 pClient
= (WDMAUD_CLIENT
*)IoStack
->FileObject
->FsContext
;
210 for (Index
= 0; Index
< pClient
->NumPins
; Index
++)
212 DPRINT("Index %u Pin %p Type %x\n", Index
, pClient
->hPins
[Index
].Handle
, pClient
->hPins
[Index
].Type
);
213 if (pClient
->hPins
[Index
].Handle
&& pClient
->hPins
[Index
].Type
!= MIXER_DEVICE_TYPE
)
215 ZwClose(pClient
->hPins
[Index
].Handle
);
221 ExFreePool(pClient
->hPins
);
225 IoStack
->FileObject
->FsContext
= NULL
;
228 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
229 Irp
->IoStatus
.Information
= 0;
230 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
231 DPRINT("WdmAudCleanup complete\n");
232 return STATUS_SUCCESS
;
239 IN PDRIVER_OBJECT Driver
,
240 IN PUNICODE_STRING Registry_path
243 DPRINT1("Wdmaud.sys loaded\n");
245 Driver
->DriverUnload
= WdmAudUnload
;
247 Driver
->MajorFunction
[IRP_MJ_CREATE
] = WdmAudCreate
;
248 Driver
->MajorFunction
[IRP_MJ_CLOSE
] = WdmAudClose
;
249 Driver
->MajorFunction
[IRP_MJ_PNP
] = WdmAudPnp
;
250 Driver
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = KsDefaultForwardIrp
;
251 Driver
->MajorFunction
[IRP_MJ_CLEANUP
] = WdmAudCleanup
;
252 Driver
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = WdmAudDeviceControl
;
253 Driver
->MajorFunction
[IRP_MJ_WRITE
] = WdmAudReadWrite
;
254 Driver
->MajorFunction
[IRP_MJ_READ
] = WdmAudReadWrite
;
255 Driver
->MajorFunction
[IRP_MJ_POWER
] = KsDefaultDispatchPower
;
257 return WdmAudInstallDevice(Driver
);