2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/sysaudio/main.c
5 * PURPOSE: System Audio graph builder
6 * PROGRAMMER: Andrew Greenwood
9 * 8 Jul 07 Started basic implementation
15 const GUID KSCATEGORY_SYSAUDIO
= {0xA7C7A5B1L
, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
16 const GUID KSCATEGORY_AUDIO_DEVICE
= {0xFBF6F530L
, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
17 const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE
= {0xD6C5066EL
, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
18 const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE
= {0xD6C50671L
, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
19 const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE
= {0xD6C50674L
, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
25 SysAudio_Unload(IN PDRIVER_OBJECT DriverObject
)
27 DPRINT("SysAudio_Unload called\n");
33 IN PDEVICE_OBJECT DeviceObject
,
36 PKSAUDIO_DEVICE_ENTRY DeviceEntry
;
37 PSYSAUDIODEVEXT DeviceExtension
;
40 DPRINT("SysAudio_Shutdown called\n");
42 DeviceExtension
= (PSYSAUDIODEVEXT
)DeviceObject
->DeviceExtension
;
44 while(!IsListEmpty(&DeviceExtension
->KsAudioDeviceList
))
46 Entry
= RemoveHeadList(&DeviceExtension
->KsAudioDeviceList
);
47 DeviceEntry
= (PKSAUDIO_DEVICE_ENTRY
)CONTAINING_RECORD(Entry
, KSAUDIO_DEVICE_ENTRY
, Entry
);
49 DPRINT("Freeing item %wZ\n", &DeviceEntry
->DeviceName
);
51 /* dereference audio device file object */
52 ObDereferenceObject(DeviceEntry
->FileObject
);
54 /* close audio device handle */
55 ZwClose(DeviceEntry
->Handle
);
57 /* free device string */
58 RtlFreeUnicodeString(&DeviceEntry
->DeviceName
);
60 /* free audio device entry */
61 ExFreePool(DeviceEntry
);
64 Irp
->IoStatus
.Information
= 0;
65 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
66 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
67 return STATUS_SUCCESS
;
74 IN PDEVICE_OBJECT DeviceObject
,
77 PIO_STACK_LOCATION IrpStack
;
78 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\DosDevices\\sysaudio");
79 SYSAUDIODEVEXT
*DeviceExtension
;
81 /* Get current irp stack */
82 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
84 /* Fetch the device extension */
85 DeviceExtension
= (SYSAUDIODEVEXT
*)DeviceObject
->DeviceExtension
;
86 ASSERT(DeviceExtension
);
88 if (IrpStack
->MinorFunction
== IRP_MN_REMOVE_DEVICE
)
90 /* Unregister the echo cancel hook */
91 if (DeviceExtension
->EchoCancelNotificationEntry
)
92 IoUnregisterPlugPlayNotification(DeviceExtension
->EchoCancelNotificationEntry
);
94 /* Unregister the ks audio hook */
95 if (DeviceExtension
->KsAudioNotificationEntry
)
96 IoUnregisterPlugPlayNotification(DeviceExtension
->KsAudioNotificationEntry
);
98 /* Destroy our symbolic link */
99 IoDeleteSymbolicLink(&SymlinkName
);
101 else if (IrpStack
->MinorFunction
== IRP_MN_QUERY_PNP_DEVICE_STATE
)
103 /* Sysaudio can not be disabled */
104 Irp
->IoStatus
.Information
|= PNP_DEVICE_NOT_DISABLEABLE
;
107 /* Perform default pnp actions */
108 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
113 SysAudio_InstallDevice(
114 IN PDRIVER_OBJECT DriverObject
)
117 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\sysaudio");
118 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\DosDevices\\sysaudio");
119 PDEVICE_OBJECT DeviceObject
;
120 SYSAUDIODEVEXT
*DeviceExtension
;
123 DPRINT("SysAudio_InstallDevice called\n");
125 /* Create the device */
126 Status
= IoCreateDevice(DriverObject
,
127 sizeof(SYSAUDIODEVEXT
),
134 /* Check for success */
135 if (!NT_SUCCESS(Status
))
137 DPRINT("Failed to create \\Device\\sysaudio !\n");
141 /* Register device interfaces */
142 Status
= SysAudioRegisterDeviceInterfaces(DeviceObject
);
143 if (!NT_SUCCESS(Status
))
145 /* Failed to register
146 * Create a hack interface
148 Status
= IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
149 if (!NT_SUCCESS(Status
))
151 IoDeleteDevice(DeviceObject
);
152 DPRINT1("Failed to create sysaudio symlink!\n");
156 /* Acquire device extension */
157 DeviceExtension
= (SYSAUDIODEVEXT
*)DeviceObject
->DeviceExtension
;
158 /* Initialize device extension */
159 RtlZeroMemory(DeviceExtension
, sizeof(SYSAUDIODEVEXT
));
161 /* Initialize the mutex */
162 KeInitializeSpinLock(&DeviceExtension
->Lock
);
164 /* Initialize the ks audio device list */
165 InitializeListHead(&DeviceExtension
->KsAudioDeviceList
);
167 /* Allocate kernel streaming device header */
168 Status
= SysAudioAllocateDeviceHeader(DeviceExtension
);
169 if (!NT_SUCCESS(Status
))
171 DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status
);
175 /* Register device notification hooks */
176 Status
= SysAudioRegisterNotifications(DriverObject
,
178 if (!NT_SUCCESS(Status
))
180 DPRINT1("Failed to register device notifications\n");
185 Status
= SysAudioOpenKMixer(DeviceExtension
);
186 if (!NT_SUCCESS(Status
))
188 DPRINT1("SysAudioOpenKMixer failed with %x\n", Status
);
193 DeviceObject
->Flags
|= DO_DIRECT_IO
| DO_POWER_PAGABLE
;
194 /* clear initializing flag */
195 DeviceObject
->Flags
&= ~ DO_DEVICE_INITIALIZING
;
197 /* register shutdown notfication */
198 IoRegisterShutdownNotification(DeviceObject
);
202 return STATUS_SUCCESS
;
206 if (DeviceExtension
->KsAudioNotificationEntry
)
207 IoUnregisterPlugPlayNotification(DeviceExtension
->KsAudioNotificationEntry
);
209 if (DeviceExtension
->EchoCancelNotificationEntry
)
210 IoUnregisterPlugPlayNotification(DeviceExtension
->EchoCancelNotificationEntry
);
212 IoDeleteSymbolicLink(&SymlinkName
);
213 IoDeleteDevice(DeviceObject
);
220 IN PDRIVER_OBJECT DriverObject
,
221 IN PUNICODE_STRING RegistryPath
)
223 DPRINT("System audio graph builder (sysaudio) started\n");
225 /* Let ks handle these */
226 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CREATE
);
227 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CLOSE
);
228 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_WRITE
);
229 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_DEVICE_CONTROL
);
231 /* Let ks handle these */
232 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = KsDefaultDispatchPower
;
233 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = KsDefaultForwardIrp
;
235 /* Use provided ks unload function */
236 DriverObject
->DriverUnload
= KsNullDriverUnload
;
238 /* Sysaudio needs to do work on pnp, so handle it */
239 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = SysAudio_Pnp
;
240 DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = SysAudio_Shutdown
;
242 /* Call our initialization function */
243 return SysAudio_InstallDevice(DriverObject
);