mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:45:53 +00:00
- Rewrite mixer enumeration functions
- WDMAUD should reports a mixer device each time it sees a KSNODETYPE_ADC / KSNODETYPE_DAC svn path=/trunk/; revision=43129
This commit is contained in:
parent
5a4647d276
commit
fee01ee6d4
2 changed files with 180 additions and 103 deletions
|
@ -8,152 +8,224 @@
|
||||||
*/
|
*/
|
||||||
#include "wdmaud.h"
|
#include "wdmaud.h"
|
||||||
|
|
||||||
ULONG
|
const GUID KSNODETYPE_DAC = {0x507AE360L, 0xC554, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
|
||||||
IsVirtualDeviceATopologyFilter(
|
const GUID KSNODETYPE_ADC = {0x4D837FE0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
ULONG VirtualDeviceId)
|
|
||||||
{
|
|
||||||
KSP_PIN Pin;
|
|
||||||
ULONG Count, BytesReturned, Index, NumPins;
|
|
||||||
NTSTATUS Status;
|
|
||||||
KSPIN_COMMUNICATION Communication;
|
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
ULONG MixerPinCount;
|
|
||||||
|
|
||||||
Pin.Property.Set = KSPROPSETID_Sysaudio;
|
ULONG
|
||||||
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
GetSysAudioDeviceCount(
|
||||||
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
KSPROPERTY Pin;
|
||||||
|
ULONG Count, BytesReturned;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* setup the query request */
|
||||||
|
Pin.Set = KSPROPSETID_Sysaudio;
|
||||||
|
Pin.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
||||||
|
Pin.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* query sysaudio for the device count */
|
||||||
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return FALSE;
|
return 0;
|
||||||
|
|
||||||
if (VirtualDeviceId >= Count)
|
return Count;
|
||||||
return FALSE;
|
}
|
||||||
|
|
||||||
/* query number of pins */
|
NTSTATUS
|
||||||
Pin.Reserved = VirtualDeviceId; // see sysaudio
|
OpenSysAudioDeviceByIndex(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG DeviceIndex,
|
||||||
|
IN PHANDLE DeviceHandle,
|
||||||
|
IN PFILE_OBJECT * FileObject)
|
||||||
|
{
|
||||||
|
LPWSTR Device;
|
||||||
|
HANDLE hDevice;
|
||||||
|
ULONG BytesReturned;
|
||||||
|
KSP_PIN Pin;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
/* first check if the device index is within bounds */
|
||||||
|
if (DeviceIndex >= GetSysAudioDeviceCount(DeviceObject))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* setup the query request */
|
||||||
|
Pin.Property.Set = KSPROPSETID_Sysaudio;
|
||||||
|
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME;
|
||||||
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
Pin.Property.Set = KSPROPSETID_Pin;
|
Pin.PinId = DeviceIndex;
|
||||||
Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
|
|
||||||
Pin.PinId = 0;
|
|
||||||
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* query sysaudio for the device path */
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), NULL, 0, &BytesReturned);
|
||||||
|
|
||||||
|
/* check if the request failed */
|
||||||
|
if (Status != STATUS_BUFFER_TOO_SMALL || BytesReturned == 0)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
/* allocate buffer for the device */
|
||||||
|
Device = ExAllocatePool(NonPagedPool, BytesReturned);
|
||||||
|
if (!Device)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* query sysaudio again for the device path */
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), (PVOID)Device, BytesReturned, &BytesReturned);
|
||||||
|
|
||||||
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* enumerate now all pins */
|
|
||||||
MixerPinCount = 0;
|
|
||||||
for(Index = 0; Index < NumPins; Index++)
|
|
||||||
{
|
{
|
||||||
Pin.PinId = Index;
|
/* failed */
|
||||||
Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
|
ExFreePool(Device);
|
||||||
Communication = KSPIN_COMMUNICATION_NONE;
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* get pin communication type */
|
/* now open the device */
|
||||||
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
|
Status = WdmAudOpenSysAudioDevice(Device, &hDevice);
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
|
/* free device buffer */
|
||||||
|
ExFreePool(Device);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
*DeviceHandle = hDevice;
|
||||||
|
|
||||||
|
if (FileObject)
|
||||||
|
{
|
||||||
|
Status = ObReferenceObjectByHandle(hDevice, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)FileObject, NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (Communication == KSPIN_COMMUNICATION_NONE)
|
ZwClose(hDevice);
|
||||||
MixerPinCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MixerPinCount == NumPins)
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
GetFilterNodeTypes(
|
||||||
|
PFILE_OBJECT FileObject,
|
||||||
|
PKSMULTIPLE_ITEM * Item)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG BytesReturned;
|
||||||
|
PKSMULTIPLE_ITEM MultipleItem;
|
||||||
|
KSPROPERTY Property;
|
||||||
|
|
||||||
|
/* setup query request */
|
||||||
|
Property.Id = KSPROPERTY_TOPOLOGY_NODES;
|
||||||
|
Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
Property.Set = KSPROPSETID_Topology;
|
||||||
|
|
||||||
|
/* query for required size */
|
||||||
|
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &BytesReturned);
|
||||||
|
|
||||||
|
/* check for success */
|
||||||
|
if (Status != STATUS_MORE_ENTRIES)
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/* allocate buffer */
|
||||||
|
MultipleItem = (PKSMULTIPLE_ITEM)ExAllocatePool(NonPagedPool, BytesReturned);
|
||||||
|
if (!MultipleItem)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* query for required size */
|
||||||
|
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* filter has no pins which can be instantiated -> topology filter */
|
/* failed */
|
||||||
return TRUE;
|
ExFreePool(MultipleItem);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
*Item = MultipleItem;
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
GetNumOfMixerPinsFromTopologyFilter(
|
CountNodeType(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
PKSMULTIPLE_ITEM MultipleItem,
|
||||||
ULONG VirtualDeviceId)
|
LPGUID NodeType)
|
||||||
{
|
{
|
||||||
KSP_PIN Pin;
|
ULONG Count;
|
||||||
ULONG BytesReturned, Index, NumPins;
|
ULONG Index;
|
||||||
NTSTATUS Status;
|
LPGUID Guid;
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
PKSMULTIPLE_ITEM MultipleItem;
|
|
||||||
PKSTOPOLOGY_CONNECTION Conn;
|
|
||||||
|
|
||||||
Pin.PinId = 0;
|
Count = 0;
|
||||||
Pin.Reserved = VirtualDeviceId;
|
Guid = (LPGUID)(MultipleItem+1);
|
||||||
Pin.Property.Set = KSPROPSETID_Topology;
|
|
||||||
Pin.Property.Id = KSPROPERTY_TOPOLOGY_CONNECTIONS;
|
|
||||||
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
|
||||||
|
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
/* iterate through node type array */
|
||||||
|
for(Index = 0; Index < MultipleItem->Count; Index++)
|
||||||
BytesReturned = 0;
|
|
||||||
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned);
|
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
|
|
||||||
if (!MultipleItem)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
RtlZeroMemory(MultipleItem, BytesReturned);
|
|
||||||
|
|
||||||
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
ExFreePool(MultipleItem);
|
if (IsEqualGUIDAligned(NodeType, Guid))
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Conn = (PKSTOPOLOGY_CONNECTION)(MultipleItem + 1);
|
|
||||||
NumPins = 0;
|
|
||||||
for (Index = 0; Index < MultipleItem->Count; Index++)
|
|
||||||
{
|
|
||||||
if (Conn[Index].ToNode == PCFILTER_NODE)
|
|
||||||
{
|
{
|
||||||
NumPins++;
|
/* found matching guid */
|
||||||
|
Count++;
|
||||||
}
|
}
|
||||||
|
Guid++;
|
||||||
}
|
}
|
||||||
|
return Count;
|
||||||
ExFreePool(MultipleItem);
|
|
||||||
return NumPins;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
GetNumOfMixerDevices(
|
GetNumOfMixerDevices(
|
||||||
IN PDEVICE_OBJECT DeviceObject)
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
KSP_PIN Pin;
|
ULONG DeviceCount, Index, Count;
|
||||||
ULONG Count, BytesReturned, Index, NumPins;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
HANDLE hDevice;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
PKSMULTIPLE_ITEM MultipleItem;
|
||||||
|
|
||||||
Pin.Property.Set = KSPROPSETID_Sysaudio;
|
/* get number of devices */
|
||||||
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
DeviceCount = GetSysAudioDeviceCount(DeviceObject);
|
||||||
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
|
||||||
|
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
if (!DeviceCount)
|
||||||
|
|
||||||
Count = 0;
|
|
||||||
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
|
|
||||||
if (!NT_SUCCESS(Status) || !Count)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
NumPins = 0;
|
Index = 0;
|
||||||
for(Index = 0; Index < Count; Index++)
|
Count = 0;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
if (IsVirtualDeviceATopologyFilter(DeviceObject, Index))
|
/* open the virtual audio device */
|
||||||
{
|
Status = OpenSysAudioDeviceByIndex(DeviceObject, Index, &hDevice, &FileObject);
|
||||||
NumPins += GetNumOfMixerPinsFromTopologyFilter(DeviceObject, Index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NumPins;
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* retrieve all available node types */
|
||||||
|
Status = GetFilterNodeTypes(FileObject, &MultipleItem);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (CountNodeType(MultipleItem, (LPGUID)&KSNODETYPE_DAC))
|
||||||
|
{
|
||||||
|
/* increment (output) mixer count */
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CountNodeType(MultipleItem, (LPGUID)&KSNODETYPE_ADC))
|
||||||
|
{
|
||||||
|
/* increment (input) mixer count */
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
ExFreePool(MultipleItem);
|
||||||
|
}
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
ZwClose(hDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
Index++;
|
||||||
|
}while(Index < DeviceCount);
|
||||||
|
|
||||||
|
return Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -103,4 +103,9 @@ SetIrpIoStatus(
|
||||||
IN NTSTATUS Status,
|
IN NTSTATUS Status,
|
||||||
IN ULONG Length);
|
IN ULONG Length);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudOpenSysAudioDevice(
|
||||||
|
IN LPWSTR DeviceName,
|
||||||
|
OUT PHANDLE Handle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue