ReactOS 0.4.15-dev-6056-gb29b268
main.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/sysaudio/main.c
5 * PURPOSE: System Audio graph builder
6 * PROGRAMMER: Andrew Greenwood
7 * Johannes Anderwald
8 * HISTORY:
9 * 8 Jul 07 Started basic implementation
10 */
11
12#include "sysaudio.h"
13
14#define NDEBUG
15#include <debug.h>
16
17const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
18const GUID KSCATEGORY_AUDIO_DEVICE = {0xFBF6F530L, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
19const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE = {0xD6C5066EL, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
20const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE = {0xD6C50671L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
21const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE = {0xD6C50674L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
22
27{
29 if (!Item)
30 return Item;
31
33 return Item;
34}
35
36VOID
39{
41}
42
43
44VOID
47{
48 DPRINT("SysAudio_Unload called\n");
49}
50
55 IN PIRP Irp)
56{
57 PKSAUDIO_DEVICE_ENTRY DeviceEntry;
58 PSYSAUDIODEVEXT DeviceExtension;
60
61 DPRINT("SysAudio_Shutdown called\n");
62
63 DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
64
65 while(!IsListEmpty(&DeviceExtension->KsAudioDeviceList))
66 {
67 Entry = RemoveHeadList(&DeviceExtension->KsAudioDeviceList);
69
70 DPRINT("Freeing item %wZ\n", &DeviceEntry->DeviceName);
71
72 /* dereference audio device file object */
73 ObDereferenceObject(DeviceEntry->FileObject);
74
75 /* close audio device handle */
76 ZwClose(DeviceEntry->Handle);
77
78 /* free device string */
79 RtlFreeUnicodeString(&DeviceEntry->DeviceName);
80
81 /* free audio device entry */
82 FreeItem(DeviceEntry);
83 }
84
85 Irp->IoStatus.Information = 0;
86 Irp->IoStatus.Status = STATUS_SUCCESS;
88 return STATUS_SUCCESS;
89}
90
91
96 IN PIRP Irp)
97{
98 PIO_STACK_LOCATION IrpStack;
99 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
100 SYSAUDIODEVEXT *DeviceExtension;
101
102 /* Get current irp stack */
104
105 /* Fetch the device extension */
106 DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
107 ASSERT(DeviceExtension);
108
109 if (IrpStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
110 {
111 /* Unregister the echo cancel hook */
112 if (DeviceExtension->EchoCancelNotificationEntry)
114
115 /* Unregister the ks audio hook */
116 if (DeviceExtension->KsAudioNotificationEntry)
118
119 /* Destroy our symbolic link */
120 IoDeleteSymbolicLink(&SymlinkName);
121 }
122 else if (IrpStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
123 {
124 /* Sysaudio can not be disabled */
125 Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
126 }
127
128 /* Perform default pnp actions */
130}
131
133NTAPI
137{
139 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio");
140 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
142 SYSAUDIODEVEXT *DeviceExtension;
143
144 DPRINT("SysAudio_AddDevice called\n");
145
146 /* Create the device */
148 sizeof(SYSAUDIODEVEXT),
149 &DeviceName,
151 0,
152 FALSE,
153 &DeviceObject);
154
155 /* Check for success */
156 if (!NT_SUCCESS(Status))
157 {
158 DPRINT("Failed to create \\Device\\sysaudio !\n");
159 return Status;
160 }
161
162 /* Register device interfaces */
164 if (!NT_SUCCESS(Status))
165 {
166 /* Failed to register
167 * Create a hack interface
168 */
169 Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
170 if (!NT_SUCCESS(Status))
171 {
173 DPRINT1("Failed to create sysaudio symlink!\n");
174 return Status;
175 }
176 }
177 /* Acquire device extension */
178 DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
179 /* Initialize device extension */
180 RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
181
182 /* Initialize the mutex */
183 KeInitializeSpinLock(&DeviceExtension->Lock);
184
185 /* Initialize the ks audio device list */
186 InitializeListHead(&DeviceExtension->KsAudioDeviceList);
187
188 /* Allocate kernel streaming device header */
189 Status = SysAudioAllocateDeviceHeader(DeviceExtension);
190 if (!NT_SUCCESS(Status))
191 {
192 DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
193 goto cleanup;
194 }
195
196 /* Register device notification hooks */
199 if (!NT_SUCCESS(Status))
200 {
201 DPRINT1("Failed to register device notifications\n");
202 goto cleanup;
203 }
204
205 /* Load kmixer */
206 Status = SysAudioOpenKMixer(DeviceExtension);
207 if (!NT_SUCCESS(Status))
208 {
209 DPRINT1("SysAudioOpenKMixer failed with %x\n", Status);
210 goto cleanup;
211 }
212
213 /* set io flags */
215 /* clear initializing flag */
216 DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
217
218 /* atttach to device stack */
221
222 /* register shutdown notification */
224
225
226 /* Done */
227 return STATUS_SUCCESS;
228
229cleanup:
230
231 if (DeviceExtension->KsAudioNotificationEntry)
233
234 if (DeviceExtension->EchoCancelNotificationEntry)
236
237 IoDeleteSymbolicLink(&SymlinkName);
239 return Status;
240}
241
243NTAPI
247{
248 DPRINT("System audio graph builder (sysaudio) started\n");
249
250 /* Let ks handle these */
255
256 /* Let ks handle these */
259
260 /* Use provided ks unload function */
261 DriverObject->DriverUnload = KsNullDriverUnload;
262
263 /* Sysaudio needs to do work on pnp, so handle it */
264 DriverObject->MajorFunction[IRP_MJ_PNP] = SysAudio_Pnp;
266 DriverObject->DriverExtension->AddDevice = SysAudio_AddDevice;
267
268 /* done */
269 return STATUS_SUCCESS;
270}
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 FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static void cleanup(void)
Definition: main.c:1335
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 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 KsSetMajorFunctionHandler(IN PDRIVER_OBJECT DriverObject, IN ULONG MajorFunction)
Definition: irp.c:2029
KSDDKAPI VOID NTAPI KsNullDriverUnload(IN PDRIVER_OBJECT DriverObject)
Definition: irp.c:1157
NTSTATUS SysAudioRegisterNotifications(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject)
Definition: deviface.c:172
NTSTATUS SysAudioRegisterDeviceInterfaces(IN PDEVICE_OBJECT DeviceObject)
Definition: deviface.c:214
NTSTATUS SysAudioAllocateDeviceHeader(IN SYSAUDIODEVEXT *DeviceExtension)
Definition: dispatcher.c:104
NTSTATUS SysAudioOpenKMixer(IN SYSAUDIODEVEXT *DeviceExtension)
Definition: dispatcher.c:132
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: main.c:24
const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE
Definition: main.c:19
const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE
Definition: main.c:20
VOID NTAPI SysAudio_Unload(IN PDRIVER_OBJECT DriverObject)
Definition: main.c:46
const GUID KSCATEGORY_SYSAUDIO
Definition: main.c:17
NTSTATUS NTAPI SysAudio_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: main.c:134
const GUID KSCATEGORY_AUDIO_DEVICE
Definition: main.c:18
NTSTATUS NTAPI SysAudio_Shutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: main.c:53
NTSTATUS NTAPI SysAudio_Pnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: main.c:94
const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE
Definition: main.c:21
VOID FreeItem(IN PVOID Item)
Definition: main.c:37
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT * NextDeviceObject
Definition: ndis.h:4642
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
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
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:479
#define FILE_DEVICE_KS
Definition: winioctl.h:153
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#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
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:83
Definition: sysaudio.h:13
PFILE_OBJECT FileObject
Definition: sysaudio.h:18
HANDLE Handle
Definition: sysaudio.h:17
UNICODE_STRING DeviceName
Definition: sysaudio.h:15
KSDEVICE_HEADER KsDeviceHeader
Definition: sysaudio.h:25
PVOID EchoCancelNotificationEntry
Definition: sysaudio.h:32
PVOID KsAudioNotificationEntry
Definition: sysaudio.h:31
LIST_ENTRY KsAudioDeviceList
Definition: sysaudio.h:30
KSPIN_LOCK Lock
Definition: sysaudio.h:33
Definition: typedefs.h:120
struct SYSAUDIODEVEXT * PSYSAUDIODEVEXT
struct KSAUDIO_DEVICE_ENTRY * PKSAUDIO_DEVICE_ENTRY
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
INT POOL_TYPE
Definition: typedefs.h:78
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_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
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#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 IRP_MN_REMOVE_DEVICE
#define DO_POWER_PAGABLE
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_POWER
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
#define ObDereferenceObject
Definition: obfuncs.h:203