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
16 WdmAudOpenSysAudioDevice(
20 UNICODE_STRING SymbolicLink
;
21 OBJECT_ATTRIBUTES ObjectAttributes
;
22 IO_STATUS_BLOCK IoStatusBlock
;
25 RtlInitUnicodeString(&SymbolicLink
, DeviceName
);
26 InitializeObjectAttributes(&ObjectAttributes
, &SymbolicLink
, OBJ_OPENIF
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
28 Status
= IoCreateFile(Handle
,
29 SYNCHRONIZE
| GENERIC_READ
| GENERIC_WRITE
,
36 FILE_SYNCHRONOUS_IO_NONALERT
,
41 IO_NO_PARAMETER_CHECKING
| IO_FORCE_ACCESS_CHECK
);
48 DeviceInterfaceChangeCallback(
49 IN PVOID NotificationStructure
,
52 DEVICE_INTERFACE_CHANGE_NOTIFICATION
* Event
= (DEVICE_INTERFACE_CHANGE_NOTIFICATION
*)NotificationStructure
;
54 DPRINT1("DeviceInterfaceChangeCallback called %p\n", Event
);
56 return STATUS_SUCCESS
;
60 WdmAudOpenSysAudioDeviceInterfaces(
61 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
,
62 IN LPWSTR SymbolicLinkList
)
64 SYSAUDIO_ENTRY
* Entry
;
67 DPRINT1("WdmAudOpenSysAudioDeviceInterfaces called\n");
69 while(*SymbolicLinkList
)
71 Length
= wcslen(SymbolicLinkList
) + 1;
72 Entry
= (SYSAUDIO_ENTRY
*)AllocateItem(NonPagedPool
, sizeof(SYSAUDIO_ENTRY
) + Length
* sizeof(WCHAR
));
75 return STATUS_INSUFFICIENT_RESOURCES
;
78 Entry
->SymbolicLink
.Length
= Length
* sizeof(WCHAR
);
79 Entry
->SymbolicLink
.MaximumLength
= Length
* sizeof(WCHAR
);
80 Entry
->SymbolicLink
.Buffer
= (LPWSTR
) (Entry
+ 1);
81 wcscpy(Entry
->SymbolicLink
.Buffer
, SymbolicLinkList
);
83 InsertTailList(&DeviceExtension
->SysAudioDeviceList
, &Entry
->Entry
);
85 DeviceExtension
->NumSysAudioDevices
++;
86 SymbolicLinkList
+= Length
;
88 return STATUS_SUCCESS
;
93 WdmAudOpenSysAudioDevices(
94 IN PDEVICE_OBJECT DeviceObject
,
95 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
97 NTSTATUS Status
= STATUS_SUCCESS
;
98 LPWSTR SymbolicLinkList
;
99 SYSAUDIO_ENTRY
* Entry
;
102 PFILE_OBJECT FileObject
;
103 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\sysaudio\\GLOBAL");
105 if (DeviceExtension
->DeviceInterfaceSupport
)
107 Status
= IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO
,
112 if (NT_SUCCESS(Status
))
114 WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension
, SymbolicLinkList
);
115 FreeItem(SymbolicLinkList
);
119 Status
= IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange
,
120 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
,
121 (PVOID
)&KSCATEGORY_SYSAUDIO
,
122 DeviceObject
->DriverObject
,
123 DeviceInterfaceChangeCallback
,
124 (PVOID
)DeviceExtension
,
125 &DeviceExtension
->SysAudioNotification
);
129 Entry
= (SYSAUDIO_ENTRY
*)AllocateItem(NonPagedPool
, sizeof(SYSAUDIO_ENTRY
));
132 return STATUS_INSUFFICIENT_RESOURCES
;
136 Length
= wcslen(DeviceName
.Buffer
) + 1;
137 Entry
->SymbolicLink
.Length
= 0;
138 Entry
->SymbolicLink
.MaximumLength
= Length
* sizeof(WCHAR
);
139 Entry
->SymbolicLink
.Buffer
= AllocateItem(NonPagedPool
, Entry
->SymbolicLink
.MaximumLength
);
141 if (!Entry
->SymbolicLink
.Buffer
)
144 return STATUS_INSUFFICIENT_RESOURCES
;
147 Status
= RtlAppendUnicodeStringToString(&Entry
->SymbolicLink
, &DeviceName
);
149 if (!NT_SUCCESS(Status
))
151 FreeItem(Entry
->SymbolicLink
.Buffer
);
156 InsertTailList(&DeviceExtension
->SysAudioDeviceList
, &Entry
->Entry
);
157 DeviceExtension
->NumSysAudioDevices
++;
159 DPRINT("Opening device %S\n", Entry
->SymbolicLink
.Buffer
);
160 Status
= WdmAudOpenSysAudioDevice(Entry
->SymbolicLink
.Buffer
, &hSysAudio
);
161 if (!NT_SUCCESS(Status
))
163 DPRINT1("Failed to open sysaudio %x\n", Status
);
167 /* get the file object */
168 Status
= ObReferenceObjectByHandle(hSysAudio
, FILE_READ_DATA
| FILE_WRITE_DATA
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
169 if (!NT_SUCCESS(Status
))
171 DPRINT1("Failed to reference FileObject %x\n", Status
);
175 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
176 DeviceExtension
->hSysAudio
= hSysAudio
;
177 DeviceExtension
->FileObject
= FileObject
;
184 WdmAudRegisterDeviceInterface(
185 IN PDEVICE_OBJECT PhysicalDeviceObject
,
186 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
189 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\DosDevices\\wdmaud");
190 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\wdmaud");
191 UNICODE_STRING SymbolicLinkName
;
193 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
, &KSCATEGORY_WDMAUD
, NULL
, &SymbolicLinkName
);
194 if (NT_SUCCESS(Status
))
196 IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
197 RtlFreeUnicodeString(&SymbolicLinkName
);
198 DeviceExtension
->DeviceInterfaceSupport
= TRUE
;
202 /* failed to register device interface
203 * create a symbolic link instead
205 DeviceExtension
->DeviceInterfaceSupport
= FALSE
;
207 Status
= IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
208 if (!NT_SUCCESS(Status
))
210 IoDeleteDevice(PhysicalDeviceObject
); //FIXME
211 DPRINT("Failed to create wdmaud symlink!\n");
220 IN PDEVICE_OBJECT DeviceObject
,
221 IN PWDMAUD_CLIENT
*pClient
)
223 PWDMAUD_CLIENT Client
;
224 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
226 /* get device extension */
227 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
229 if (!DeviceExtension
->NumSysAudioDevices
)
231 /* wdmaud failed to open sysaudio */
232 return STATUS_UNSUCCESSFUL
;
236 ASSERT(!IsListEmpty(&DeviceExtension
->SysAudioDeviceList
));
238 /* allocate client context struct */
239 Client
= AllocateItem(NonPagedPool
, sizeof(WDMAUD_CLIENT
));
241 /* check for allocation failure */
244 /* not enough memory */
245 return STATUS_INSUFFICIENT_RESOURCES
;
248 /* zero client context struct */
249 RtlZeroMemory(Client
, sizeof(WDMAUD_CLIENT
));
251 /* initialize mixer event list */
252 InitializeListHead(&Client
->MixerEventList
);
257 /* insert client into list */
258 ExInterlockedInsertTailList(&DeviceExtension
->WdmAudClientList
, &Client
->Entry
, &DeviceExtension
->Lock
);
261 return STATUS_SUCCESS
;