2006-12-10 05:43:49 +00:00
|
|
|
/*
|
2009-01-28 00:04:00 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS Kernel Streaming
|
|
|
|
* FILE: drivers/wdm/audio/legacy/wdmaud/main.c
|
|
|
|
* PURPOSE: System Audio graph builder
|
|
|
|
* PROGRAMMER: Andrew Greenwood
|
|
|
|
* Johannes Anderwald
|
|
|
|
*/
|
|
|
|
#include "wdmaud.h"
|
2006-12-10 05:43:49 +00:00
|
|
|
|
2009-01-28 00:04:00 +00:00
|
|
|
const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
|
2009-02-20 17:52:47 +00:00
|
|
|
const GUID KSCATEGORY_WDMAUD = {0x3E227E76L, 0x690D, 0x11D2, {0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1}};
|
2006-12-10 05:43:49 +00:00
|
|
|
|
2009-01-28 00:04:00 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2009-02-20 17:52:47 +00:00
|
|
|
WdmAudInstallDevice(
|
|
|
|
IN PDRIVER_OBJECT DriverObject)
|
2009-01-28 00:04:00 +00:00
|
|
|
{
|
2009-02-20 17:52:47 +00:00
|
|
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
|
|
|
|
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
|
2009-01-28 00:04:00 +00:00
|
|
|
PDEVICE_OBJECT DeviceObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
2006-12-10 05:43:49 +00:00
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
DPRINT1("WdmAudInstallDevice called\n");
|
2006-12-10 05:43:49 +00:00
|
|
|
|
2009-01-28 00:04:00 +00:00
|
|
|
Status = IoCreateDevice(DriverObject,
|
|
|
|
sizeof(WDMAUD_DEVICE_EXTENSION),
|
2009-02-20 17:52:47 +00:00
|
|
|
&DeviceName,
|
2009-01-28 00:04:00 +00:00
|
|
|
FILE_DEVICE_KS,
|
|
|
|
0,
|
|
|
|
FALSE,
|
|
|
|
&DeviceObject);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("IoCreateDevice failed with %x\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
/* clear device extension */
|
2009-01-28 00:04:00 +00:00
|
|
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));
|
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
/* register device interfaces */
|
|
|
|
Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
|
|
|
|
IoDeleteDevice(DeviceObject);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize sysaudio device list */
|
2009-01-28 15:24:57 +00:00
|
|
|
InitializeListHead(&DeviceExtension->SysAudioDeviceList);
|
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
/* initialize spinlock */
|
|
|
|
KeInitializeSpinLock(&DeviceExtension->Lock);
|
|
|
|
|
|
|
|
/* find available sysaudio devices */
|
|
|
|
Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
|
2009-01-28 00:04:00 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2009-02-20 17:52:47 +00:00
|
|
|
DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
|
|
|
|
IoDeleteSymbolicLink(&SymlinkName);
|
2009-01-28 00:04:00 +00:00
|
|
|
IoDeleteDevice(DeviceObject);
|
|
|
|
return Status;
|
|
|
|
}
|
2009-02-20 17:52:47 +00:00
|
|
|
/* allocate ks device header */
|
|
|
|
Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2009-01-28 00:04:00 +00:00
|
|
|
{
|
2009-02-20 17:52:47 +00:00
|
|
|
DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
|
|
|
|
IoDeleteSymbolicLink(&SymlinkName);
|
|
|
|
IoDeleteDevice(DeviceObject);
|
|
|
|
return Status;
|
2009-01-28 00:04:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
|
|
|
|
DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
WdmAudUnload(
|
|
|
|
IN PDRIVER_OBJECT driver)
|
|
|
|
{
|
2009-02-20 17:52:47 +00:00
|
|
|
DPRINT1("WdmAudUnload called\n");
|
2009-01-28 00:04:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
WdmAudPnp(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp)
|
2006-12-10 05:43:49 +00:00
|
|
|
{
|
2009-01-28 00:04:00 +00:00
|
|
|
PIO_STACK_LOCATION IrpStack;
|
|
|
|
|
2009-04-03 17:06:16 +00:00
|
|
|
DPRINT("WdmAudPnp called\n");
|
2009-01-28 00:04:00 +00:00
|
|
|
|
|
|
|
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
|
|
|
|
if (IrpStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
|
|
|
|
{
|
|
|
|
Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
|
|
|
|
return KsDefaultDispatchPnp(DeviceObject, Irp);
|
|
|
|
}
|
|
|
|
return KsDefaultDispatchPnp(DeviceObject, Irp);
|
|
|
|
}
|
|
|
|
|
2006-12-10 05:43:49 +00:00
|
|
|
|
2009-01-28 00:04:00 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
WdmAudCreate(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp)
|
2006-12-10 05:43:49 +00:00
|
|
|
{
|
2009-01-28 00:04:00 +00:00
|
|
|
NTSTATUS Status;
|
2009-02-20 17:52:47 +00:00
|
|
|
|
|
|
|
PIO_STACK_LOCATION IoStack;
|
2009-02-21 20:18:44 +00:00
|
|
|
PWDMAUD_CLIENT pClient;
|
2009-02-20 17:52:47 +00:00
|
|
|
|
2009-01-28 00:04:00 +00:00
|
|
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
2009-04-03 17:06:16 +00:00
|
|
|
DPRINT("WdmAudCreate\n");
|
2009-01-28 00:04:00 +00:00
|
|
|
|
|
|
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
2006-12-10 05:43:49 +00:00
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
#if KS_IMPLEMENTED
|
2009-01-28 00:04:00 +00:00
|
|
|
Status = KsReferenceSoftwareBusObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2006-12-10 05:43:49 +00:00
|
|
|
{
|
2009-01-28 00:04:00 +00:00
|
|
|
DPRINT1("KsReferenceSoftwareBusObject failed with %x\n", Status);
|
|
|
|
return Status;
|
2006-12-10 05:43:49 +00:00
|
|
|
}
|
2009-01-28 00:04:00 +00:00
|
|
|
#endif
|
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
Status = WdmAudOpenSysaudio(DeviceObject, &pClient);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2009-01-28 15:24:57 +00:00
|
|
|
{
|
2009-02-20 17:52:47 +00:00
|
|
|
DPRINT1("Failed to open sysaudio!\n");
|
|
|
|
if (pClient)
|
|
|
|
ExFreePool(pClient);
|
2009-01-28 15:24:57 +00:00
|
|
|
}
|
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
ASSERT(IoStack->FileObject);
|
2009-01-28 15:24:57 +00:00
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
/* store client context in file object */
|
|
|
|
IoStack->FileObject->FsContext = pClient;
|
|
|
|
Status = STATUS_SUCCESS;
|
2009-01-28 00:04:00 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
WdmAudClose(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp)
|
|
|
|
{
|
2009-04-03 17:06:16 +00:00
|
|
|
DPRINT("WdmAudClose\n");
|
2009-01-28 00:04:00 +00:00
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
#if KS_IMPLEMENTED
|
2009-01-28 00:04:00 +00:00
|
|
|
Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2009-02-20 17:52:47 +00:00
|
|
|
if (DeviceExtension->SysAudioNotification)
|
|
|
|
Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
|
2009-01-28 00:04:00 +00:00
|
|
|
}
|
2009-02-20 17:52:47 +00:00
|
|
|
#endif
|
2009-01-28 00:04:00 +00:00
|
|
|
|
2009-02-23 23:24:58 +00:00
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
2009-01-28 00:04:00 +00:00
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-02-23 23:24:58 +00:00
|
|
|
return STATUS_SUCCESS;
|
2006-12-10 05:43:49 +00:00
|
|
|
}
|
|
|
|
|
2009-01-28 00:04:00 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
WdmAudCleanup(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp)
|
2006-12-10 05:43:49 +00:00
|
|
|
{
|
2009-02-22 18:58:51 +00:00
|
|
|
PIO_STACK_LOCATION IoStack;
|
|
|
|
WDMAUD_CLIENT *pClient;
|
|
|
|
ULONG Index;
|
|
|
|
|
2009-04-03 17:06:16 +00:00
|
|
|
DPRINT("WdmAudCleanup\n");
|
2009-02-22 18:58:51 +00:00
|
|
|
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
|
|
|
|
pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext;
|
|
|
|
|
|
|
|
if (pClient)
|
|
|
|
{
|
|
|
|
for (Index = 0; Index < pClient->NumPins; Index++)
|
2009-02-25 15:55:21 +00:00
|
|
|
{
|
2009-06-19 10:50:19 +00:00
|
|
|
DPRINT("Index %u Pin %p Type %x\n", Index, pClient->hPins[Index].Handle, pClient->hPins[Index].Type);
|
2009-06-08 21:37:20 +00:00
|
|
|
if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE)
|
2009-02-25 15:55:21 +00:00
|
|
|
{
|
2009-06-08 21:37:20 +00:00
|
|
|
ZwClose(pClient->hPins[Index].Handle);
|
2009-02-25 15:55:21 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-22 18:58:51 +00:00
|
|
|
|
|
|
|
if (pClient->hPins)
|
|
|
|
{
|
|
|
|
ExFreePool(pClient->hPins);
|
|
|
|
}
|
|
|
|
|
|
|
|
ExFreePool(pClient);
|
|
|
|
IoStack->FileObject->FsContext = NULL;
|
|
|
|
}
|
2009-01-28 00:04:00 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
2009-04-03 17:06:16 +00:00
|
|
|
DPRINT("WdmAudCleanup complete\n");
|
2009-01-28 00:04:00 +00:00
|
|
|
return STATUS_SUCCESS;
|
2006-12-10 05:43:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-11-30 11:16:55 +00:00
|
|
|
NTSTATUS NTAPI
|
2006-12-10 05:43:49 +00:00
|
|
|
DriverEntry(
|
2009-01-28 00:04:00 +00:00
|
|
|
IN PDRIVER_OBJECT Driver,
|
|
|
|
IN PUNICODE_STRING Registry_path
|
2006-12-10 05:43:49 +00:00
|
|
|
)
|
|
|
|
{
|
2009-02-20 17:52:47 +00:00
|
|
|
DPRINT1("Wdmaud.sys loaded\n");
|
2006-12-10 05:43:49 +00:00
|
|
|
|
2009-01-28 00:04:00 +00:00
|
|
|
Driver->DriverUnload = WdmAudUnload;
|
|
|
|
|
|
|
|
|
|
|
|
Driver->MajorFunction[IRP_MJ_CREATE] = WdmAudCreate;
|
|
|
|
Driver->MajorFunction[IRP_MJ_CLOSE] = WdmAudClose;
|
|
|
|
Driver->MajorFunction[IRP_MJ_PNP] = WdmAudPnp;
|
|
|
|
Driver->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
|
|
|
|
Driver->MajorFunction[IRP_MJ_CLEANUP] = WdmAudCleanup;
|
|
|
|
Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl;
|
2009-03-06 19:06:21 +00:00
|
|
|
Driver->MajorFunction[IRP_MJ_WRITE] = WdmAudWrite;
|
2009-01-28 00:04:00 +00:00
|
|
|
Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
|
2006-12-10 05:43:49 +00:00
|
|
|
|
2009-02-20 17:52:47 +00:00
|
|
|
return WdmAudInstallDevice(Driver);
|
2006-12-10 05:43:49 +00:00
|
|
|
}
|