2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/sysaudio/deviface.c
5 * PURPOSE: System Audio graph builder
6 * PROGRAMMER: Johannes Anderwald
11 const GUID GUID_DEVICE_INTERFACE_ARRIVAL
= {0xCB3A4004L
, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
12 const GUID GUID_DEVICE_INTERFACE_REMOVAL
= {0xCB3A4005L
, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
13 const GUID KS_CATEGORY_AUDIO
= {0x6994AD04L
, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
14 const GUID KS_CATEGORY_TOPOLOGY
= {0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00}};
15 const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL
= {0xBF963D80L
, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
19 IN PUNICODE_STRING DeviceName
,
21 IN PFILE_OBJECT
* FileObjectOut
)
25 PFILE_OBJECT FileObject
;
26 OBJECT_ATTRIBUTES ObjectAttributes
;
27 IO_STATUS_BLOCK IoStatusBlock
;
29 InitializeObjectAttributes(&ObjectAttributes
, DeviceName
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
31 Status
= ZwCreateFile(&NodeHandle
,
32 GENERIC_READ
| GENERIC_WRITE
,
39 FILE_SYNCHRONOUS_IO_NONALERT
,
44 if (!NT_SUCCESS(Status
))
46 DPRINT("ZwCreateFile failed with %x %S\n", Status
, DeviceName
->Buffer
);
50 Status
= ObReferenceObjectByHandle(NodeHandle
, GENERIC_READ
| GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
51 if (!NT_SUCCESS(Status
))
54 DPRINT("ObReferenceObjectByHandle failed with %x\n", Status
);
58 *HandleOut
= NodeHandle
;
59 *FileObjectOut
= FileObject
;
65 IN PDEVICE_OBJECT DeviceObject
,
66 IN PUNICODE_STRING DeviceName
)
68 NTSTATUS Status
= STATUS_SUCCESS
;
69 PSYSAUDIODEVEXT DeviceExtension
;
70 PKSAUDIO_DEVICE_ENTRY DeviceEntry
= NULL
;
72 /* a new device has arrived */
73 DeviceEntry
= AllocateItem(NonPagedPool
, sizeof(KSAUDIO_DEVICE_ENTRY
));
77 return STATUS_INSUFFICIENT_RESOURCES
;
80 /* initialize audio device entry */
81 RtlZeroMemory(DeviceEntry
, sizeof(KSAUDIO_DEVICE_ENTRY
));
84 DeviceEntry
->DeviceName
.Length
= 0;
85 DeviceEntry
->DeviceName
.MaximumLength
= DeviceName
->MaximumLength
+ 10 * sizeof(WCHAR
);
87 DeviceEntry
->DeviceName
.Buffer
= AllocateItem(NonPagedPool
, DeviceEntry
->DeviceName
.MaximumLength
);
89 if (!DeviceEntry
->DeviceName
.Buffer
)
91 Status
= STATUS_INSUFFICIENT_RESOURCES
;
95 RtlAppendUnicodeToString(&DeviceEntry
->DeviceName
, L
"\\??\\");
96 RtlAppendUnicodeStringToString(&DeviceEntry
->DeviceName
, DeviceName
);
98 Status
= OpenDevice(&DeviceEntry
->DeviceName
, &DeviceEntry
->Handle
, &DeviceEntry
->FileObject
);
100 if (!NT_SUCCESS(Status
))
105 /* fetch device extension */
106 DeviceExtension
= (PSYSAUDIODEVEXT
)DeviceObject
->DeviceExtension
;
107 /* insert new audio device */
108 ExInterlockedInsertTailList(&DeviceExtension
->KsAudioDeviceList
, &DeviceEntry
->Entry
, &DeviceExtension
->Lock
);
109 InterlockedIncrement((PLONG
)&DeviceExtension
->NumberOfKsAudioDevices
);
111 DPRINT("Successfully opened audio device %u Device %S\n", DeviceExtension
->NumberOfKsAudioDevices
, DeviceEntry
->DeviceName
.Buffer
);
117 if (DeviceEntry
->DeviceName
.Buffer
)
118 FreeItem(DeviceEntry
->DeviceName
.Buffer
);
120 FreeItem(DeviceEntry
);
130 DeviceInterfaceChangeCallback(
131 IN PVOID NotificationStructure
,
134 DEVICE_INTERFACE_CHANGE_NOTIFICATION
* Event
;
135 NTSTATUS Status
= STATUS_SUCCESS
;
136 PSYSAUDIODEVEXT DeviceExtension
;
137 PDEVICE_OBJECT DeviceObject
= (PDEVICE_OBJECT
)Context
;
139 DeviceExtension
= (PSYSAUDIODEVEXT
)DeviceObject
->DeviceExtension
;
141 Event
= (DEVICE_INTERFACE_CHANGE_NOTIFICATION
*)NotificationStructure
;
143 if (IsEqualGUIDAligned(&Event
->Event
,
144 &GUID_DEVICE_INTERFACE_ARRIVAL
))
146 Status
= InsertAudioDevice(DeviceObject
, Event
->SymbolicLinkName
);
151 DPRINT("Remove interface to audio device!\n");
153 return STATUS_SUCCESS
;
160 SysAudioRegisterNotifications(
161 IN PDRIVER_OBJECT DriverObject
,
162 IN PDEVICE_OBJECT DeviceObject
)
165 PSYSAUDIODEVEXT DeviceExtension
;
167 DeviceExtension
= (PSYSAUDIODEVEXT
)DeviceObject
->DeviceExtension
;
169 Status
= IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange
,
170 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
,
171 (PVOID
)&KS_CATEGORY_AUDIO
,
173 DeviceInterfaceChangeCallback
,
175 (PVOID
*)&DeviceExtension
->KsAudioNotificationEntry
);
177 if (!NT_SUCCESS(Status
))
179 DPRINT("IoRegisterPlugPlayNotification failed with %x\n", Status
);
182 Status
= IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange
,
183 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
,
184 (PVOID
)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL
,
186 DeviceInterfaceChangeCallback
,
188 (PVOID
*)&DeviceExtension
->EchoCancelNotificationEntry
);
190 if (!NT_SUCCESS(Status
))
192 /* ignore failure for now */
193 DPRINT("IoRegisterPlugPlayNotification failed for DMOCATEGORY_ACOUSTIC_ECHO_CANCEL\n", Status
);
196 return STATUS_SUCCESS
;
202 SysAudioRegisterDeviceInterfaces(
203 IN PDEVICE_OBJECT DeviceObject
)
206 UNICODE_STRING SymbolicLink
;
208 Status
= IoRegisterDeviceInterface(DeviceObject
, &KSCATEGORY_PREFERRED_MIDIOUT_DEVICE
, NULL
, &SymbolicLink
);
209 if (NT_SUCCESS(Status
))
211 IoSetDeviceInterfaceState(&SymbolicLink
, TRUE
);
212 RtlFreeUnicodeString(&SymbolicLink
);
216 DPRINT("Failed to register KSCATEGORY_PREFERRED_MIDIOUT_DEVICE interface Status %x\n", Status
);
220 Status
= IoRegisterDeviceInterface(DeviceObject
, &KSCATEGORY_PREFERRED_WAVEIN_DEVICE
, NULL
, &SymbolicLink
);
221 if (NT_SUCCESS(Status
))
223 IoSetDeviceInterfaceState(&SymbolicLink
, TRUE
);
224 RtlFreeUnicodeString(&SymbolicLink
);
228 DPRINT("Failed to register KSCATEGORY_PREFERRED_WAVEIN_DEVICE interface Status %x\n", Status
);
232 Status
= IoRegisterDeviceInterface(DeviceObject
, &KSCATEGORY_PREFERRED_WAVEOUT_DEVICE
, NULL
, &SymbolicLink
);
233 if (NT_SUCCESS(Status
))
235 IoSetDeviceInterfaceState(&SymbolicLink
, TRUE
);
236 RtlFreeUnicodeString(&SymbolicLink
);
240 DPRINT("Failed to register KSCATEGORY_PREFERRED_WAVEOUT_DEVICE interface Status %x\n", Status
);
243 Status
= IoRegisterDeviceInterface(DeviceObject
, &KSCATEGORY_SYSAUDIO
, NULL
, &SymbolicLink
);
244 if (NT_SUCCESS(Status
))
246 IoSetDeviceInterfaceState(&SymbolicLink
, TRUE
);
247 RtlFreeUnicodeString(&SymbolicLink
);
251 DPRINT("Failed to register KSCATEGORY_SYSAUDIO interface Status %x\n", Status
);