From 82bba6cd0c9eee5f15bece197708ad98d3922eb9 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 20 Feb 2009 17:52:47 +0000 Subject: [PATCH] - 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 --- .../drivers/wdm/audio/legacy/wdmaud/control.c | 57 ++++ .../wdm/audio/legacy/wdmaud/deviface.c | 237 ++++++++++++++ .../drivers/wdm/audio/legacy/wdmaud/entry.c | 238 +++++--------- .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 38 ++- .../wdm/audio/legacy/wdmaud/wdmaud.rbuild | 4 + .../drivers/wdm/audio/legacy/wdmaud/wdmaud.rc | 5 + reactos/drivers/wdm/audio/sysaudio/control.c | 291 ++++++++++++++++++ reactos/drivers/wdm/audio/sysaudio/deviface.c | 239 ++++++++++++++ .../drivers/wdm/audio/sysaudio/dispatcher.c | 244 +++++++++++++++ reactos/drivers/wdm/audio/sysaudio/main.c | 279 ++--------------- reactos/drivers/wdm/audio/sysaudio/sysaudio.h | 30 +- .../wdm/audio/sysaudio/sysaudio.rbuild | 4 + 12 files changed, 1236 insertions(+), 430 deletions(-) create mode 100644 reactos/drivers/wdm/audio/legacy/wdmaud/control.c create mode 100644 reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c create mode 100644 reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc create mode 100644 reactos/drivers/wdm/audio/sysaudio/control.c create mode 100644 reactos/drivers/wdm/audio/sysaudio/deviface.c create mode 100644 reactos/drivers/wdm/audio/sysaudio/dispatcher.c diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c new file mode 100644 index 00000000000..f6dcfd39c6e --- /dev/null +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -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; +} diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c b/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c new file mode 100644 index 00000000000..8b0f5569cb4 --- /dev/null +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c @@ -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; +} + + + diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c index 4c6c7c29c42..dbb432ef590 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c @@ -9,23 +9,24 @@ #include "wdmaud.h" 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 NTAPI -WdmAudAddDevice( - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT PhysicalDeviceObject) +WdmAudInstallDevice( + IN PDRIVER_OBJECT DriverObject) { + UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud"); + UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud"); PDEVICE_OBJECT DeviceObject; - PDEVICE_OBJECT NextDeviceObject; NTSTATUS Status; PWDMAUD_DEVICE_EXTENSION DeviceExtension; - DPRINT("WdmAudAddDevice called\n"); + DPRINT1("WdmAudInstallDevice called\n"); Status = IoCreateDevice(DriverObject, sizeof(WDMAUD_DEVICE_EXTENSION), - NULL, + &DeviceName, FILE_DEVICE_KS, 0, FALSE, @@ -37,26 +38,43 @@ WdmAudAddDevice( return Status; } + /* clear device extension */ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION)); - InitializeListHead(&DeviceExtension->SysAudioDeviceList); - - Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL); + /* register device interfaces */ + Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension); if (!NT_SUCCESS(Status)) { - DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status); + DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status); IoDeleteDevice(DeviceObject); return Status; } - NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); - if (NextDeviceObject) - { - /// FIXME - /// KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension, NextDeviceObject, DeviceObject); - } + /* initialize sysaudio device list */ + InitializeListHead(&DeviceExtension->SysAudioDeviceList); + /* 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_DEVICE_INITIALIZING; @@ -69,7 +87,7 @@ NTAPI WdmAudUnload( IN PDRIVER_OBJECT driver) { - DPRINT("WdmAudUnload called\n"); + DPRINT1("WdmAudUnload called\n"); } NTSTATUS @@ -80,7 +98,7 @@ WdmAudPnp( { PIO_STACK_LOCATION IrpStack; - DPRINT("WdmAudPnp called\n"); + DPRINT1("WdmAudPnp called\n"); IrpStack = IoGetCurrentIrpStackLocation(Irp); @@ -92,115 +110,6 @@ 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( - 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 NTAPI @@ -209,15 +118,17 @@ WdmAudCreate( IN PIRP Irp) { NTSTATUS Status; - LPWSTR SymbolicLinkList; + + PIO_STACK_LOCATION IoStack; + WDMAUD_CLIENT *pClient; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; DPRINT1("WdmAudCreate\n"); - DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; -#if 0 +#if KS_IMPLEMENTED Status = KsReferenceSoftwareBusObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension); if (!NT_SUCCESS(Status)) { @@ -226,26 +137,20 @@ WdmAudCreate( } #endif - Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO, - NULL, - 0, - &SymbolicLinkList); - - if (NT_SUCCESS(Status)) + Status = WdmAudOpenSysaudio(DeviceObject, &pClient); + if (!NT_SUCCESS(Status)) { - WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList); - ExFreePool(SymbolicLinkList); + DPRINT1("Failed to open sysaudio!\n"); + if (pClient) + ExFreePool(pClient); } + IoStack = IoGetCurrentIrpStackLocation(Irp); + ASSERT(IoStack->FileObject); - Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, - PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, - (PVOID)&KSCATEGORY_SYSAUDIO, - DeviceObject->DriverObject, - DeviceInterfaceChangeCallback, - (PVOID)DeviceExtension, - &DeviceExtension->SysAudioNotification); - + /* store client context in file object */ + IoStack->FileObject->FsContext = pClient; + Status = STATUS_SUCCESS; Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; @@ -262,19 +167,33 @@ WdmAudClose( { NTSTATUS Status = STATUS_SUCCESS; PWDMAUD_DEVICE_EXTENSION DeviceExtension; + PIO_STACK_LOCATION IoStack; + WDMAUD_CLIENT *pClient; DPRINT1("WdmAudClose\n"); DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; -#if 0 +#if KS_IMPLEMENTED Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader); -#endif 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.Information = 0; @@ -283,21 +202,6 @@ WdmAudClose( 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 NTAPI WdmAudCleanup( @@ -321,9 +225,8 @@ DriverEntry( IN PUNICODE_STRING Registry_path ) { - DPRINT("Wdmaud.sys loaded\n"); + DPRINT1("Wdmaud.sys loaded\n"); - Driver->DriverExtension->AddDevice = WdmAudAddDevice; Driver->DriverUnload = WdmAudUnload; @@ -335,6 +238,5 @@ DriverEntry( Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl; Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower; - - return STATUS_SUCCESS; + return WdmAudInstallDevice(Driver); } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 62e2f39384e..7fc6ba6bf9f 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -57,28 +57,54 @@ typedef struct } WAVEINCAPS; #endif - - #include "interface.h" typedef struct { - LIST_ENTRY Entry; - HANDLE Handle; - UNICODE_STRING SymbolicLink; + HANDLE hProcess; + HANDLE hSysAudio; PFILE_OBJECT FileObject; -}SYSAUDIO_ENTRY; + +}WDMAUD_CLIENT, *PWDMAUD_CLIENT; + +typedef struct +{ + LIST_ENTRY Entry; + UNICODE_STRING SymbolicLink; +}SYSAUDIO_ENTRY, *PSYSAUDIO_ENTRY; typedef struct { KSDEVICE_HEADER DeviceHeader; PVOID SysAudioNotification; + BOOL DeviceInterfaceSupport; + + KSPIN_LOCK Lock; ULONG NumSysAudioDevices; LIST_ENTRY SysAudioDeviceList; }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 diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild index 93ab5bba026..16568851e25 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild @@ -2,8 +2,12 @@ . + include/reactos/libs/sound ntoskrnl ks + control.c + deviface.c entry.c + wdmaud.rc diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc new file mode 100644 index 00000000000..84a27f7d808 --- /dev/null +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc @@ -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 diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c new file mode 100644 index 00000000000..d885cb2ba9b --- /dev/null +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -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 +#include +#include +#include +#include +#include +#define YDEBUG +#include +#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; +} + + diff --git a/reactos/drivers/wdm/audio/sysaudio/deviface.c b/reactos/drivers/wdm/audio/sysaudio/deviface.c new file mode 100644 index 00000000000..32d71c49c7f --- /dev/null +++ b/reactos/drivers/wdm/audio/sysaudio/deviface.c @@ -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 +#include +#include +#include +#include +#include +#define YDEBUG +#include +#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; +} + diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c new file mode 100644 index 00000000000..0def7c95477 --- /dev/null +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -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 +#include +#include +#include +#include +#include +#define YDEBUG +#include +#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; +} + diff --git a/reactos/drivers/wdm/audio/sysaudio/main.c b/reactos/drivers/wdm/audio/sysaudio/main.c index e20db49512e..d17708e683c 100644 --- a/reactos/drivers/wdm/audio/sysaudio/main.c +++ b/reactos/drivers/wdm/audio/sysaudio/main.c @@ -4,7 +4,7 @@ * FILE: drivers/wdm/audio/sysaudio/main.c * PURPOSE: System Audio graph builder * PROGRAMMER: Andrew Greenwood - * + * Johannes Anderwald * HISTORY: * 8 Jul 07 Started basic implementation */ @@ -13,20 +13,20 @@ #include #include #include +#include +#include #define YDEBUG #include //#include #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_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_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 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 @@ -49,13 +49,12 @@ SysAudio_Pnp( IrpStack = IoGetCurrentIrpStackLocation(Irp); DPRINT1("SysAudio_Pnp called for func %x\n", IrpStack->MinorFunction); - DbgBreakPoint(); DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension; if (IrpStack->MinorFunction == IRP_MN_START_DEVICE) - { + { DPRINT1("SysAudio_Pnp called for func IRP_MN_START_DEVICE\n"); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -81,132 +80,6 @@ SysAudio_Pnp( 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 NTAPI SysAudio_InstallDevice( @@ -217,9 +90,8 @@ SysAudio_InstallDevice( UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio"); PDEVICE_OBJECT DeviceObject; //PDEVICE_OBJECT NextDeviceObject; - KSOBJECT_CREATE_ITEM CreateItem; SYSAUDIODEVEXT *DeviceExtension; - UNICODE_STRING SymbolicLink; + DPRINT1("SysAudio_InstallDevice called\n"); @@ -239,16 +111,22 @@ SysAudio_InstallDevice( return Status; } - /* create the symbolic link */ - Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName); + /* register device interfaces */ + Status = SysAudioRegisterDeviceInterfaces(DeviceObject); if (!NT_SUCCESS(Status)) { - IoDeleteDevice(DeviceObject); - DPRINT("Failed to create \\DosDevices\\sysaudio symlink!\n"); - return Status; + /* failed to register + * create a hack interface + */ + Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName); + if (!NT_SUCCESS(Status)) + { + IoDeleteDevice(DeviceObject); + DPRINT("Failed to create sysaudio symlink!\n"); + return Status; + } } - DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension; /* initialize device extension */ RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT)); @@ -257,109 +135,27 @@ SysAudio_InstallDevice( //DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; InitializeListHead(&DeviceExtension->KsAudioDeviceList); - /* initialize create item struct */ - RtlZeroMemory(&CreateItem, sizeof(KSOBJECT_CREATE_ITEM)); - CreateItem.Create = DispatchCreate; - - Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader, - 1, - &CreateItem); - + Status = SysAudioAllocateDeviceHeader(DeviceExtension); if (!NT_SUCCESS(Status)) { DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status); goto cleanup; } -#if 0 - //NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); - /// 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); - + Status = SysAudioRegisterNotifications(DriverObject, + DeviceExtension); if (!NT_SUCCESS(Status)) { - DPRINT1("IoRegisterPlugPlayNotification failed with %x\n", Status); + DPRINT1("Failed to register device notifications\n"); 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 */ DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; /* clear initializing flag */ DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING; - DPRINT("Device SysAudio_AddDevice result %x\n", Status); + DPRINT("Device SysAudio_InstallDevice result %x\n", Status); return STATUS_SUCCESS; cleanup: @@ -375,23 +171,6 @@ cleanup: 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 DriverEntry( IN PDRIVER_OBJECT DriverObject, @@ -399,20 +178,10 @@ DriverEntry( { 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_CLOSE); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE); 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_SYSTEM_CONTROL] = KsDefaultForwardIrp; diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h index 5136591d2b5..a766e8e71df 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h @@ -1,6 +1,14 @@ #ifndef SYSAUDIO_H__ #define SYSAUDIO_H__ +typedef struct +{ + ULONG NumDevices; + PULONG Devices; + +}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT; + + typedef struct { LIST_ENTRY Entry; @@ -8,6 +16,7 @@ typedef struct PFILE_OBJECT FileObject; UNICODE_STRING DeviceName; + ULONG NumberOfClients; }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY; @@ -17,10 +26,29 @@ typedef struct PDEVICE_OBJECT NextDeviceObject; KSDEVICE_HEADER KsDeviceHeader; ULONG NumberOfKsAudioDevices; + LIST_ENTRY KsAudioDeviceList; PVOID KsAudioNotificationEntry; PVOID EchoCancelNotificationEntry; 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 diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild b/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild index 0e277357725..44655a48cd8 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild @@ -4,7 +4,11 @@ . ntoskrnl ks + libcntpr + control.c + deviface.c + dispatcher.c main.c sysaudio.rc