- Implement enumerating available virtual audio devices and opening them

svn path=/trunk/; revision=39178
This commit is contained in:
Johannes Anderwald 2009-01-28 15:24:57 +00:00
parent 45041346e6
commit 3f066801c8
2 changed files with 124 additions and 0 deletions

View file

@ -40,6 +40,8 @@ WdmAudAddDevice(
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));
InitializeListHead(&DeviceExtension->SysAudioDeviceList);
Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
if (!NT_SUCCESS(Status))
{
@ -90,6 +92,37 @@ WdmAudPnp(
return KsDefaultDispatchPnp(DeviceObject, Irp);
}
NTSTATUS
WdmAudOpenSysAudioDevice(
IN LPWSTR DeviceName,
OUT PHANDLE Handle)
{
UNICODE_STRING SymbolicLink;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
RtlInitUnicodeString(&SymbolicLink, DeviceName);
InitializeObjectAttributes(&ObjectAttributes, &SymbolicLink, OBJ_OPENIF | OBJ_KERNEL_HANDLE, NULL, NULL);
Status = IoCreateFile(Handle,
SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,
&ObjectAttributes,
&IoStatusBlock,
NULL,
0,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0,
CreateFileTypeNone,
NULL,
IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
return Status;
}
NTSTATUS
NTAPI
DeviceInterfaceChangeCallback(
@ -102,6 +135,72 @@ DeviceInterfaceChangeCallback(
return STATUS_SUCCESS;
}
NTSTATUS
WdmAudOpenSysAudioDeviceInterfaces(
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
IN LPWSTR SymbolicLinkList)
{
NTSTATUS Status;
HANDLE Handle;
SYSAUDIO_ENTRY * Entry;
UINT Length;
PFILE_OBJECT FileObject;
ULONG Result;
ULONG BytesReturned;
KSPROPERTY KsPropset = {{STATIC_KSPROPSETID_Sysaudio}, KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT, KSPROPERTY_TYPE_SET};
while(*SymbolicLinkList)
{
Length = wcslen(SymbolicLinkList) + 1;
Status = WdmAudOpenSysAudioDevice(SymbolicLinkList, &Handle);
if (NT_SUCCESS(Status))
{
Status = ObReferenceObjectByHandle(Handle,
FILE_READ_DATA | FILE_WRITE_DATA,
IoFileObjectType,
KernelMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("ObReferenceObjectByHandle failed with %x\n", Status);
ZwClose(Handle);
}
Entry = (SYSAUDIO_ENTRY*)ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR));
if (!Entry)
{
ZwClose(Handle);
ObDereferenceObject((PVOID)FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
Entry->Handle = Handle;
Entry->SymbolicLink.Length = Length * sizeof(WCHAR);
Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1);
Entry->FileObject = FileObject;
wcscpy(Entry->SymbolicLink.Buffer, SymbolicLinkList);
InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
/* set device as default device */
KsSynchronousIoControlDevice(FileObject,
KernelMode,
IOCTL_KS_PROPERTY,
(PVOID)&KsPropset,
sizeof(KSPROPERTY),
(PVOID)&Result,
sizeof(ULONG),
&BytesReturned);
DeviceExtension->NumSysAudioDevices++;
}
SymbolicLinkList += Length;
}
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
@ -110,6 +209,7 @@ WdmAudCreate(
IN PIRP Irp)
{
NTSTATUS Status;
LPWSTR SymbolicLinkList;
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
DPRINT1("WdmAudCreate\n");
@ -126,6 +226,18 @@ WdmAudCreate(
}
#endif
Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO,
NULL,
0,
&SymbolicLinkList);
if (NT_SUCCESS(Status))
{
WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList);
ExFreePool(SymbolicLinkList);
}
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
(PVOID)&KSCATEGORY_SYSAUDIO,

View file

@ -7,11 +7,23 @@
#define YDEBUG
#include <debug.h>
typedef struct
{
LIST_ENTRY Entry;
HANDLE Handle;
UNICODE_STRING SymbolicLink;
PFILE_OBJECT FileObject;
}SYSAUDIO_ENTRY;
typedef struct
{
KSDEVICE_HEADER DeviceHeader;
PVOID SysAudioNotification;
ULONG NumSysAudioDevices;
LIST_ENTRY SysAudioDeviceList;
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;