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 Length
= wcslen(DeviceName
.Buffer
) + 1;
126 Entry
= (SYSAUDIO_ENTRY
*)AllocateItem(NonPagedPool
, sizeof(SYSAUDIO_ENTRY
) + Length
* sizeof(WCHAR
));
129 return STATUS_INSUFFICIENT_RESOURCES
;
132 Entry
->SymbolicLink
.Length
= Entry
->SymbolicLink
.MaximumLength
= Length
* sizeof(WCHAR
);
133 Entry
->SymbolicLink
.MaximumLength
+= sizeof(WCHAR
);
134 Entry
->SymbolicLink
.Buffer
= (LPWSTR
) (Entry
+ 1);
136 wcscpy(Entry
->SymbolicLink
.Buffer
, DeviceName
.Buffer
);
138 InsertTailList(&DeviceExtension
->SysAudioDeviceList
, &Entry
->Entry
);
139 DeviceExtension
->NumSysAudioDevices
++;
141 DPRINT("Opening device %S\n", Entry
->SymbolicLink
.Buffer
);
142 Status
= WdmAudOpenSysAudioDevice(Entry
->SymbolicLink
.Buffer
, &hSysAudio
);
143 if (!NT_SUCCESS(Status
))
145 DPRINT1("Failed to open sysaudio %x\n", Status
);
149 /* get the file object */
150 Status
= ObReferenceObjectByHandle(hSysAudio
, FILE_READ_DATA
| FILE_WRITE_DATA
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
151 if (!NT_SUCCESS(Status
))
153 DPRINT1("Failed to reference FileObject %x\n", Status
);
157 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
158 DeviceExtension
->hSysAudio
= hSysAudio
;
159 DeviceExtension
->FileObject
= FileObject
;
166 WdmAudRegisterDeviceInterface(
167 IN PDEVICE_OBJECT PhysicalDeviceObject
,
168 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
171 UNICODE_STRING SymlinkName
= RTL_CONSTANT_STRING(L
"\\DosDevices\\wdmaud");
172 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\wdmaud");
173 UNICODE_STRING SymbolicLinkName
;
175 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
, &KSCATEGORY_WDMAUD
, NULL
, &SymbolicLinkName
);
176 if (NT_SUCCESS(Status
))
178 IoSetDeviceInterfaceState(&SymbolicLinkName
, TRUE
);
179 RtlFreeUnicodeString(&SymbolicLinkName
);
180 DeviceExtension
->DeviceInterfaceSupport
= TRUE
;
184 /* failed to register device interface
185 * create a symbolic link instead
187 DeviceExtension
->DeviceInterfaceSupport
= FALSE
;
189 Status
= IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
190 if (!NT_SUCCESS(Status
))
192 IoDeleteDevice(PhysicalDeviceObject
); //FIXME
193 DPRINT("Failed to create wdmaud symlink!\n");
202 IN PDEVICE_OBJECT DeviceObject
,
203 IN PWDMAUD_CLIENT
*pClient
)
205 PWDMAUD_CLIENT Client
;
206 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
208 /* get device extension */
209 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
211 if (!DeviceExtension
->NumSysAudioDevices
)
213 /* wdmaud failed to open sysaudio */
214 return STATUS_UNSUCCESSFUL
;
218 ASSERT(!IsListEmpty(&DeviceExtension
->SysAudioDeviceList
));
220 /* allocate client context struct */
221 Client
= AllocateItem(NonPagedPool
, sizeof(WDMAUD_CLIENT
));
223 /* check for allocation failure */
226 /* not enough memory */
227 return STATUS_INSUFFICIENT_RESOURCES
;
230 /* zero client context struct */
231 RtlZeroMemory(Client
, sizeof(WDMAUD_CLIENT
));
233 /* initialize mixer event list */
234 InitializeListHead(&Client
->MixerEventList
);
239 /* insert client into list */
240 ExInterlockedInsertTailList(&DeviceExtension
->WdmAudClientList
, &Client
->Entry
, &DeviceExtension
->Lock
);
243 return STATUS_SUCCESS
;