mirror of
https://github.com/reactos/reactos.git
synced 2025-06-03 16:30:26 +00:00

- The pin creation parameters are now placed right after the reference string. Handle this case in KsValidateConnectRequest - Only store the passed create items, no need to copy the passed create items. This is required for enabling dynamic audio devices - Fix copying of the object class in KsAllocateObjectHeader - Check for KSCREATE_ITEM_IRP_STORAGE flag in KsCreate [PORTCLS] - Reduce initial audio buffer to about 1/3 second which greatly improves performance [SYSAUDIO] - Remove concept of audio subdevices - Remove imported KsCreatePin - Replace OpenDevice loop hack svn path=/trunk/; revision=41842
292 lines
7.3 KiB
C
292 lines
7.3 KiB
C
/*
|
|
* 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 "sysaudio.h"
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
Dispatch_fnDeviceIoControl(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
PIO_STACK_LOCATION IoStack;
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
|
|
{
|
|
return SysAudioHandleProperty(DeviceObject, Irp);
|
|
}
|
|
|
|
/* unsupported request */
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
Dispatch_fnRead(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
/* unsupported request */
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
Dispatch_fnWrite(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
/* unsupported request */
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
Dispatch_fnFlush(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
Dispatch_fnClose(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
DPRINT("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
Dispatch_fnQuerySecurity(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
DPRINT("Dispatch_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
Dispatch_fnSetSecurity(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
|
|
DPRINT("Dispatch_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject);
|
|
|
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
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)
|
|
{
|
|
DPRINT("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)
|
|
{
|
|
DPRINT("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)
|
|
{
|
|
DPRINT("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;
|
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
|
PIO_STACK_LOCATION IoStatus;
|
|
LPWSTR Buffer;
|
|
PSYSAUDIODEVEXT DeviceExtension;
|
|
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
|
|
|
|
IoStatus = IoGetCurrentIrpStackLocation(Irp);
|
|
Buffer = IoStatus->FileObject->FileName.Buffer;
|
|
|
|
DPRINT("DispatchCreateSysAudio entered\n");
|
|
|
|
if (Buffer)
|
|
{
|
|
/* is the request for a new pin */
|
|
if (wcsstr(Buffer, KS_NAME_PIN))
|
|
{
|
|
Status = CreateDispatcher(Irp);
|
|
DPRINT("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject);
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = Status;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
/* allocate create item */
|
|
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
|
|
if (!CreateItem)
|
|
{
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
/* get device extension */
|
|
DeviceExtension = (PSYSAUDIODEVEXT) DeviceObject->DeviceExtension;
|
|
|
|
/* zero create struct */
|
|
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
|
|
|
|
/* store create context */
|
|
RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
|
|
|
|
/* allocate object header */
|
|
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
|
|
|
|
DPRINT("KsAllocateObjectHeader result %x\n", Status);
|
|
/* complete the irp */
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = Status;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
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");
|
|
CreateItem->Flags = KSCREATE_ITEM_WILDCARD;
|
|
|
|
Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
|
|
1,
|
|
CreateItem);
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
SysAudioOpenKMixer(
|
|
IN SYSAUDIODEVEXT *DeviceExtension)
|
|
{
|
|
NTSTATUS Status;
|
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\kmixer");
|
|
UNICODE_STRING DevicePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\kmixer");
|
|
|
|
Status = ZwLoadDriver(&DevicePath);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
Status = OpenDevice(&DeviceName, &DeviceExtension->KMixerHandle, &DeviceExtension->KMixerFileObject);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DeviceExtension->KMixerHandle = NULL;
|
|
DeviceExtension->KMixerFileObject = NULL;
|
|
}
|
|
}
|
|
|
|
DPRINT("Status %lx KMixerHandle %p KMixerFileObject %p\n", Status, DeviceExtension->KMixerHandle, DeviceExtension->KMixerFileObject);
|
|
return STATUS_SUCCESS;
|
|
}
|