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
14 const GUID GUID_DEVICE_INTERFACE_ARRIVAL
= {0xCB3A4004L
, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
15 const GUID GUID_DEVICE_INTERFACE_REMOVAL
= {0xCB3A4005L
, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
16 const GUID KS_CATEGORY_AUDIO
= {0x6994AD04L
, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
17 const GUID KS_CATEGORY_TOPOLOGY
= {0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00}};
18 const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL
= {0xBF963D80L
, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
22 IN PUNICODE_STRING DeviceName
,
24 IN PFILE_OBJECT
* FileObjectOut
)
28 PFILE_OBJECT FileObject
;
29 OBJECT_ATTRIBUTES ObjectAttributes
;
30 IO_STATUS_BLOCK IoStatusBlock
;
32 InitializeObjectAttributes(&ObjectAttributes
, DeviceName
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
34 Status
= ZwCreateFile(&NodeHandle
,
35 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
,
42 FILE_SYNCHRONOUS_IO_NONALERT
,
47 if (!NT_SUCCESS(Status
))
49 DPRINT("ZwCreateFile failed with %x %S\n", Status
, DeviceName
->Buffer
);
53 Status
= ObReferenceObjectByHandle(NodeHandle
, GENERIC_READ
| GENERIC_WRITE
, *IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
54 if (!NT_SUCCESS(Status
))
57 DPRINT("ObReferenceObjectByHandle failed with %x\n", Status
);
61 *HandleOut
= NodeHandle
;
62 *FileObjectOut
= FileObject
;
68 IN PDEVICE_OBJECT DeviceObject
,
69 IN PUNICODE_STRING DeviceName
)
71 NTSTATUS Status
= STATUS_SUCCESS
;
72 PSYSAUDIODEVEXT DeviceExtension
;
73 PKSAUDIO_DEVICE_ENTRY DeviceEntry
= NULL
;
75 /* a new device has arrived */
76 DeviceEntry
= AllocateItem(NonPagedPool
, sizeof(KSAUDIO_DEVICE_ENTRY
));
80 return STATUS_INSUFFICIENT_RESOURCES
;
83 /* initialize audio device entry */
84 RtlZeroMemory(DeviceEntry
, sizeof(KSAUDIO_DEVICE_ENTRY
));
87 DeviceEntry
->DeviceName
.Length
= 0;
88 DeviceEntry
->DeviceName
.MaximumLength
= DeviceName
->MaximumLength
+ 10 * sizeof(WCHAR
);
90 DeviceEntry
->DeviceName
.Buffer
= AllocateItem(NonPagedPool
, DeviceEntry
->DeviceName
.MaximumLength
);
92 if (!DeviceEntry
->DeviceName
.Buffer
)
94 Status
= STATUS_INSUFFICIENT_RESOURCES
;
99 Status
= OpenDevice(DeviceName
, &DeviceEntry
->Handle
, &DeviceEntry
->FileObject
);
100 if (NT_SUCCESS(Status
))
102 /* copy device name */
103 RtlAppendUnicodeStringToString(&DeviceEntry
->DeviceName
, DeviceName
);
107 /* the device name needs to be prefixed */
108 RtlAppendUnicodeToString(&DeviceEntry
->DeviceName
, L
"\\??\\");
109 RtlAppendUnicodeStringToString(&DeviceEntry
->DeviceName
, DeviceName
);
112 Status
= OpenDevice(&DeviceEntry
->DeviceName
, &DeviceEntry
->Handle
, &DeviceEntry
->FileObject
);
115 if (!NT_SUCCESS(Status
))
120 /* fetch device extension */
121 DeviceExtension
= (PSYSAUDIODEVEXT
)DeviceObject
->DeviceExtension
;
122 /* insert new audio device */
123 ExInterlockedInsertTailList(&DeviceExtension
->KsAudioDeviceList
, &DeviceEntry
->Entry
, &DeviceExtension
->Lock
);
124 InterlockedIncrement((PLONG
)&DeviceExtension
->NumberOfKsAudioDevices
);
126 DPRINT("Successfully opened audio device %u Device %S\n", DeviceExtension
->NumberOfKsAudioDevices
, DeviceEntry
->DeviceName
.Buffer
);
132 if (DeviceEntry
->DeviceName
.Buffer
)
133 FreeItem(DeviceEntry
->DeviceName
.Buffer
);
135 FreeItem(DeviceEntry
);
145 DeviceInterfaceChangeCallback(
146 IN PVOID NotificationStructure
,
149 DEVICE_INTERFACE_CHANGE_NOTIFICATION
* Event
;
150 NTSTATUS Status
= STATUS_SUCCESS
;
151 PDEVICE_OBJECT DeviceObject
= (PDEVICE_OBJECT
)Context
;
153 Event
= (DEVICE_INTERFACE_CHANGE_NOTIFICATION
*)NotificationStructure
;
155 if (IsEqualGUIDAligned(&Event
->Event
,
156 &GUID_DEVICE_INTERFACE_ARRIVAL
))
158 Status
= InsertAudioDevice(DeviceObject
, Event
->SymbolicLinkName
);
163 DPRINT("Remove interface to audio device!\n");
165 return STATUS_SUCCESS
;
172 SysAudioRegisterNotifications(
173 IN PDRIVER_OBJECT DriverObject
,
174 IN PDEVICE_OBJECT DeviceObject
)
177 PSYSAUDIODEVEXT DeviceExtension
;
179 DeviceExtension
= (PSYSAUDIODEVEXT
)DeviceObject
->DeviceExtension
;
181 Status
= IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange
,
182 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
,
183 (PVOID
)&KS_CATEGORY_AUDIO
,
185 DeviceInterfaceChangeCallback
,
187 (PVOID
*)&DeviceExtension
->KsAudioNotificationEntry
);
189 if (!NT_SUCCESS(Status
))
191 DPRINT("IoRegisterPlugPlayNotification failed with %x\n", Status
);
194 Status
= IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange
,
195 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
,
196 (PVOID
)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL
,
198 DeviceInterfaceChangeCallback
,
200 (PVOID
*)&DeviceExtension
->EchoCancelNotificationEntry
);
202 if (!NT_SUCCESS(Status
))
204 /* ignore failure for now */
205 DPRINT("IoRegisterPlugPlayNotification failed for DMOCATEGORY_ACOUSTIC_ECHO_CANCEL\n", Status
);
208 return STATUS_SUCCESS
;
214 SysAudioRegisterDeviceInterfaces(
215 IN PDEVICE_OBJECT DeviceObject
)
218 UNICODE_STRING SymbolicLink
;
220 Status
= IoRegisterDeviceInterface(DeviceObject
, &KSCATEGORY_PREFERRED_MIDIOUT_DEVICE
, NULL
, &SymbolicLink
);
221 if (NT_SUCCESS(Status
))
223 IoSetDeviceInterfaceState(&SymbolicLink
, TRUE
);
224 RtlFreeUnicodeString(&SymbolicLink
);
228 DPRINT("Failed to register KSCATEGORY_PREFERRED_MIDIOUT_DEVICE interface Status %x\n", Status
);
232 Status
= IoRegisterDeviceInterface(DeviceObject
, &KSCATEGORY_PREFERRED_WAVEIN_DEVICE
, NULL
, &SymbolicLink
);
233 if (NT_SUCCESS(Status
))
235 IoSetDeviceInterfaceState(&SymbolicLink
, TRUE
);
236 RtlFreeUnicodeString(&SymbolicLink
);
240 DPRINT("Failed to register KSCATEGORY_PREFERRED_WAVEIN_DEVICE interface Status %x\n", Status
);
244 Status
= IoRegisterDeviceInterface(DeviceObject
, &KSCATEGORY_PREFERRED_WAVEOUT_DEVICE
, NULL
, &SymbolicLink
);
245 if (NT_SUCCESS(Status
))
247 IoSetDeviceInterfaceState(&SymbolicLink
, TRUE
);
248 RtlFreeUnicodeString(&SymbolicLink
);
252 DPRINT("Failed to register KSCATEGORY_PREFERRED_WAVEOUT_DEVICE interface Status %x\n", Status
);
255 Status
= IoRegisterDeviceInterface(DeviceObject
, &KSCATEGORY_SYSAUDIO
, NULL
, &SymbolicLink
);
256 if (NT_SUCCESS(Status
))
258 IoSetDeviceInterfaceState(&SymbolicLink
, TRUE
);
259 RtlFreeUnicodeString(&SymbolicLink
);
263 DPRINT("Failed to register KSCATEGORY_SYSAUDIO interface Status %x\n", Status
);