[ros-diffs] [janderwald] 39783: - Implement enumerating devices for wave in devices - Implement mapping virtual device id to real filter id and pin id - Wdmaud can now select the correct pin

janderwald at svn.reactos.org janderwald at svn.reactos.org
Fri Feb 27 13:22:19 CET 2009


Author: janderwald
Date: Fri Feb 27 15:22:18 2009
New Revision: 39783

URL: http://svn.reactos.org/svn/reactos?rev=39783&view=rev
Log:
- Implement enumerating devices for wave in devices
- Implement mapping virtual device id to real filter id and pin id
- Wdmaud can now select the correct pin

Modified:
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c?rev=39783&r1=39782&r2=39783&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Fri Feb 27 15:22:18 2009
@@ -32,6 +32,99 @@
 }
 
 NTSTATUS
+GetFilterIdAndPinId(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo,
+    IN PULONG FilterId,
+    IN PULONG PinId)
+{
+    KSP_PIN Pin;
+    ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
+    NTSTATUS Status;
+    KSPIN_COMMUNICATION Communication;
+    KSPIN_DATAFLOW DataFlow;
+
+    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
+    {
+        DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    Pin.Property.Set = KSPROPSETID_Sysaudio;
+    Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
+    Pin.Property.Flags = KSPROPERTY_TYPE_GET;
+
+    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
+    if (!NT_SUCCESS(Status))
+        return STATUS_UNSUCCESSFUL;
+
+    Result = 0;
+    for(Index = 0; Index < Count; Index++)
+    {
+        /* query number of pins */
+        Pin.Reserved = Index; // see sysaudio
+        Pin.Property.Flags = KSPROPERTY_TYPE_GET;
+        Pin.Property.Set = KSPROPSETID_Pin;
+        Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
+        Pin.PinId = 0;
+
+        Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned);
+        if (NT_SUCCESS(Status))
+        {
+            /* enumerate now all pins */
+            for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
+            {
+                Pin.PinId = SubIndex;
+                Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
+                Communication = KSPIN_COMMUNICATION_NONE;
+
+                /* get pin communication type */
+                KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
+
+                Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
+                DataFlow = 0;
+
+                /* get pin dataflow type */
+                KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
+
+                if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+                {
+                    if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
+                    {
+                        if(DeviceInfo->DeviceIndex == Result)
+                        {
+                            /* found the index */
+                            *FilterId = Index;
+                            *PinId = SubIndex;
+                            return STATUS_SUCCESS;
+                        }
+
+                        Result++;
+                    }
+                }
+                else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
+                {
+                    if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
+                    {
+                        if(DeviceInfo->DeviceIndex == Result)
+                        {
+                            /* found the index */
+                            *FilterId = Index;
+                            *PinId = SubIndex;
+                            return STATUS_SUCCESS;
+                        }
+                        Result++;
+                    }
+                }
+            }
+        }
+    }
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
 WdmAudControlOpen(
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp,
@@ -46,12 +139,22 @@
     KSPIN_CONNECT * PinConnect;
     ULONG Length;
     KSDATAFORMAT_WAVEFORMATEX * DataFormat;
-
-    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
+    ULONG FilterId;
+    ULONG PinId;
+
+    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
     {
         DPRINT1("FIXME: only waveout devices are supported\n");
         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
     }
+
+    Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Invalid device index %u\n", DeviceInfo->DeviceIndex);
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+    }
+
 
     Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
     InstanceInfo = ExAllocatePool(NonPagedPool, Length);
@@ -65,7 +168,7 @@
     InstanceInfo->Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO;
     InstanceInfo->Property.Flags = KSPROPERTY_TYPE_SET;
     InstanceInfo->Flags = 0;
-    InstanceInfo->DeviceNumber = DeviceInfo->DeviceIndex;
+    InstanceInfo->DeviceNumber = FilterId;
 
     Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned);
 
@@ -101,7 +204,7 @@
     PinConnect->Medium.Set = KSMEDIUMSETID_Standard;
     PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
     PinConnect->Medium.Flags = 0;
-    PinConnect->PinId = 0; //FIXME
+    PinConnect->PinId = PinId;
     PinConnect->PinToHandle = ClientInfo->hSysAudio;
     PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
     PinConnect->Priority.PrioritySubClass = 1;
@@ -163,21 +266,74 @@
     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
     IN  PWDMAUD_CLIENT ClientInfo)
 {
-    KSPROPERTY Property;
-    ULONG Result, BytesReturned;
+    KSP_PIN Pin;
+    ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
     NTSTATUS Status;
-
-    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
-    {
-        DPRINT1("FIXME: only waveout devices are supported\n");
+    KSPIN_COMMUNICATION Communication;
+    KSPIN_DATAFLOW DataFlow;
+
+    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
+    {
+        DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
     }
 
-    Property.Set = KSPROPSETID_Sysaudio;
-    Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
-    Property.Flags = KSPROPERTY_TYPE_GET;
-
-    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Result, sizeof(ULONG), &BytesReturned);
+    Pin.Property.Set = KSPROPSETID_Sysaudio;
+    Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
+    Pin.Property.Flags = KSPROPERTY_TYPE_GET;
+
+    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status);
+        return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+    }
+    Result = 0;
+    /* now enumerate all available filters */
+    for(Index = 0; Index < Count; Index++)
+    {
+        /* query number of pins */
+        Pin.Reserved = Index; // see sysaudio
+        Pin.Property.Flags = KSPROPERTY_TYPE_GET;
+        Pin.Property.Set = KSPROPSETID_Pin;
+        Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
+        Pin.PinId = 0;
+
+        Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned);
+        if (NT_SUCCESS(Status))
+        {
+            /* enumerate now all pins */
+            for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
+            {
+                Pin.PinId = SubIndex;
+                Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
+                Communication = KSPIN_COMMUNICATION_NONE;
+
+                /* get pin communication type */
+                KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
+
+                Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
+                DataFlow = 0;
+
+                /* get pin dataflow type */
+                KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
+
+                if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+                {
+                    if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
+                        Result++;
+                }
+                else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
+                {
+                    if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
+                        Result++;
+                }
+            }
+        }
+		else
+			DPRINT1("KSPROPERTY_PIN_CTYPES index %u failed with %x\n", Index, Status);
+    }
+
 
     if (NT_SUCCESS(Status))
         DeviceInfo->DeviceCount = Result;
@@ -200,12 +356,6 @@
     NTSTATUS Status;
     ULONG BytesReturned;
     PFILE_OBJECT FileObject;
-
-    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
-    {
-        DPRINT1("FIXME: only waveout devices are supported\n");
-        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-    }
 
     Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
     if (!NT_SUCCESS(Status))
@@ -378,16 +528,24 @@
     ULONG BytesReturned;
     PKSDATARANGE_AUDIO DataRangeAudio;
     PKSDATARANGE DataRange;
-
     ULONG Index;
     ULONG wChannels = 0;
     ULONG dwFormats = 0;
     ULONG dwSupport = 0;
+    ULONG FilterId;
     ULONG PinId;
 
     DPRINT("WdmAudCapabilities entered\n");
 
-    PinProperty.PinId = DeviceInfo->DeviceIndex; // used as index of the virtual audio device
+
+    Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Invalid device index provided %u\n", DeviceInfo->DeviceIndex);
+        return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+    }
+
+    PinProperty.PinId = FilterId;
     PinProperty.Property.Set = KSPROPSETID_Sysaudio;
     PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_COMPONENT_ID;
     PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
@@ -400,19 +558,12 @@
         DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7;
         DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version, ComponentId.Revision);
     }
-
-    //FIXME
-    // Reserved index defines the audio device index
-    // pin offset should be first determined
-    // by determing the pin type of the target filter
-    PinId = 0;
 
     PinProperty.Reserved = DeviceInfo->DeviceIndex;
     PinProperty.PinId = PinId;
     PinProperty.Property.Set = KSPROPSETID_Pin;
     PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES;
     PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
-
 
     BytesReturned = 0;
     Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned);



More information about the Ros-diffs mailing list