2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/legacy/wdmaud/deviface.c
5 * PURPOSE: System Audio graph builder
6 * PROGRAMMER: Andrew Greenwood
12 WdmAudOpenSysAudioDevice(
16 UNICODE_STRING SymbolicLink
;
17 OBJECT_ATTRIBUTES ObjectAttributes
;
18 IO_STATUS_BLOCK IoStatusBlock
;
21 RtlInitUnicodeString(&SymbolicLink
, DeviceName
);
22 InitializeObjectAttributes(&ObjectAttributes
, &SymbolicLink
, OBJ_OPENIF
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
24 Status
= IoCreateFile(Handle
,
25 SYNCHRONIZE
| GENERIC_READ
| GENERIC_WRITE
,
32 FILE_SYNCHRONOUS_IO_NONALERT
,
37 IO_NO_PARAMETER_CHECKING
| IO_FORCE_ACCESS_CHECK
);
44 DeviceInterfaceChangeCallback(
45 IN PVOID NotificationStructure
,
48 DEVICE_INTERFACE_CHANGE_NOTIFICATION
* Event
= (DEVICE_INTERFACE_CHANGE_NOTIFICATION
*)NotificationStructure
;
50 DPRINT1("DeviceInterfaceChangeCallback called %p\n", Event
);
52 return STATUS_SUCCESS
;
56 WdmAudOpenSysAudioDeviceInterfaces(
57 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
,
58 IN LPWSTR SymbolicLinkList
)
60 SYSAUDIO_ENTRY
* Entry
;
63 DPRINT1("WdmAudOpenSysAudioDeviceInterfaces called\n");
65 while(*SymbolicLinkList
)
67 Length
= wcslen(SymbolicLinkList
) + 1;
68 Entry
= (SYSAUDIO_ENTRY
*)AllocateItem(NonPagedPool
, sizeof(SYSAUDIO_ENTRY
) + Length
* sizeof(WCHAR
));
71 return STATUS_INSUFFICIENT_RESOURCES
;
74 Entry
->SymbolicLink
.Length
= Length
* sizeof(WCHAR
);
75 Entry
->SymbolicLink
.MaximumLength
= Length
* sizeof(WCHAR
);
76 Entry
->SymbolicLink
.Buffer
= (LPWSTR
) (Entry
+ 1);
77 wcscpy(Entry
->SymbolicLink
.Buffer
, SymbolicLinkList
);
79 InsertTailList(&DeviceExtension
->SysAudioDeviceList
, &Entry
->Entry
);
81 DeviceExtension
->NumSysAudioDevices
++;
82 SymbolicLinkList
+= Length
;
84 return STATUS_SUCCESS
;
89 WdmAudOpenSysAudioDevices(
90 IN PDEVICE_OBJECT DeviceObject
,
91 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
93 NTSTATUS Status
= STATUS_SUCCESS
;
94 LPWSTR SymbolicLinkList
;
95 SYSAUDIO_ENTRY
* Entry
;
98 PFILE_OBJECT FileObject
;
99 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\sysaudio\\GLOBAL");
101 if (DeviceExtension
->DeviceInterfaceSupport
)
103 Status
= IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO
,
108 if (NT_SUCCESS(Status
))
110 WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension
, SymbolicLinkList
);
111 FreeItem(SymbolicLinkList
);
115 Status
= IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange
,
116 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
,
117 (PVOID
)&KSCATEGORY_SYSAUDIO
,
118 DeviceObject
->DriverObject
,
119 DeviceInterfaceChangeCallback
,
120 (PVOID
)DeviceExtension
,
121 &DeviceExtension
->SysAudioNotification
);
125 Entry
= (SYSAUDIO_ENTRY
*)AllocateItem(NonPagedPool
, sizeof(SYSAUDIO_ENTRY
));
128 return STATUS_INSUFFICIENT_RESOURCES
;
132 Length
= wcslen(DeviceName
.Buffer
) + 1;
133 Entry
->SymbolicLink
.Length
= 0;
134 Entry
->SymbolicLink
.MaximumLength
= Length
* sizeof(WCHAR
);
135 Entry
->SymbolicLink
.Buffer
= AllocateItem(NonPagedPool
, Entry
->SymbolicLink
.MaximumLength
);
137 if (!Entry
->SymbolicLink
.Buffer
)
140 return STATUS_INSUFFICIENT_RESOURCES
;
143 Status
= RtlAppendUnicodeStringToString(&Entry
->SymbolicLink
, &DeviceName
);
145 if (!NT_SUCCESS(Status
))
147 FreeItem(Entry
->SymbolicLink
.Buffer
);
152 InsertTailList(&DeviceExtension
->SysAudioDeviceList
, &Entry
->Entry
);
153 DeviceExtension
->NumSysAudioDevices
++;
155 DPRINT("Opening device %S\n", Entry
->SymbolicLink
.Buffer
);
156 Status
= WdmAudOpenSysAudioDevice(Entry
->SymbolicLink
.Buffer
, &hSysAudio
);
157 if (!NT_SUCCESS(Status
))
159 DPRINT1("Failed to open sysaudio %x\n", Status
);
163 /* get the file object */
164 Status
= ObReferenceObjectByHandle(hSysAudio
, FILE_READ_DATA
| FILE_WRITE_DATA
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
165 if (!NT_SUCCESS(Status
))
167 DPRINT1("Failed to reference FileObject %x\n", Status
);
171 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
172 DeviceExtension
->hSysAudio
= hSysAudio
;
173 DeviceExtension
->FileObject
= FileObject
;
180 WdmAudRegisterDeviceInterface(
181 IN PDEVICE_OBJECT PhysicalDeviceObject
,
182 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
185 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\DosDevices\\wdmaud");
186 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\wdmaud");
187 UNICODE_STRING SymbolicLinkName
;
189 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
, &KSCATEGORY_WDMAUD
, NULL
, &SymbolicLinkName
);
190 if (NT_SUCCESS(Status
))
192 IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
193 RtlFreeUnicodeString(&SymbolicLinkName
);
194 DeviceExtension
->DeviceInterfaceSupport
= TRUE
;
198 /* failed to register device interface
199 * create a symbolic link instead
201 DeviceExtension
->DeviceInterfaceSupport
= FALSE
;
203 Status
= IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
204 if (!NT_SUCCESS(Status
))
206 IoDeleteDevice(PhysicalDeviceObject
); //FIXME
207 DPRINT("Failed to create wdmaud symlink!\n");
216 IN PDEVICE_OBJECT DeviceObject
,
217 IN PWDMAUD_CLIENT
*pClient
)
219 PWDMAUD_CLIENT Client
;
220 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
222 /* get device extension */
223 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
225 if (!DeviceExtension
->NumSysAudioDevices
)
227 /* wdmaud failed to open sysaudio */
228 return STATUS_UNSUCCESSFUL
;
232 ASSERT(!IsListEmpty(&DeviceExtension
->SysAudioDeviceList
));
234 /* allocate client context struct */
235 Client
= AllocateItem(NonPagedPool
, sizeof(WDMAUD_CLIENT
));
237 /* check for allocation failure */
240 /* not enough memory */
241 return STATUS_INSUFFICIENT_RESOURCES
;
244 /* zero client context struct */
245 RtlZeroMemory(Client
, sizeof(WDMAUD_CLIENT
));
247 /* initialize mixer event list */
248 InitializeListHead(&Client
->MixerEventList
);
253 /* insert client into list */
254 ExInterlockedInsertTailList(&DeviceExtension
->WdmAudClientList
, &Client
->Entry
, &DeviceExtension
->Lock
);
257 return STATUS_SUCCESS
;