Author: janderwald
Date: Thu Sep 24 16:54:58 2009
New Revision: 43129
URL:
http://svn.reactos.org/svn/reactos?rev=43129&view=rev
Log:
- Rewrite mixer enumeration functions
- WDMAUD should reports a mixer device each time it sees a KSNODETYPE_ADC /
KSNODETYPE_DAC
Modified:
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c [iso-8859-1] Thu Sep 24 16:54:58
2009
@@ -8,152 +8,224 @@
*/
#include "wdmaud.h"
+const GUID KSNODETYPE_DAC = {0x507AE360L, 0xC554, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9,
0x25, 0x5A, 0xC1}};
+const GUID KSNODETYPE_ADC = {0x4D837FE0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9,
0x25, 0x5A, 0xC1}};
+
ULONG
-IsVirtualDeviceATopologyFilter(
+GetSysAudioDeviceCount(
+ 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;
+
+ /* query sysaudio for the device count */
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG),
&BytesReturned);
+ if (!NT_SUCCESS(Status))
+ return 0;
+
+ return Count;
+}
+
+NTSTATUS
+OpenSysAudioDeviceByIndex(
IN PDEVICE_OBJECT DeviceObject,
- ULONG VirtualDeviceId)
-{
+ IN ULONG DeviceIndex,
+ IN PHANDLE DeviceHandle,
+ IN PFILE_OBJECT * FileObject)
+{
+ LPWSTR Device;
+ HANDLE hDevice;
+ ULONG BytesReturned;
KSP_PIN Pin;
- ULONG Count, BytesReturned, Index, NumPins;
- NTSTATUS Status;
- KSPIN_COMMUNICATION Communication;
+ NTSTATUS Status;
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- ULONG MixerPinCount;
-
+
+ /* 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_COUNT;
+ Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME;
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
+ Pin.PinId = DeviceIndex;
+
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG),
&BytesReturned);
- if (!NT_SUCCESS(Status))
- return FALSE;
-
- if (VirtualDeviceId >= Count)
- return FALSE;
-
- /* query number of pins */
- Pin.Reserved = VirtualDeviceId; // see sysaudio
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
- Pin.Property.Set = KSPROPSETID_Pin;
- Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
- Pin.PinId = 0;
-
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG),
&BytesReturned);
- if (!NT_SUCCESS(Status))
- return FALSE;
-
- /* enumerate now all pins */
- MixerPinCount = 0;
- for(Index = 0; Index < NumPins; Index++)
- {
- Pin.PinId = Index;
- Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
- Communication = KSPIN_COMMUNICATION_NONE;
-
- /* get pin communication type */
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication,
sizeof(KSPIN_COMMUNICATION), &BytesReturned);
- if (NT_SUCCESS(Status))
- {
- if (Communication == KSPIN_COMMUNICATION_NONE)
- MixerPinCount++;
- }
-
- }
-
- if (MixerPinCount == NumPins)
- {
- /* filter has no pins which can be instantiated -> topology filter */
- return TRUE;
- }
-
- return FALSE;
+ /* 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);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ ExFreePool(Device);
+ return Status;
+ }
+
+ /* now open the device */
+ Status = WdmAudOpenSysAudioDevice(Device, &hDevice);
+
+ /* 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))
+ {
+ ZwClose(hDevice);
+ }
+ }
+
+ 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))
+ {
+ /* failed */
+ ExFreePool(MultipleItem);
+ return Status;
+ }
+
+ *Item = MultipleItem;
+ return Status;
}
ULONG
-GetNumOfMixerPinsFromTopologyFilter(
- IN PDEVICE_OBJECT DeviceObject,
- ULONG VirtualDeviceId)
-{
- KSP_PIN Pin;
- ULONG BytesReturned, Index, NumPins;
- NTSTATUS Status;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- PKSMULTIPLE_ITEM MultipleItem;
- PKSTOPOLOGY_CONNECTION Conn;
-
- Pin.PinId = 0;
- Pin.Reserved = VirtualDeviceId;
- Pin.Property.Set = KSPROPSETID_Topology;
- Pin.Property.Id = KSPROPERTY_TOPOLOGY_CONNECTIONS;
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- 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);
- return 0;
- }
-
- Conn = (PKSTOPOLOGY_CONNECTION)(MultipleItem + 1);
- NumPins = 0;
- for (Index = 0; Index < MultipleItem->Count; Index++)
- {
- if (Conn[Index].ToNode == PCFILTER_NODE)
- {
- NumPins++;
- }
- }
-
- ExFreePool(MultipleItem);
- return NumPins;
+CountNodeType(
+ PKSMULTIPLE_ITEM MultipleItem,
+ LPGUID NodeType)
+{
+ ULONG Count;
+ ULONG Index;
+ LPGUID Guid;
+
+ Count = 0;
+ Guid = (LPGUID)(MultipleItem+1);
+
+ /* iterate through node type array */
+ for(Index = 0; Index < MultipleItem->Count; Index++)
+ {
+ if (IsEqualGUIDAligned(NodeType, Guid))
+ {
+ /* found matching guid */
+ Count++;
+ }
+ Guid++;
+ }
+ return Count;
}
ULONG
GetNumOfMixerDevices(
IN PDEVICE_OBJECT DeviceObject)
{
- KSP_PIN Pin;
- ULONG Count, BytesReturned, Index, NumPins;
- NTSTATUS Status;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
-
- Pin.Property.Set = KSPROPSETID_Sysaudio;
- Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
+ ULONG DeviceCount, Index, Count;
+ NTSTATUS Status;
+ HANDLE hDevice;
+ PFILE_OBJECT FileObject;
+ PKSMULTIPLE_ITEM MultipleItem;
+
+ /* get number of devices */
+ DeviceCount = GetSysAudioDeviceCount(DeviceObject);
+
+ if (!DeviceCount)
+ return 0;
+
+ Index = 0;
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;
-
- NumPins = 0;
- for(Index = 0; Index < Count; Index++)
- {
- if (IsVirtualDeviceATopologyFilter(DeviceObject, Index))
- {
- NumPins += GetNumOfMixerPinsFromTopologyFilter(DeviceObject, Index);
- }
- }
-
- return NumPins;
+ do
+ {
+ /* open the virtual audio device */
+ Status = OpenSysAudioDeviceByIndex(DeviceObject, Index, &hDevice,
&FileObject);
+
+ 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
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Thu Sep 24
16:54:58 2009
@@ -103,4 +103,9 @@
IN NTSTATUS Status,
IN ULONG Length);
+NTSTATUS
+WdmAudOpenSysAudioDevice(
+ IN LPWSTR DeviceName,
+ OUT PHANDLE Handle);
+
#endif