mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:42:57 +00:00
[WDMAUD_KERNEL]
- Implement kernel side of notifying clients of volume / mute control changes svn path=/trunk/; revision=44122
This commit is contained in:
parent
a8286c3821
commit
61887111ab
6 changed files with 296 additions and 41 deletions
|
@ -372,6 +372,8 @@ WdmAudDeviceControl(
|
||||||
return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
||||||
case IOCTL_QUERYDEVICEINTERFACESTRING:
|
case IOCTL_QUERYDEVICEINTERFACESTRING:
|
||||||
return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo);
|
return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo);
|
||||||
|
case IOCTL_GET_MIXER_EVENT:
|
||||||
|
return WdmAudGetMixerEvent(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
||||||
case IOCTL_GETPOS:
|
case IOCTL_GETPOS:
|
||||||
case IOCTL_GETDEVID:
|
case IOCTL_GETDEVID:
|
||||||
case IOCTL_GETVOLUME:
|
case IOCTL_GETVOLUME:
|
||||||
|
|
|
@ -205,22 +205,41 @@ WdmAudOpenSysaudio(
|
||||||
PWDMAUD_CLIENT Client;
|
PWDMAUD_CLIENT Client;
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
if (!DeviceExtension->NumSysAudioDevices)
|
if (!DeviceExtension->NumSysAudioDevices)
|
||||||
|
{
|
||||||
|
/* wdmaud failed to open sysaudio */
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
ASSERT(!IsListEmpty(&DeviceExtension->SysAudioDeviceList));
|
ASSERT(!IsListEmpty(&DeviceExtension->SysAudioDeviceList));
|
||||||
|
|
||||||
|
/* allocate client context struct */
|
||||||
Client = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_CLIENT));
|
Client = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_CLIENT));
|
||||||
|
|
||||||
|
/* check for allocation failure */
|
||||||
if (!Client)
|
if (!Client)
|
||||||
{
|
{
|
||||||
|
/* not enough memory */
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* zero client context struct */
|
||||||
RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT));
|
RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT));
|
||||||
|
|
||||||
|
/* initialize mixer event list */
|
||||||
|
InitializeListHead(&Client->MixerEventList);
|
||||||
|
|
||||||
|
/* store result */
|
||||||
*pClient = Client;
|
*pClient = Client;
|
||||||
|
|
||||||
|
/* insert client into list */
|
||||||
|
ExInterlockedInsertTailList(&DeviceExtension->WdmAudClientList, &Client->Entry, &DeviceExtension->Lock);
|
||||||
|
|
||||||
|
/* done */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ WdmAudInstallDevice(
|
||||||
/* initialize sysaudio device list */
|
/* initialize sysaudio device list */
|
||||||
InitializeListHead(&DeviceExtension->SysAudioDeviceList);
|
InitializeListHead(&DeviceExtension->SysAudioDeviceList);
|
||||||
|
|
||||||
|
/* initialize client context device list */
|
||||||
|
InitializeListHead(&DeviceExtension->WdmAudClientList);
|
||||||
|
|
||||||
/* initialize spinlock */
|
/* initialize spinlock */
|
||||||
KeInitializeSpinLock(&DeviceExtension->Lock);
|
KeInitializeSpinLock(&DeviceExtension->Lock);
|
||||||
|
|
||||||
|
@ -123,14 +126,11 @@ WdmAudCreate(
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PWDMAUD_CLIENT pClient;
|
PWDMAUD_CLIENT pClient;
|
||||||
|
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DPRINT("WdmAudCreate\n");
|
/* get device extension */
|
||||||
|
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
#if KS_IMPLEMENTED
|
#if KS_IMPLEMENTED
|
||||||
|
@ -146,8 +146,12 @@ WdmAudCreate(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to open sysaudio!\n");
|
DPRINT1("Failed to open sysaudio!\n");
|
||||||
if (pClient)
|
|
||||||
ExFreePool(pClient);
|
/* complete and forget */
|
||||||
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
/* done */
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
@ -170,8 +174,7 @@ WdmAudClose(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
DPRINT("WdmAudClose\n");
|
/* nothing to do complete request */
|
||||||
|
|
||||||
#if KS_IMPLEMENTED
|
#if KS_IMPLEMENTED
|
||||||
Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
|
Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
|
||||||
|
|
||||||
|
@ -186,6 +189,7 @@ WdmAudClose(
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
/* done */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,45 +200,67 @@ WdmAudCleanup(
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
WDMAUD_CLIENT *pClient;
|
PWDMAUD_CLIENT pClient;
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
DPRINT("WdmAudCleanup\n");
|
/* get device extension */
|
||||||
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* get current irp stack location */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext;
|
/* sanity check */
|
||||||
|
ASSERT(IoStack->FileObject);
|
||||||
|
|
||||||
if (pClient)
|
/* get client context struct */
|
||||||
{
|
pClient = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(pClient);
|
||||||
|
|
||||||
|
/* acquire client context list lock */
|
||||||
|
KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
|
||||||
|
|
||||||
|
/* remove entry */
|
||||||
|
RemoveEntryList(&pClient->Entry);
|
||||||
|
|
||||||
|
/* release lock */
|
||||||
|
KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
|
||||||
|
|
||||||
|
/* check if all audio pins have been closed */
|
||||||
for (Index = 0; Index < pClient->NumPins; Index++)
|
for (Index = 0; Index < pClient->NumPins; Index++)
|
||||||
{
|
{
|
||||||
DPRINT("Index %u Pin %p Type %x\n", Index, pClient->hPins[Index].Handle, pClient->hPins[Index].Type);
|
DPRINT("Index %u Pin %p Type %x\n", Index, pClient->hPins[Index].Handle, pClient->hPins[Index].Type);
|
||||||
if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE)
|
if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
|
/* found an still open audio pin */
|
||||||
ZwClose(pClient->hPins[Index].Handle);
|
ZwClose(pClient->hPins[Index].Handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* free pin array */
|
||||||
if (pClient->hPins)
|
if (pClient->hPins)
|
||||||
{
|
|
||||||
ExFreePool(pClient->hPins);
|
ExFreePool(pClient->hPins);
|
||||||
}
|
|
||||||
|
|
||||||
|
/* free client context struct */
|
||||||
ExFreePool(pClient);
|
ExFreePool(pClient);
|
||||||
IoStack->FileObject->FsContext = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* clear old client pointer */
|
||||||
|
IoStack->FileObject->FsContext = NULL;
|
||||||
|
|
||||||
|
/* complete request */
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
DPRINT("WdmAudCleanup complete\n");
|
|
||||||
|
/* done */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
NTSTATUS NTAPI
|
|
||||||
DriverEntry(
|
DriverEntry(
|
||||||
IN PDRIVER_OBJECT Driver,
|
IN PDRIVER_OBJECT Driver,
|
||||||
IN PUNICODE_STRING Registry_path
|
IN PUNICODE_STRING Registry_path
|
||||||
|
|
|
@ -49,9 +49,17 @@ typedef struct
|
||||||
LPWSTR DeviceInterfaceString;
|
LPWSTR DeviceInterfaceString;
|
||||||
ULONG DeviceInterfaceStringSize;
|
ULONG DeviceInterfaceStringSize;
|
||||||
}Interface;
|
}Interface;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE hMixer;
|
||||||
|
ULONG NotificationType;
|
||||||
|
ULONG Value;
|
||||||
|
}MixerEvent;
|
||||||
KSSTATE State;
|
KSSTATE State;
|
||||||
ULONG Volume;
|
ULONG Volume;
|
||||||
ULONG FrameSize;
|
ULONG FrameSize;
|
||||||
|
HANDLE hNotifyEvent;
|
||||||
}u;
|
}u;
|
||||||
|
|
||||||
}WDMAUD_DEVICE_INFO, *PWDMAUD_DEVICE_INFO;
|
}WDMAUD_DEVICE_INFO, *PWDMAUD_DEVICE_INFO;
|
||||||
|
@ -336,4 +344,21 @@ typedef struct
|
||||||
METHOD_BUFFERED, \
|
METHOD_BUFFERED, \
|
||||||
FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
|
FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
|
||||||
|
|
||||||
|
/// IOCTL_GET_MIXER_EVENT
|
||||||
|
///
|
||||||
|
/// Description: This IOCTL queries for
|
||||||
|
///
|
||||||
|
/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
|
||||||
|
/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure
|
||||||
|
/// Note: The hDevice member must be set
|
||||||
|
/// Result: The result is returned in the struct MixerInfo
|
||||||
|
/// ReturnCode: STATUS_SUCCESS indicates success
|
||||||
|
|
||||||
|
#define IOCTL_GET_MIXER_EVENT \
|
||||||
|
CTL_CODE(FILE_DEVICE_SOUND, \
|
||||||
|
16, \
|
||||||
|
METHOD_BUFFERED, \
|
||||||
|
FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1770,6 +1770,7 @@ WdmAudControlOpenMixer(
|
||||||
{
|
{
|
||||||
/* re-use pseudo handle */
|
/* re-use pseudo handle */
|
||||||
DeviceInfo->hDevice = (HANDLE)DeviceInfo->DeviceIndex;
|
DeviceInfo->hDevice = (HANDLE)DeviceInfo->DeviceIndex;
|
||||||
|
ClientInfo->hPins[Index].hNotifyEvent = DeviceInfo->u.hNotifyEvent;
|
||||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1787,6 +1788,7 @@ WdmAudControlOpenMixer(
|
||||||
ClientInfo->hPins = Handels;
|
ClientInfo->hPins = Handels;
|
||||||
ClientInfo->hPins[ClientInfo->NumPins].Handle = (HANDLE)DeviceInfo->DeviceIndex;
|
ClientInfo->hPins[ClientInfo->NumPins].Handle = (HANDLE)DeviceInfo->DeviceIndex;
|
||||||
ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE;
|
ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE;
|
||||||
|
ClientInfo->hPins[ClientInfo->NumPins].hNotifyEvent = DeviceInfo->u.hNotifyEvent;
|
||||||
ClientInfo->NumPins++;
|
ClientInfo->NumPins++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2049,11 +2051,95 @@ SetGetControlDetails(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NotifyWdmAudClients(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG NotificationType,
|
||||||
|
IN HANDLE hMixer,
|
||||||
|
IN ULONG Value)
|
||||||
|
{
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
PWDMAUD_CLIENT CurClient;
|
||||||
|
PKEVENT EventObject;
|
||||||
|
PMIXER_EVENT Event;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
ULONG Index;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* acquire client context lock */
|
||||||
|
KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
|
||||||
|
|
||||||
|
/* point to first entry */
|
||||||
|
Entry = DeviceExtension->WdmAudClientList.Flink;
|
||||||
|
|
||||||
|
/* iterate through all clients */
|
||||||
|
while(Entry != &DeviceExtension->WdmAudClientList)
|
||||||
|
{
|
||||||
|
/* get client context */
|
||||||
|
CurClient = (PWDMAUD_CLIENT)CONTAINING_RECORD(Entry, WDMAUD_CLIENT, Entry);
|
||||||
|
|
||||||
|
/* now iterate through all pins and try to find an matching handle */
|
||||||
|
for(Index = 0; Index < CurClient->NumPins; Index++)
|
||||||
|
{
|
||||||
|
if (CurClient->hPins[Index].Handle == hMixer && CurClient->hPins[Index].Type == MIXER_DEVICE_TYPE && CurClient->hPins[Index].hNotifyEvent)
|
||||||
|
{
|
||||||
|
/* found a matching mixer handle and a valid notify event */
|
||||||
|
Status = ObReferenceObjectByHandle(CurClient->hPins[Index].hNotifyEvent, EVENT_MODIFY_STATE, ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Invalid notify event passed %p from client %p\n", CurClient->hPins[Index].hNotifyEvent, CurClient);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate event entry */
|
||||||
|
Event = (PMIXER_EVENT)ExAllocatePool(NonPagedPool, sizeof(MIXER_EVENT));
|
||||||
|
if (!Event)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
ObDereferenceObject(EventObject);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize event entry */
|
||||||
|
Event->hMixer = hMixer;
|
||||||
|
Event->NotificationType = NotificationType;
|
||||||
|
Event->Value = Value;
|
||||||
|
|
||||||
|
/* insert event entry */
|
||||||
|
InsertTailList(&CurClient->MixerEventList, &Event->Entry);
|
||||||
|
|
||||||
|
/* now signal the event */
|
||||||
|
KeSetEvent(EventObject, 0, FALSE);
|
||||||
|
|
||||||
|
/* dereference event */
|
||||||
|
ObDereferenceObject(EventObject);
|
||||||
|
|
||||||
|
/* search next client */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move to next client */
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release client context lock */
|
||||||
|
KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SetGetMuteControlDetails(
|
SetGetMuteControlDetails(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN ULONG DeviceId,
|
IN ULONG DeviceId,
|
||||||
IN ULONG NodeId,
|
IN ULONG NodeId,
|
||||||
|
IN ULONG dwLineID,
|
||||||
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
IN ULONG bSet)
|
IN ULONG bSet)
|
||||||
{
|
{
|
||||||
|
@ -2074,9 +2160,21 @@ SetGetMuteControlDetails(
|
||||||
/* set control details */
|
/* set control details */
|
||||||
Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, MAXULONG, &Value);
|
Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, MAXULONG, &Value);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
/* FIXME SEH */
|
/* FIXME SEH */
|
||||||
if (!bSet)
|
if (!bSet)
|
||||||
|
{
|
||||||
Input->fValue = Value;
|
Input->fValue = Value;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* notify clients of a line change */
|
||||||
|
NotifyWdmAudClients(DeviceObject, MM_MIXM_LINE_CHANGE, DeviceInfo->hDevice, dwLineID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -2147,10 +2245,76 @@ SetGetVolumeControlDetails(
|
||||||
}
|
}
|
||||||
Input->dwValue = VolumeData->InputSteppingDelta * (VolumeData->ValuesCount-1);
|
Input->dwValue = VolumeData->InputSteppingDelta * (VolumeData->ValuesCount-1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* notify clients of a line change */
|
||||||
|
NotifyWdmAudClients(DeviceObject, MM_MIXM_CONTROL_CHANGE, DeviceInfo->hDevice, MixerControl->dwControlID);
|
||||||
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
WdmAudGetMixerEvent(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
|
IN PWDMAUD_CLIENT ClientInfo)
|
||||||
|
{
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PMIXER_EVENT Event = NULL;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* acquire client context lock */
|
||||||
|
KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
|
||||||
|
|
||||||
|
/* point to first entry */
|
||||||
|
Entry = ClientInfo->MixerEventList.Flink;
|
||||||
|
|
||||||
|
while(Entry != &ClientInfo->MixerEventList)
|
||||||
|
{
|
||||||
|
/* get mixer event */
|
||||||
|
Event = (PMIXER_EVENT)CONTAINING_RECORD(Entry, MIXER_EVENT, Entry);
|
||||||
|
|
||||||
|
if (Event->hMixer == DeviceInfo->hDevice)
|
||||||
|
{
|
||||||
|
/* found an event for that particular device */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no match found */
|
||||||
|
Event = NULL;
|
||||||
|
|
||||||
|
/* move to next entry */
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* release client context lock */
|
||||||
|
KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
|
||||||
|
|
||||||
|
if (!Event)
|
||||||
|
{
|
||||||
|
/* no events available */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store event result */
|
||||||
|
DeviceInfo->u.MixerEvent.hMixer = Event->hMixer;
|
||||||
|
DeviceInfo->u.MixerEvent.NotificationType = Event->NotificationType;
|
||||||
|
DeviceInfo->u.MixerEvent.Value = Event->Value;
|
||||||
|
|
||||||
|
/* free event info */
|
||||||
|
ExFreePool(Event);
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
WdmAudSetControlDetails(
|
WdmAudSetControlDetails(
|
||||||
|
@ -2193,7 +2357,7 @@ WdmAudSetControlDetails(
|
||||||
if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
|
if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
|
||||||
{
|
{
|
||||||
/* send the request */
|
/* send the request */
|
||||||
Status = SetGetMuteControlDetails(DeviceObject, MixerLine->DeviceIndex, NodeId, DeviceInfo, TRUE);
|
Status = SetGetMuteControlDetails(DeviceObject, MixerLine->DeviceIndex, NodeId, MixerLine->Line.dwLineID, DeviceInfo, TRUE);
|
||||||
}
|
}
|
||||||
else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
|
else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
|
||||||
{
|
{
|
||||||
|
@ -2245,7 +2409,7 @@ WdmAudGetControlDetails(
|
||||||
if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
|
if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
|
||||||
{
|
{
|
||||||
/* send the request */
|
/* send the request */
|
||||||
Status = SetGetMuteControlDetails(DeviceObject, MixerLine->DeviceIndex, NodeId, DeviceInfo, FALSE);
|
Status = SetGetMuteControlDetails(DeviceObject, MixerLine->DeviceIndex, NodeId, MixerLine->Line.dwLineID, DeviceInfo, FALSE);
|
||||||
}
|
}
|
||||||
else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
|
else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,19 +18,30 @@
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE Handle;
|
LIST_ENTRY Entry;
|
||||||
SOUND_DEVICE_TYPE Type;
|
HANDLE hMixer;
|
||||||
ULONG FilterId;
|
ULONG NotificationType;
|
||||||
ULONG PinId;
|
ULONG Value;
|
||||||
}WDMAUD_HANDLE, *PWDMAUD_HANDLE;
|
}MIXER_EVENT, *PMIXER_EVENT;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
HANDLE Handle;
|
||||||
|
SOUND_DEVICE_TYPE Type;
|
||||||
|
ULONG FilterId;
|
||||||
|
ULONG PinId;
|
||||||
|
HANDLE hNotifyEvent;
|
||||||
|
}WDMAUD_HANDLE, *PWDMAUD_HANDLE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LIST_ENTRY Entry;
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
ULONG NumPins;
|
ULONG NumPins;
|
||||||
WDMAUD_HANDLE * hPins;
|
WDMAUD_HANDLE * hPins;
|
||||||
|
|
||||||
|
LIST_ENTRY MixerEventList;
|
||||||
}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
|
}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -115,7 +126,7 @@ typedef struct
|
||||||
ULONG WaveOutDeviceCount;
|
ULONG WaveOutDeviceCount;
|
||||||
LIST_ENTRY WaveOutList;
|
LIST_ENTRY WaveOutList;
|
||||||
|
|
||||||
|
LIST_ENTRY WdmAudClientList;
|
||||||
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
|
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -243,6 +254,14 @@ WdmAudSetControlDetails(
|
||||||
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
IN PWDMAUD_CLIENT ClientInfo);
|
IN PWDMAUD_CLIENT ClientInfo);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
WdmAudGetMixerEvent(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
|
IN PWDMAUD_CLIENT ClientInfo);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
WdmAudGetControlDetails(
|
WdmAudGetControlDetails(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue