mirror of
https://github.com/reactos/reactos.git
synced 2025-05-23 11:04:52 +00:00
- Implement enumerating sysaudio devices using device interface or using static symbolic link(hack)
- Implement a few options of sysaudio property set - Implement an object dispatcher like in portcls which will be used to forward requests svn path=/trunk/; revision=39694
This commit is contained in:
parent
31877406c6
commit
82bba6cd0c
12 changed files with 1236 additions and 430 deletions
57
reactos/drivers/wdm/audio/legacy/wdmaud/control.c
Normal file
57
reactos/drivers/wdm/audio/legacy/wdmaud/control.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/wdmaud/deviface.c
|
||||||
|
* PURPOSE: System Audio graph builder
|
||||||
|
* PROGRAMMER: Andrew Greenwood
|
||||||
|
* Johannes Anderwald
|
||||||
|
*/
|
||||||
|
#include "wdmaud.h"
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
WdmAudDeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("WdmAudDeviceControl entered\n");
|
||||||
|
|
||||||
|
switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
|
||||||
|
{
|
||||||
|
case IOCTL_OPEN_WDMAUD:
|
||||||
|
//return WdmAudDeviceControlOpen(DeviceObject, Irp);
|
||||||
|
case IOCTL_CLOSE_WDMAUD:
|
||||||
|
case IOCTL_GETNUMDEVS_TYPE:
|
||||||
|
case IOCTL_SETDEVICE_STATE:
|
||||||
|
case IOCTL_GETDEVID:
|
||||||
|
case IOCTL_GETVOLUME:
|
||||||
|
case IOCTL_SETVOLUME:
|
||||||
|
case IOCTL_GETCAPABILITIES:
|
||||||
|
case IOCTL_WRITEDATA:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UNIMPLEMENTED
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
237
reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c
Normal file
237
reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/wdmaud/deviface.c
|
||||||
|
* PURPOSE: System Audio graph builder
|
||||||
|
* PROGRAMMER: Andrew Greenwood
|
||||||
|
* Johannes Anderwald
|
||||||
|
*/
|
||||||
|
#include "wdmaud.h"
|
||||||
|
|
||||||
|
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(
|
||||||
|
IN PVOID NotificationStructure,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
|
||||||
|
|
||||||
|
DPRINT1("DeviceInterfaceChangeCallback called %p\n", Event);
|
||||||
|
DbgBreakPoint();
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudOpenSysAudioDeviceInterfaces(
|
||||||
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
IN LPWSTR SymbolicLinkList)
|
||||||
|
{
|
||||||
|
SYSAUDIO_ENTRY * Entry;
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
|
DPRINT1("WdmAudOpenSysAudioDeviceInterfaces called\n");
|
||||||
|
|
||||||
|
while(*SymbolicLinkList)
|
||||||
|
{
|
||||||
|
Length = wcslen(SymbolicLinkList) + 1;
|
||||||
|
Entry = (SYSAUDIO_ENTRY*)ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR));
|
||||||
|
if (!Entry)
|
||||||
|
{
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry->SymbolicLink.Length = Length * sizeof(WCHAR);
|
||||||
|
Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
|
||||||
|
Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1);
|
||||||
|
wcscpy(Entry->SymbolicLink.Buffer, SymbolicLinkList);
|
||||||
|
|
||||||
|
InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
|
||||||
|
|
||||||
|
DeviceExtension->NumSysAudioDevices++;
|
||||||
|
SymbolicLinkList += Length;
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudOpenSysAudioDevices(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
LPWSTR SymbolicLinkList;
|
||||||
|
SYSAUDIO_ENTRY * Entry;
|
||||||
|
ULONG Length;
|
||||||
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio");
|
||||||
|
|
||||||
|
if (DeviceExtension->DeviceInterfaceSupport)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
DeviceObject->DriverObject,
|
||||||
|
DeviceInterfaceChangeCallback,
|
||||||
|
(PVOID)DeviceExtension,
|
||||||
|
&DeviceExtension->SysAudioNotification);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Length = wcslen(DeviceName.Buffer) + 1;
|
||||||
|
Entry = (SYSAUDIO_ENTRY*)ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR));
|
||||||
|
if (!Entry)
|
||||||
|
{
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry->SymbolicLink.Length = Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
|
||||||
|
Entry->SymbolicLink.MaximumLength += sizeof(WCHAR);
|
||||||
|
Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1);
|
||||||
|
|
||||||
|
wcscpy(Entry->SymbolicLink.Buffer, DeviceName.Buffer);
|
||||||
|
|
||||||
|
InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
|
||||||
|
DeviceExtension->NumSysAudioDevices++;
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudRegisterDeviceInterface(
|
||||||
|
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||||
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
|
||||||
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
|
||||||
|
UNICODE_STRING SymbolicLinkName;
|
||||||
|
|
||||||
|
Status = IoRegisterDeviceInterface(PhysicalDeviceObject, &KSCATEGORY_WDMAUD, NULL, &SymbolicLinkName);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
|
||||||
|
RtlFreeUnicodeString(&SymbolicLinkName);
|
||||||
|
DeviceExtension->DeviceInterfaceSupport = TRUE;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* failed to register device interface
|
||||||
|
* create a symbolic link instead
|
||||||
|
*/
|
||||||
|
DeviceExtension->DeviceInterfaceSupport = FALSE;
|
||||||
|
|
||||||
|
Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IoDeleteDevice(PhysicalDeviceObject); //FIXME
|
||||||
|
DPRINT("Failed to create wdmaud symlink!\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudOpenSysaudio(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PWDMAUD_CLIENT *pClient)
|
||||||
|
{
|
||||||
|
PWDMAUD_CLIENT Client;
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE hSysAudio;
|
||||||
|
PSYSAUDIO_ENTRY SysEntry;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
if (!DeviceExtension->NumSysAudioDevices)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
ASSERT(!IsListEmpty(&DeviceExtension->SysAudioDeviceList));
|
||||||
|
|
||||||
|
Client = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_CLIENT));
|
||||||
|
if (!Client)
|
||||||
|
{
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT));
|
||||||
|
|
||||||
|
|
||||||
|
/* open the first sysaudio device available */
|
||||||
|
SysEntry = (PSYSAUDIO_ENTRY)DeviceExtension->SysAudioDeviceList.Flink;
|
||||||
|
|
||||||
|
DPRINT1("Opening device %S\n", SysEntry->SymbolicLink.Buffer);
|
||||||
|
Status = WdmAudOpenSysAudioDevice(SysEntry->SymbolicLink.Buffer, &hSysAudio);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to open sysaudio %x\n", Status);
|
||||||
|
ExFreePool(Client);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the file object */
|
||||||
|
Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to reference FileObject %x\n", Status);
|
||||||
|
ExFreePool(Client);
|
||||||
|
ZwClose(hSysAudio);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client->hSysAudio = hSysAudio;
|
||||||
|
Client->FileObject = FileObject;
|
||||||
|
Client->hProcess = PsGetCurrentProcessId();
|
||||||
|
|
||||||
|
*pClient = Client;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,23 +9,24 @@
|
||||||
#include "wdmaud.h"
|
#include "wdmaud.h"
|
||||||
|
|
||||||
const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
|
const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
|
||||||
|
const GUID KSCATEGORY_WDMAUD = {0x3E227E76L, 0x690D, 0x11D2, {0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1}};
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
WdmAudAddDevice(
|
WdmAudInstallDevice(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject)
|
||||||
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
|
||||||
{
|
{
|
||||||
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
|
||||||
|
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PDEVICE_OBJECT NextDeviceObject;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DPRINT("WdmAudAddDevice called\n");
|
DPRINT1("WdmAudInstallDevice called\n");
|
||||||
|
|
||||||
Status = IoCreateDevice(DriverObject,
|
Status = IoCreateDevice(DriverObject,
|
||||||
sizeof(WDMAUD_DEVICE_EXTENSION),
|
sizeof(WDMAUD_DEVICE_EXTENSION),
|
||||||
NULL,
|
&DeviceName,
|
||||||
FILE_DEVICE_KS,
|
FILE_DEVICE_KS,
|
||||||
0,
|
0,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
@ -37,26 +38,43 @@ WdmAudAddDevice(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clear device extension */
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));
|
RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));
|
||||||
|
|
||||||
InitializeListHead(&DeviceExtension->SysAudioDeviceList);
|
/* register device interfaces */
|
||||||
|
Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
|
||||||
Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
|
DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
|
||||||
IoDeleteDevice(DeviceObject);
|
IoDeleteDevice(DeviceObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
|
/* initialize sysaudio device list */
|
||||||
if (NextDeviceObject)
|
InitializeListHead(&DeviceExtension->SysAudioDeviceList);
|
||||||
{
|
|
||||||
/// FIXME
|
|
||||||
/// KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension, NextDeviceObject, DeviceObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* initialize spinlock */
|
||||||
|
KeInitializeSpinLock(&DeviceExtension->Lock);
|
||||||
|
|
||||||
|
/* find available sysaudio devices */
|
||||||
|
Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
|
||||||
|
IoDeleteSymbolicLink(&SymlinkName);
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/* allocate ks device header */
|
||||||
|
Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
|
||||||
|
IoDeleteSymbolicLink(&SymlinkName);
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
|
DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
|
||||||
DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
|
DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
|
||||||
|
@ -69,7 +87,7 @@ NTAPI
|
||||||
WdmAudUnload(
|
WdmAudUnload(
|
||||||
IN PDRIVER_OBJECT driver)
|
IN PDRIVER_OBJECT driver)
|
||||||
{
|
{
|
||||||
DPRINT("WdmAudUnload called\n");
|
DPRINT1("WdmAudUnload called\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -80,7 +98,7 @@ WdmAudPnp(
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IrpStack;
|
PIO_STACK_LOCATION IrpStack;
|
||||||
|
|
||||||
DPRINT("WdmAudPnp called\n");
|
DPRINT1("WdmAudPnp called\n");
|
||||||
|
|
||||||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
@ -92,115 +110,6 @@ WdmAudPnp(
|
||||||
return KsDefaultDispatchPnp(DeviceObject, Irp);
|
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(
|
|
||||||
IN PVOID NotificationStructure,
|
|
||||||
IN PVOID Context)
|
|
||||||
{
|
|
||||||
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
|
|
||||||
|
|
||||||
DPRINT1("DeviceInterfaceChangeCallback called %p\n", Event);
|
|
||||||
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -209,15 +118,17 @@ WdmAudCreate(
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
LPWSTR SymbolicLinkList;
|
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
WDMAUD_CLIENT *pClient;
|
||||||
|
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DPRINT1("WdmAudCreate\n");
|
DPRINT1("WdmAudCreate\n");
|
||||||
|
|
||||||
|
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
#if 0
|
#if KS_IMPLEMENTED
|
||||||
Status = KsReferenceSoftwareBusObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension);
|
Status = KsReferenceSoftwareBusObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -226,26 +137,20 @@ WdmAudCreate(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO,
|
Status = WdmAudOpenSysaudio(DeviceObject, &pClient);
|
||||||
NULL,
|
if (!NT_SUCCESS(Status))
|
||||||
0,
|
|
||||||
&SymbolicLinkList);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList);
|
DPRINT1("Failed to open sysaudio!\n");
|
||||||
ExFreePool(SymbolicLinkList);
|
if (pClient)
|
||||||
|
ExFreePool(pClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
ASSERT(IoStack->FileObject);
|
||||||
|
|
||||||
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
|
/* store client context in file object */
|
||||||
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
|
IoStack->FileObject->FsContext = pClient;
|
||||||
(PVOID)&KSCATEGORY_SYSAUDIO,
|
Status = STATUS_SUCCESS;
|
||||||
DeviceObject->DriverObject,
|
|
||||||
DeviceInterfaceChangeCallback,
|
|
||||||
(PVOID)DeviceExtension,
|
|
||||||
&DeviceExtension->SysAudioNotification);
|
|
||||||
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
@ -262,19 +167,33 @@ WdmAudClose(
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
WDMAUD_CLIENT *pClient;
|
||||||
|
|
||||||
DPRINT1("WdmAudClose\n");
|
DPRINT1("WdmAudClose\n");
|
||||||
|
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
#if 0
|
#if KS_IMPLEMENTED
|
||||||
Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
|
Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
|
if (DeviceExtension->SysAudioNotification)
|
||||||
|
Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext;
|
||||||
|
if (pClient)
|
||||||
|
{
|
||||||
|
ZwClose(pClient->hSysAudio);
|
||||||
|
ExFreePool(pClient);
|
||||||
|
IoStack->FileObject->FsContext = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
@ -283,21 +202,6 @@ WdmAudClose(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
WdmAudDeviceControl(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
WdmAudCleanup(
|
WdmAudCleanup(
|
||||||
|
@ -321,9 +225,8 @@ DriverEntry(
|
||||||
IN PUNICODE_STRING Registry_path
|
IN PUNICODE_STRING Registry_path
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DPRINT("Wdmaud.sys loaded\n");
|
DPRINT1("Wdmaud.sys loaded\n");
|
||||||
|
|
||||||
Driver->DriverExtension->AddDevice = WdmAudAddDevice;
|
|
||||||
Driver->DriverUnload = WdmAudUnload;
|
Driver->DriverUnload = WdmAudUnload;
|
||||||
|
|
||||||
|
|
||||||
|
@ -335,6 +238,5 @@ DriverEntry(
|
||||||
Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl;
|
Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl;
|
||||||
Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
|
Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
|
||||||
|
|
||||||
|
return WdmAudInstallDevice(Driver);
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,28 +57,54 @@ typedef struct
|
||||||
} WAVEINCAPS;
|
} WAVEINCAPS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
HANDLE hProcess;
|
||||||
HANDLE Handle;
|
HANDLE hSysAudio;
|
||||||
UNICODE_STRING SymbolicLink;
|
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
}SYSAUDIO_ENTRY;
|
|
||||||
|
}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LIST_ENTRY Entry;
|
||||||
|
UNICODE_STRING SymbolicLink;
|
||||||
|
}SYSAUDIO_ENTRY, *PSYSAUDIO_ENTRY;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
KSDEVICE_HEADER DeviceHeader;
|
KSDEVICE_HEADER DeviceHeader;
|
||||||
PVOID SysAudioNotification;
|
PVOID SysAudioNotification;
|
||||||
|
|
||||||
|
BOOL DeviceInterfaceSupport;
|
||||||
|
|
||||||
|
KSPIN_LOCK Lock;
|
||||||
ULONG NumSysAudioDevices;
|
ULONG NumSysAudioDevices;
|
||||||
LIST_ENTRY SysAudioDeviceList;
|
LIST_ENTRY SysAudioDeviceList;
|
||||||
|
|
||||||
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
|
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudRegisterDeviceInterface(
|
||||||
|
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||||
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudOpenSysAudioDevices(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudOpenSysaudio(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PWDMAUD_CLIENT *pClient);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
WdmAudDeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
|
<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
|
||||||
<module name="wdmaud_kernel" type="kernelmodedriver" installbase="system32/drivers" installname="wdmaud.sys">
|
<module name="wdmaud_kernel" type="kernelmodedriver" installbase="system32/drivers" installname="wdmaud.sys">
|
||||||
<include base="wdmaud_kernel">.</include>
|
<include base="wdmaud_kernel">.</include>
|
||||||
|
<define name="_COMDDK_" />
|
||||||
<include base="ReactOS">include/reactos/libs/sound</include>
|
<include base="ReactOS">include/reactos/libs/sound</include>
|
||||||
<library>ntoskrnl</library>
|
<library>ntoskrnl</library>
|
||||||
<library>ks</library>
|
<library>ks</library>
|
||||||
|
<file>control.c</file>
|
||||||
|
<file>deviface.c</file>
|
||||||
<file>entry.c</file>
|
<file>entry.c</file>
|
||||||
|
<file>wdmaud.rc</file>
|
||||||
</module>
|
</module>
|
||||||
|
|
5
reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc
Normal file
5
reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#define REACTOS_VERSION_DLL
|
||||||
|
#define REACTOS_STR_FILE_DESCRIPTION "Reactos audio mapper driver\0"
|
||||||
|
#define REACTOS_STR_INTERNAL_NAME "wdmaud\0"
|
||||||
|
#define REACTOS_STR_ORIGINAL_FILENAME "wdmaud.sys\0"
|
||||||
|
#include <reactos/version.rc>
|
291
reactos/drivers/wdm/audio/sysaudio/control.c
Normal file
291
reactos/drivers/wdm/audio/sysaudio/control.c
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/sysaudio/control.c
|
||||||
|
* PURPOSE: System Audio graph builder
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
#include <ntddk.h>
|
||||||
|
#include <portcls.h>
|
||||||
|
#include <ks.h>
|
||||||
|
#include <ksmedia.h>
|
||||||
|
#include <math.h>
|
||||||
|
#define YDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
#include "sysaudio.h"
|
||||||
|
|
||||||
|
const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
|
||||||
|
const GUID KSPROPSETID_Sysaudio_Pin = {0xA3A53220L, 0xC6E4, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
|
||||||
|
const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SetIrpIoStatus(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN NTSTATUS Status,
|
||||||
|
IN ULONG Length)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = Length;
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PKSAUDIO_DEVICE_ENTRY
|
||||||
|
GetListEntry(
|
||||||
|
IN PLIST_ENTRY Head,
|
||||||
|
IN ULONG Index)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Entry = Head->Flink;
|
||||||
|
|
||||||
|
while(Index-- && Entry != Head)
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
|
||||||
|
if (Entry == Head)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioOpenVirtualDevice(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN ULONG DeviceNumber,
|
||||||
|
PSYSAUDIODEVEXT DeviceExtension)
|
||||||
|
{
|
||||||
|
PULONG Index;
|
||||||
|
ULONG Count;
|
||||||
|
PSYSAUDIO_CLIENT ClientInfo;
|
||||||
|
PKSAUDIO_DEVICE_ENTRY Entry;
|
||||||
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
|
||||||
|
/* access the create item */
|
||||||
|
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
||||||
|
ASSERT(CreateItem);
|
||||||
|
|
||||||
|
if (DeviceNumber >= DeviceExtension->NumberOfKsAudioDevices)
|
||||||
|
{
|
||||||
|
/* invalid device index */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get device context */
|
||||||
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber);
|
||||||
|
ASSERT(Entry != NULL);
|
||||||
|
|
||||||
|
/* get client context */
|
||||||
|
ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
|
||||||
|
/* does the client already use a device */
|
||||||
|
if (!ClientInfo->NumDevices)
|
||||||
|
{
|
||||||
|
/* first device to be openend */
|
||||||
|
ClientInfo->Devices = ExAllocatePool(NonPagedPool, sizeof(ULONG));
|
||||||
|
if (!ClientInfo->Devices)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||||
|
}
|
||||||
|
ClientInfo->NumDevices = 1;
|
||||||
|
ClientInfo->Devices[0] = DeviceNumber;
|
||||||
|
/* increase usage count */
|
||||||
|
Entry->NumberOfClients++;
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if device has already been openend */
|
||||||
|
for(Count = 0; Count < ClientInfo->NumDevices; Count++)
|
||||||
|
{
|
||||||
|
if (ClientInfo->Devices[Count] == DeviceNumber)
|
||||||
|
{
|
||||||
|
/* device has already been opened */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* new device to be openend */
|
||||||
|
Index = ExAllocatePool(NonPagedPool, sizeof(ULONG) * (ClientInfo->NumDevices + 1));
|
||||||
|
if (!Index)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||||
|
}
|
||||||
|
/* increase usage count */
|
||||||
|
Entry->NumberOfClients++;
|
||||||
|
|
||||||
|
/* copy device count array */
|
||||||
|
RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG));
|
||||||
|
Index[ClientInfo->NumDevices] = DeviceNumber;
|
||||||
|
ExFreePool(ClientInfo->Devices);
|
||||||
|
ClientInfo->NumDevices++;
|
||||||
|
ClientInfo->Devices = Index;
|
||||||
|
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioHandleProperty(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
KSPROPERTY PropertyRequest;
|
||||||
|
KSCOMPONENTID ComponentId;
|
||||||
|
PULONG Index;
|
||||||
|
PKSPROPERTY Property;
|
||||||
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
|
PKSAUDIO_DEVICE_ENTRY Entry;
|
||||||
|
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
||||||
|
PSYSAUDIO_CLIENT ClientInfo;
|
||||||
|
ULONG Count, BytesReturned;
|
||||||
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
UNICODE_STRING GuidString;
|
||||||
|
|
||||||
|
/* access the create item */
|
||||||
|
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
||||||
|
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
|
||||||
|
{
|
||||||
|
/* buffer must be atleast of sizeof KSPROPERTY */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY));
|
||||||
|
}
|
||||||
|
|
||||||
|
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
|
||||||
|
{
|
||||||
|
if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID)
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY) + sizeof(ULONG))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY) + sizeof(ULONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSCOMPONENTID))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSCOMPONENTID));
|
||||||
|
}
|
||||||
|
|
||||||
|
Index = (PULONG)(Property + 1);
|
||||||
|
|
||||||
|
if (DeviceExtension->NumberOfKsAudioDevices <= *Index)
|
||||||
|
{
|
||||||
|
/* invalid index */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, *Index);
|
||||||
|
ASSERT(Entry != NULL);
|
||||||
|
|
||||||
|
PropertyRequest.Set = KSPROPSETID_General;
|
||||||
|
PropertyRequest.Id = KSPROPERTY_GENERAL_COMPONENTID;
|
||||||
|
PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
|
||||||
|
/* call the filter */
|
||||||
|
Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("KsSynchronousIoControlDevice failed with %x for KSPROPERTY_GENERAL_COMPONENTID\n", Status);
|
||||||
|
return SetIrpIoStatus(Irp, Status, 0);
|
||||||
|
}
|
||||||
|
RtlMoveMemory(Irp->UserBuffer, &ComponentId, sizeof(KSCOMPONENTID));
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSCOMPONENTID));
|
||||||
|
}
|
||||||
|
else if (Property->Id == KSPROPERTY_SYSAUDIO_DEVICE_COUNT)
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
|
||||||
|
}
|
||||||
|
*((PULONG)Irp->UserBuffer) = DeviceExtension->NumberOfKsAudioDevices;
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
|
||||||
|
}
|
||||||
|
else if (Property->Id == KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE)
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSCOMPONENTID));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Property->Flags & KSPROPERTY_TYPE_SET)
|
||||||
|
{
|
||||||
|
Index = (PULONG)Irp->UserBuffer;
|
||||||
|
return SysAudioOpenVirtualDevice(Irp, *Index, DeviceExtension);
|
||||||
|
}
|
||||||
|
else if (Property->Flags & KSPROPERTY_TYPE_GET)
|
||||||
|
{
|
||||||
|
Index = (PULONG)Irp->UserBuffer;
|
||||||
|
/* get client context */
|
||||||
|
ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
|
||||||
|
ASSERT(ClientInfo);
|
||||||
|
/* does the client already use a device */
|
||||||
|
if (!ClientInfo->NumDevices)
|
||||||
|
{
|
||||||
|
/* no device open */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
}
|
||||||
|
/* store last opened device number */
|
||||||
|
*Index = ClientInfo->Devices[ClientInfo->NumDevices-1];
|
||||||
|
/* found no device with that device index open */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Property->Id == KSPROPERTY_SYSAUDIO_INSTANCE_INFO)
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SYSAUDIO_INSTANCE_INFO))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(SYSAUDIO_INSTANCE_INFO));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get input parameter */
|
||||||
|
InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property;
|
||||||
|
|
||||||
|
if (Property->Flags & KSPROPERTY_TYPE_SET)
|
||||||
|
{
|
||||||
|
return SysAudioOpenVirtualDevice(Irp, InstanceInfo->DeviceNumber, DeviceExtension);
|
||||||
|
}
|
||||||
|
else if (Property->Flags & KSPROPERTY_TYPE_GET)
|
||||||
|
{
|
||||||
|
/* get client context */
|
||||||
|
ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
|
||||||
|
ASSERT(ClientInfo);
|
||||||
|
/* does the client already use a device */
|
||||||
|
if (!ClientInfo->NumDevices)
|
||||||
|
{
|
||||||
|
/* no device open */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
}
|
||||||
|
for(Count = 0; Count < ClientInfo->NumDevices; Count++)
|
||||||
|
{
|
||||||
|
if (ClientInfo->Devices[Count] == InstanceInfo->DeviceNumber)
|
||||||
|
{
|
||||||
|
/* specified device is open */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* found no device with that device index open */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlStringFromGUID(&Property->Set, &GuidString);
|
||||||
|
DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
|
||||||
|
DbgBreakPoint();
|
||||||
|
RtlFreeUnicodeString(&GuidString);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
239
reactos/drivers/wdm/audio/sysaudio/deviface.c
Normal file
239
reactos/drivers/wdm/audio/sysaudio/deviface.c
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/sysaudio/deviface.c
|
||||||
|
* PURPOSE: System Audio graph builder
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
#include <ntddk.h>
|
||||||
|
#include <portcls.h>
|
||||||
|
#include <ks.h>
|
||||||
|
#include <ksmedia.h>
|
||||||
|
#include <math.h>
|
||||||
|
#define YDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
#include "sysaudio.h"
|
||||||
|
|
||||||
|
const GUID GUID_DEVICE_INTERFACE_ARRIVAL = {0xCB3A4004L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
|
||||||
|
const GUID GUID_DEVICE_INTERFACE_REMOVAL = {0xCB3A4005L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
|
||||||
|
const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
||||||
|
const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DeviceInterfaceChangeCallback(
|
||||||
|
IN PVOID NotificationStructure,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
|
||||||
|
SYSAUDIODEVEXT *DeviceExtension = (SYSAUDIODEVEXT*)Context;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
|
||||||
|
|
||||||
|
if (IsEqualGUIDAligned(&Event->Event,
|
||||||
|
&GUID_DEVICE_INTERFACE_ARRIVAL))
|
||||||
|
{
|
||||||
|
/* a new device has arrived */
|
||||||
|
|
||||||
|
PFILE_OBJECT FileObject = NULL;
|
||||||
|
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
|
||||||
|
HANDLE NodeHandle;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
|
||||||
|
|
||||||
|
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
|
||||||
|
if (!DeviceEntry)
|
||||||
|
{
|
||||||
|
DPRINT1("No Mem\n");
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
DeviceEntry->DeviceName.Length = 0;
|
||||||
|
DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR);
|
||||||
|
DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
|
||||||
|
if (!DeviceEntry->DeviceName.Buffer)
|
||||||
|
{
|
||||||
|
DPRINT1("No Mem\n");
|
||||||
|
ExFreePool(DeviceEntry);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\")))
|
||||||
|
{
|
||||||
|
DPRINT1("No Mem\n");
|
||||||
|
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||||
|
ExFreePool(DeviceEntry);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName)))
|
||||||
|
{
|
||||||
|
DPRINT1("No Mem\n");
|
||||||
|
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||||
|
ExFreePool(DeviceEntry);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("Sym %wZ\n", &DeviceEntry->DeviceName);
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &DeviceEntry->DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
|
|
||||||
|
Status = ZwCreateFile(&NodeHandle,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
FILE_OPEN,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("ZwCreateFile failed with %x\n", Status);
|
||||||
|
ExFreePool(DeviceEntry);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ObReferenceObjectByHandle(NodeHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ZwClose(NodeHandle);
|
||||||
|
ExFreePool(DeviceEntry);
|
||||||
|
DPRINT1("ObReferenceObjectByHandle failed with %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceEntry->Handle = NodeHandle;
|
||||||
|
DeviceEntry->FileObject = FileObject;
|
||||||
|
|
||||||
|
InsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry);
|
||||||
|
DeviceExtension->NumberOfKsAudioDevices++;
|
||||||
|
|
||||||
|
DPRINT1("Successfully opened audio device handle %p file object %p device object %p\n", NodeHandle, FileObject, FileObject->DeviceObject);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
else if (IsEqualGUIDAligned(&Event->Event,
|
||||||
|
&GUID_DEVICE_INTERFACE_REMOVAL))
|
||||||
|
{
|
||||||
|
DPRINT1("Remove interface to audio device!\n");
|
||||||
|
///FIXME
|
||||||
|
///
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UNICODE_STRING EventName, InterfaceGuid;
|
||||||
|
|
||||||
|
RtlStringFromGUID(&Event->Event, &EventName);
|
||||||
|
RtlStringFromGUID(&Event->InterfaceClassGuid, &InterfaceGuid);
|
||||||
|
DPRINT1("Unknown event: Event %wZ GUID %wZ\n", &EventName, &InterfaceGuid);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioRegisterNotifications(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
SYSAUDIODEVEXT *DeviceExtension)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
|
||||||
|
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
|
||||||
|
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
|
||||||
|
(PVOID)&KS_CATEGORY_AUDIO,
|
||||||
|
DriverObject,
|
||||||
|
DeviceInterfaceChangeCallback,
|
||||||
|
(PVOID)DeviceExtension,
|
||||||
|
(PVOID*)&DeviceExtension->KsAudioNotificationEntry);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("IoRegisterPlugPlayNotification failed with %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
|
||||||
|
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
|
||||||
|
(PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
|
||||||
|
DriverObject,
|
||||||
|
DeviceInterfaceChangeCallback,
|
||||||
|
(PVOID)DeviceExtension,
|
||||||
|
(PVOID*)&DeviceExtension->EchoCancelNotificationEntry);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* ignore failure for now */
|
||||||
|
DPRINT1("IoRegisterPlugPlayNotification failed for DMOCATEGORY_ACOUSTIC_ECHO_CANCEL\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioRegisterDeviceInterfaces(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
UNICODE_STRING SymbolicLink;
|
||||||
|
|
||||||
|
Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_MIDIOUT_DEVICE, NULL, &SymbolicLink);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
|
||||||
|
RtlFreeUnicodeString(&SymbolicLink);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to register KSCATEGORY_PREFERRED_MIDIOUT_DEVICE interface Status %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEIN_DEVICE, NULL, &SymbolicLink);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
|
||||||
|
RtlFreeUnicodeString(&SymbolicLink);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to register KSCATEGORY_PREFERRED_WAVEIN_DEVICE interface Status %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEOUT_DEVICE, NULL, &SymbolicLink);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
|
||||||
|
RtlFreeUnicodeString(&SymbolicLink);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to register KSCATEGORY_PREFERRED_WAVEOUT_DEVICE interface Status %x\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_SYSAUDIO, NULL, &SymbolicLink);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
|
||||||
|
RtlFreeUnicodeString(&SymbolicLink);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to register KSCATEGORY_SYSAUDIO interface Status %x\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
244
reactos/drivers/wdm/audio/sysaudio/dispatcher.c
Normal file
244
reactos/drivers/wdm/audio/sysaudio/dispatcher.c
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/sysaudio/dispatcher.c
|
||||||
|
* PURPOSE: System Audio graph builder
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
#include <ntddk.h>
|
||||||
|
#include <portcls.h>
|
||||||
|
#include <ks.h>
|
||||||
|
#include <ksmedia.h>
|
||||||
|
#include <math.h>
|
||||||
|
#define YDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
#include "sysaudio.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnDeviceIoControl(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
|
DPRINT1("Dispatch_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
|
||||||
|
{
|
||||||
|
return SysAudioHandleProperty(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnRead(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT1("Dispatch_fnRead called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnWrite(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT1("Dispatch_fnWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnFlush(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT1("Dispatch_fnFlush called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnClose(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnQuerySecurity(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT1("Dispatch_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnSetSecurity(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
|
||||||
|
DPRINT1("Dispatch_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnFastDeviceIoControl(
|
||||||
|
PFILE_OBJECT FileObject,
|
||||||
|
BOOLEAN Wait,
|
||||||
|
PVOID InputBuffer,
|
||||||
|
ULONG InputBufferLength,
|
||||||
|
PVOID OutputBuffer,
|
||||||
|
ULONG OutputBufferLength,
|
||||||
|
ULONG IoControlCode,
|
||||||
|
PIO_STATUS_BLOCK IoStatus,
|
||||||
|
PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
DPRINT1("Dispatch_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnFastRead(
|
||||||
|
PFILE_OBJECT FileObject,
|
||||||
|
PLARGE_INTEGER FileOffset,
|
||||||
|
ULONG Length,
|
||||||
|
BOOLEAN Wait,
|
||||||
|
ULONG LockKey,
|
||||||
|
PVOID Buffer,
|
||||||
|
PIO_STATUS_BLOCK IoStatus,
|
||||||
|
PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
DPRINT1("Dispatch_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
Dispatch_fnFastWrite(
|
||||||
|
PFILE_OBJECT FileObject,
|
||||||
|
PLARGE_INTEGER FileOffset,
|
||||||
|
ULONG Length,
|
||||||
|
BOOLEAN Wait,
|
||||||
|
ULONG LockKey,
|
||||||
|
PVOID Buffer,
|
||||||
|
PIO_STATUS_BLOCK IoStatus,
|
||||||
|
PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
DPRINT1("Dispatch_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static KSDISPATCH_TABLE DispatchTable =
|
||||||
|
{
|
||||||
|
Dispatch_fnDeviceIoControl,
|
||||||
|
Dispatch_fnRead,
|
||||||
|
Dispatch_fnWrite,
|
||||||
|
Dispatch_fnFlush,
|
||||||
|
Dispatch_fnClose,
|
||||||
|
Dispatch_fnQuerySecurity,
|
||||||
|
Dispatch_fnSetSecurity,
|
||||||
|
Dispatch_fnFastDeviceIoControl,
|
||||||
|
Dispatch_fnFastRead,
|
||||||
|
Dispatch_fnFastWrite,
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DispatchCreateSysAudio(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
KSOBJECT_HEADER ObjectHeader;
|
||||||
|
PSYSAUDIO_CLIENT Client;
|
||||||
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
|
||||||
|
DPRINT1("DispatchCreateSysAudio entered\n");
|
||||||
|
DbgBreakPoint();
|
||||||
|
|
||||||
|
/* allocate create item */
|
||||||
|
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
if (!CreateItem)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
Client = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT));
|
||||||
|
if (!Client)
|
||||||
|
{
|
||||||
|
ExFreePool(CreateItem);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
/* initialize client struct */
|
||||||
|
RtlZeroMemory(Client, sizeof(SYSAUDIO_CLIENT));
|
||||||
|
|
||||||
|
/* zero create struct */
|
||||||
|
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
|
||||||
|
/* store create context */
|
||||||
|
CreateItem->Context = (PVOID)Client;
|
||||||
|
|
||||||
|
/* allocate object header */
|
||||||
|
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
|
||||||
|
|
||||||
|
DPRINT1("KsAllocateObjectHeader result %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioAllocateDeviceHeader(
|
||||||
|
IN SYSAUDIODEVEXT *DeviceExtension)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
|
||||||
|
/* allocate create item */
|
||||||
|
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
if (!CreateItem)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* initialize create item struct */
|
||||||
|
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
CreateItem->Create = DispatchCreateSysAudio;
|
||||||
|
RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
|
||||||
|
|
||||||
|
Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
|
||||||
|
1,
|
||||||
|
CreateItem);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* FILE: drivers/wdm/audio/sysaudio/main.c
|
* FILE: drivers/wdm/audio/sysaudio/main.c
|
||||||
* PURPOSE: System Audio graph builder
|
* PURPOSE: System Audio graph builder
|
||||||
* PROGRAMMER: Andrew Greenwood
|
* PROGRAMMER: Andrew Greenwood
|
||||||
*
|
* Johannes Anderwald
|
||||||
* HISTORY:
|
* HISTORY:
|
||||||
* 8 Jul 07 Started basic implementation
|
* 8 Jul 07 Started basic implementation
|
||||||
*/
|
*/
|
||||||
|
@ -13,20 +13,20 @@
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#include <portcls.h>
|
#include <portcls.h>
|
||||||
#include <ks.h>
|
#include <ks.h>
|
||||||
|
#include <ksmedia.h>
|
||||||
|
#include <math.h>
|
||||||
#define YDEBUG
|
#define YDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
//#include <dxsdk/mediaobj.h>
|
//#include <dxsdk/mediaobj.h>
|
||||||
#include "sysaudio.h"
|
#include "sysaudio.h"
|
||||||
|
|
||||||
const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
|
|
||||||
const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
|
const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
|
||||||
const GUID KSCATEGORY_AUDIO_DEVICE = {0xFBF6F530L, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
|
const GUID KSCATEGORY_AUDIO_DEVICE = {0xFBF6F530L, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
|
||||||
const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE = {0xD6C5066EL, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
|
const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE = {0xD6C5066EL, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
|
||||||
const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE = {0xD6C50671L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
|
const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE = {0xD6C50671L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
|
||||||
const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE = {0xD6C50674L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
|
const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE = {0xD6C50674L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
|
||||||
const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
|
||||||
const GUID GUID_DEVICE_INTERFACE_ARRIVAL = {0xCB3A4004L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
|
|
||||||
const GUID GUID_DEVICE_INTERFACE_REMOVAL = {0xCB3A4005L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -49,13 +49,12 @@ SysAudio_Pnp(
|
||||||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
DPRINT1("SysAudio_Pnp called for func %x\n", IrpStack->MinorFunction);
|
DPRINT1("SysAudio_Pnp called for func %x\n", IrpStack->MinorFunction);
|
||||||
DbgBreakPoint();
|
|
||||||
|
|
||||||
DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
|
DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
|
||||||
if (IrpStack->MinorFunction == IRP_MN_START_DEVICE)
|
if (IrpStack->MinorFunction == IRP_MN_START_DEVICE)
|
||||||
{
|
{
|
||||||
DPRINT1("SysAudio_Pnp called for func IRP_MN_START_DEVICE\n");
|
DPRINT1("SysAudio_Pnp called for func IRP_MN_START_DEVICE\n");
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
@ -81,132 +80,6 @@ SysAudio_Pnp(
|
||||||
return KsDefaultDispatchPnp(DeviceObject, Irp);
|
return KsDefaultDispatchPnp(DeviceObject, Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
DeviceInterfaceChangeCallback(
|
|
||||||
IN PVOID NotificationStructure,
|
|
||||||
IN PVOID Context)
|
|
||||||
{
|
|
||||||
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
|
|
||||||
SYSAUDIODEVEXT *DeviceExtension = (SYSAUDIODEVEXT*)Context;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
|
|
||||||
|
|
||||||
if (IsEqualGUIDAligned(&Event->Event,
|
|
||||||
&GUID_DEVICE_INTERFACE_ARRIVAL))
|
|
||||||
{
|
|
||||||
/* a new device has arrived */
|
|
||||||
|
|
||||||
PFILE_OBJECT FileObject = NULL;
|
|
||||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
|
|
||||||
HANDLE NodeHandle;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
|
|
||||||
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
|
|
||||||
if (!DeviceEntry)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
DeviceEntry->DeviceName.Length = 0;
|
|
||||||
DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR);
|
|
||||||
DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
|
|
||||||
if (!DeviceEntry->DeviceName.Buffer)
|
|
||||||
{
|
|
||||||
ExFreePool(DeviceEntry);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\")))
|
|
||||||
{
|
|
||||||
|
|
||||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
|
||||||
ExFreePool(DeviceEntry);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName)))
|
|
||||||
{
|
|
||||||
|
|
||||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
|
||||||
ExFreePool(DeviceEntry);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT1("Sym %wZ\n", &DeviceEntry->DeviceName);
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &DeviceEntry->DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
|
|
||||||
|
|
||||||
Status = ZwCreateFile(&NodeHandle,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
&ObjectAttributes,
|
|
||||||
&IoStatusBlock,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
FILE_OPEN,
|
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT,
|
|
||||||
NULL,
|
|
||||||
0);
|
|
||||||
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ZwCreateFile failed with %x\n", Status);
|
|
||||||
ExFreePool(DeviceEntry);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(NodeHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ZwClose(NodeHandle);
|
|
||||||
ExFreePool(DeviceEntry);
|
|
||||||
DPRINT1("ObReferenceObjectByHandle failed with %x\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceEntry->Handle = NodeHandle;
|
|
||||||
DeviceEntry->FileObject = FileObject;
|
|
||||||
|
|
||||||
InsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry);
|
|
||||||
DeviceExtension->NumberOfKsAudioDevices++;
|
|
||||||
|
|
||||||
DPRINT1("Successfully opened audio device handle %p file object %p device object %p\n", NodeHandle, FileObject, FileObject->DeviceObject);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
else if (IsEqualGUIDAligned(&Event->Event,
|
|
||||||
&GUID_DEVICE_INTERFACE_REMOVAL))
|
|
||||||
{
|
|
||||||
DPRINT1("Remove interface to audio device!\n");
|
|
||||||
///FIXME
|
|
||||||
///
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UNICODE_STRING EventName, InterfaceGuid;
|
|
||||||
|
|
||||||
RtlStringFromGUID(&Event->Event, &EventName);
|
|
||||||
RtlStringFromGUID(&Event->InterfaceClassGuid, &InterfaceGuid);
|
|
||||||
DPRINT1("Unknown event: Event %wZ GUID %wZ\n", &EventName, &InterfaceGuid);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
DispatchCreate(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
DPRINT1("DispatchCreate\n");
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SysAudio_InstallDevice(
|
SysAudio_InstallDevice(
|
||||||
|
@ -217,9 +90,8 @@ SysAudio_InstallDevice(
|
||||||
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
|
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
//PDEVICE_OBJECT NextDeviceObject;
|
//PDEVICE_OBJECT NextDeviceObject;
|
||||||
KSOBJECT_CREATE_ITEM CreateItem;
|
|
||||||
SYSAUDIODEVEXT *DeviceExtension;
|
SYSAUDIODEVEXT *DeviceExtension;
|
||||||
UNICODE_STRING SymbolicLink;
|
|
||||||
|
|
||||||
DPRINT1("SysAudio_InstallDevice called\n");
|
DPRINT1("SysAudio_InstallDevice called\n");
|
||||||
|
|
||||||
|
@ -239,16 +111,22 @@ SysAudio_InstallDevice(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the symbolic link */
|
/* register device interfaces */
|
||||||
Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
Status = SysAudioRegisterDeviceInterfaces(DeviceObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
IoDeleteDevice(DeviceObject);
|
/* failed to register
|
||||||
DPRINT("Failed to create \\DosDevices\\sysaudio symlink!\n");
|
* create a hack interface
|
||||||
return Status;
|
*/
|
||||||
|
Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
DPRINT("Failed to create sysaudio symlink!\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
|
DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
|
||||||
/* initialize device extension */
|
/* initialize device extension */
|
||||||
RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
|
RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
|
||||||
|
@ -257,109 +135,27 @@ SysAudio_InstallDevice(
|
||||||
//DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
|
//DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
|
||||||
InitializeListHead(&DeviceExtension->KsAudioDeviceList);
|
InitializeListHead(&DeviceExtension->KsAudioDeviceList);
|
||||||
|
|
||||||
/* initialize create item struct */
|
Status = SysAudioAllocateDeviceHeader(DeviceExtension);
|
||||||
RtlZeroMemory(&CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
|
|
||||||
CreateItem.Create = DispatchCreate;
|
|
||||||
|
|
||||||
Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
|
|
||||||
1,
|
|
||||||
&CreateItem);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
|
DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
Status = SysAudioRegisterNotifications(DriverObject,
|
||||||
//NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
|
DeviceExtension);
|
||||||
/// FIXME
|
|
||||||
/// KsSetDevicePnpAndBaseObject(DeviceExtension->KsDeviceHeader, NextDeviceObject, DeviceObject);
|
|
||||||
///
|
|
||||||
/// DeviceExtension->NextDeviceObject = NextDeviceObject;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
|
|
||||||
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
|
|
||||||
(PVOID)&KS_CATEGORY_AUDIO,
|
|
||||||
DriverObject,
|
|
||||||
DeviceInterfaceChangeCallback,
|
|
||||||
(PVOID)DeviceExtension,
|
|
||||||
(PVOID*)&DeviceExtension->KsAudioNotificationEntry);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("IoRegisterPlugPlayNotification failed with %x\n", Status);
|
DPRINT1("Failed to register device notifications\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
|
|
||||||
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
|
|
||||||
(PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
|
|
||||||
DriverObject,
|
|
||||||
DeviceInterfaceChangeCallback,
|
|
||||||
(PVOID)DeviceExtension,
|
|
||||||
(PVOID*)&DeviceExtension->EchoCancelNotificationEntry);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("IoRegisterPlugPlayNotification failed with %x\n", Status);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_MIDIOUT_DEVICE, NULL, &SymbolicLink);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLink);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to register KSCATEGORY_PREFERRED_MIDIOUT_DEVICE interface Status %x\n", Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEIN_DEVICE, NULL, &SymbolicLink);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLink);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to register KSCATEGORY_PREFERRED_WAVEIN_DEVICE interface Status %x\n", Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEOUT_DEVICE, NULL, &SymbolicLink);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLink);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to register KSCATEGORY_PREFERRED_WAVEOUT_DEVICE interface Status %x\n", Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_SYSAUDIO, NULL, &SymbolicLink);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLink);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to register KSCATEGORY_SYSAUDIO interface Status %x\n", Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* set io flags */
|
/* set io flags */
|
||||||
DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
|
DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
|
||||||
/* clear initializing flag */
|
/* clear initializing flag */
|
||||||
DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
|
DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
DPRINT("Device SysAudio_AddDevice result %x\n", Status);
|
DPRINT("Device SysAudio_InstallDevice result %x\n", Status);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -375,23 +171,6 @@ cleanup:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
SysAudio_Stub(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
DPRINT1("SysAudio_Stub called\n");
|
|
||||||
|
|
||||||
/* TODO */
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
DriverEntry(
|
DriverEntry(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
@ -399,20 +178,10 @@ DriverEntry(
|
||||||
{
|
{
|
||||||
DPRINT1("System audio graph builder (sysaudio) started\n");
|
DPRINT1("System audio graph builder (sysaudio) started\n");
|
||||||
|
|
||||||
DPRINT1("Setting KS function handlers\n");
|
|
||||||
|
|
||||||
#if KS_IMPLEMENTED
|
|
||||||
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
|
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
|
||||||
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
|
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
|
||||||
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
|
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
|
||||||
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
|
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
|
||||||
#else
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = SysAudio_Stub;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = SysAudio_Stub;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = SysAudio_Stub;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SysAudio_Stub;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
|
DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
|
||||||
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
|
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
#ifndef SYSAUDIO_H__
|
#ifndef SYSAUDIO_H__
|
||||||
#define SYSAUDIO_H__
|
#define SYSAUDIO_H__
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG NumDevices;
|
||||||
|
PULONG Devices;
|
||||||
|
|
||||||
|
}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
|
@ -8,6 +16,7 @@ typedef struct
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
|
|
||||||
|
ULONG NumberOfClients;
|
||||||
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
|
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,10 +26,29 @@ typedef struct
|
||||||
PDEVICE_OBJECT NextDeviceObject;
|
PDEVICE_OBJECT NextDeviceObject;
|
||||||
KSDEVICE_HEADER KsDeviceHeader;
|
KSDEVICE_HEADER KsDeviceHeader;
|
||||||
ULONG NumberOfKsAudioDevices;
|
ULONG NumberOfKsAudioDevices;
|
||||||
|
|
||||||
LIST_ENTRY KsAudioDeviceList;
|
LIST_ENTRY KsAudioDeviceList;
|
||||||
PVOID KsAudioNotificationEntry;
|
PVOID KsAudioNotificationEntry;
|
||||||
PVOID EchoCancelNotificationEntry;
|
PVOID EchoCancelNotificationEntry;
|
||||||
KMUTEX Mutex;
|
KMUTEX Mutex;
|
||||||
}SYSAUDIODEVEXT;
|
}SYSAUDIODEVEXT, *PSYSAUDIODEVEXT;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioAllocateDeviceHeader(
|
||||||
|
IN SYSAUDIODEVEXT *DeviceExtension);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioRegisterDeviceInterfaces(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioRegisterNotifications(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
SYSAUDIODEVEXT *DeviceExtension);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SysAudioHandleProperty(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
<include base="sysaudio">.</include>
|
<include base="sysaudio">.</include>
|
||||||
<library>ntoskrnl</library>
|
<library>ntoskrnl</library>
|
||||||
<library>ks</library>
|
<library>ks</library>
|
||||||
|
<library>libcntpr</library>
|
||||||
<define name="_COMDDK_" />
|
<define name="_COMDDK_" />
|
||||||
|
<file>control.c</file>
|
||||||
|
<file>deviface.c</file>
|
||||||
|
<file>dispatcher.c</file>
|
||||||
<file>main.c</file>
|
<file>main.c</file>
|
||||||
<file>sysaudio.rc</file>
|
<file>sysaudio.rc</file>
|
||||||
</module>
|
</module>
|
||||||
|
|
Loading…
Reference in a new issue