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/wd... ============================================================================== --- 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);