[ros-diffs] [janderwald] 43129: - Rewrite mixer enumeration functions - WDMAUD should reports a mixer device each time it sees a KSNODETYPE_ADC / KSNODETYPE_DAC

janderwald at svn.reactos.org janderwald at svn.reactos.org
Thu Sep 24 16:54:58 CEST 2009


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/wdmaud/mixer.c?rev=43129&r1=43128&r2=43129&view=diff
==============================================================================
--- 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/wdmaud/wdmaud.h?rev=43129&r1=43128&r2=43129&view=diff
==============================================================================
--- 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




More information about the Ros-diffs mailing list