Author: janderwald Date: Mon Feb 23 14:13:35 2009 New Revision: 39719
URL: http://svn.reactos.org/svn/reactos?rev=39719&view=rev Log: - Extend test prog for quering capabilities - Store PCFILTER in subdevice filter - Call driver provided property request handlers - partly implement waveout get capabilties (WIP) - remove definitions for waveoutcaps, auxcaps, waveincaps, they are defined in mmsystem.h
Modified: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
Modified: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/a... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c [iso-8859-1] Mon Feb 23 14:13:35 2009 @@ -47,6 +47,7 @@
DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE;
+ Status = DeviceIoControl(hWdmAud, IOCTL_GETNUMDEVS_TYPE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
if (!Status) @@ -74,6 +75,15 @@ DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4; DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
+ Status = DeviceIoControl(hWdmAud, IOCTL_GETCAPABILITIES, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); + + if (!Status) + { + if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0) + { + printf("Failed to get iocaps %lx\n", GetLastError()); + } + }
Status = DeviceIoControl(hWdmAud, IOCTL_OPEN_WDMAUD, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); @@ -86,6 +96,9 @@ return -1; } } + + +
// // Allocate a buffer for 1 second @@ -119,7 +132,7 @@ return -1; } } - + // // Play our 1-second buffer // @@ -136,6 +149,8 @@ } }
+ printf("WDMAUD: Played buffer\n"); + DeviceInfo.State = KSSTATE_STOP; Status = DeviceIoControl(hWdmAud, IOCTL_SETDEVICE_STATE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); if (!Status) @@ -147,6 +162,9 @@ return -1; } } + printf("WDMAUD: STOPPED\n"); CloseHandle(hWdmAud); + CloseHandle(&Overlapped.hEvent); + printf("WDMAUD: COMPLETE\n"); return 0; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Mon Feb 23 14:13:35 2009 @@ -128,6 +128,8 @@ GUID *Interfaces; KSPIN_FACTORY Factory; KSPROPERTY_SET_LIST FilterPropertySet; + + PPCFILTER_DESCRIPTOR DeviceDescriptor; }SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
#undef INTERFACE
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c [iso-8859-1] Mon Feb 23 14:13:35 2009 @@ -133,27 +133,55 @@ PFNKSHANDLER PropertyHandler = NULL; UNICODE_STRING GuidString; NTSTATUS Status = STATUS_UNSUCCESSFUL; + PCPROPERTY_REQUEST PropertyRequest;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; ASSERT(Property);
- DPRINT1("Num of Property Sets %u\n", Descriptor->FilterPropertySet.FreeKsPropertySetOffset); + /* check properties provided by the driver */ + if (Descriptor->DeviceDescriptor->AutomationTable) + { + for(Index = 0; Index < Descriptor->DeviceDescriptor->AutomationTable->PropertyCount; Index++) + { + if (IsEqualGUID(&Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Set, &Property->Set)) + { + if (Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Id == Property->Id) + { + if(Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Flags & Property->Flags) + { + RtlZeroMemory(&PropertyRequest, sizeof(PCPROPERTY_REQUEST)); + PropertyRequest.PropertyItem = &Descriptor->DeviceDescriptor->AutomationTable->Properties[Index]; + PropertyRequest.Verb = Property->Flags; + PropertyRequest.Value = Irp->UserBuffer; + PropertyRequest.ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; + PropertyRequest.Irp = Irp; + + DPRINT("Calling handler %p\n", Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Handler); + Status = Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Handler(&PropertyRequest); + + Irp->IoStatus.Information = PropertyRequest.ValueSize; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + } + } + } + } + + DPRINT("Num of Property Sets %u\n", Descriptor->FilterPropertySet.FreeKsPropertySetOffset); for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++) { - RtlStringFromGUID ((GUID*)Descriptor->FilterPropertySet.Properties[Index].Set, &GuidString); - DPRINT1("Current GUID %S\n", GuidString.Buffer); - RtlFreeUnicodeString(&GuidString); - if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set)) { - DPRINT1("Found Property Set Properties %u\n", Descriptor->FilterPropertySet.Properties[Index].PropertiesCount); + DPRINT("Found Property Set Properties %u\n", Descriptor->FilterPropertySet.Properties[Index].PropertiesCount); for(ItemIndex = 0; ItemIndex < Descriptor->FilterPropertySet.Properties[Index].PropertiesCount; ItemIndex++) { if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].PropertyId == Property->Id) { - DPRINT1("Found property set identifier %u\n", Property->Id); + DPRINT("Found property set identifier %u\n", Property->Id); if (Property->Flags & KSPROPERTY_TYPE_SET) PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].SetPropertyHandler;
@@ -165,6 +193,7 @@ /* too small input buffer */ Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty; Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_BUFFER_TOO_SMALL; }
@@ -173,19 +202,20 @@ /* too small output buffer */ Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData; Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_BUFFER_TOO_SMALL; }
if (PropertyHandler) { KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)Descriptor; - DPRINT1("Calling property handler %p\n", PropertyHandler); + DPRINT("Calling property handler %p\n", PropertyHandler); Status = PropertyHandler(Irp, Property, Irp->UserBuffer); }
/* the information member is set by the handler */ Irp->IoStatus.Status = Status; - DPRINT1("Result %x\n", Status); + DPRINT("Result %x\n", Status); IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c [iso-8859-1] Mon Feb 23 14:13:35 2009 @@ -204,7 +204,7 @@ Descriptor->Factory.Instances[Index].MinFilterInstanceCount = FilterDescription->Pins[Index].MinFilterInstanceCount; } } - + Descriptor->DeviceDescriptor = FilterDescription; *OutSubdeviceDescriptor = Descriptor; return STATUS_SUCCESS;
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] Mon Feb 23 14:13:35 2009 @@ -16,7 +16,6 @@ const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; -
NTSTATUS SetIrpIoStatus( @@ -324,17 +323,140 @@ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, (PVOID)Packet, sizeof(KSSTREAM_HEADER), NULL, 0, &BytesReturned);
DPRINT1("KsSynchronousIoControlDevice result %x\n", Status); - - IoMarkIrpPending(Irp); - Irp->IoStatus.Information = DeviceInfo->BufferSize; - Irp->IoStatus.Status = Status; - ExFreePool(Buffer);
- return Status; -} - - + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); +} + +ULONG +CheckFormatSupport( + IN PKSDATARANGE_AUDIO DataRangeAudio, + ULONG SampleFrequency, + ULONG Mono8Bit, + ULONG Stereo8Bit, + ULONG Mono16Bit, + ULONG Stereo16Bit) +{ + ULONG Result = 0; + + if (DataRangeAudio->MinimumSampleFrequency <= SampleFrequency && DataRangeAudio->MaximumSampleFrequency >= SampleFrequency) + { + if (DataRangeAudio->MinimumBitsPerSample <= 8 && DataRangeAudio->MaximumBitsPerSample >= 8) + { + Result |= Mono8Bit; + if (DataRangeAudio->MaximumChannels >= 2) + { + Result |= Stereo8Bit; + } + } + + if (DataRangeAudio->MaximumBitsPerSample <= 16 && DataRangeAudio->MaximumBitsPerSample >= 16) + { + Result |= Monot16; + if (DataRangeAudio->MaximumChannels >= 2) + { + Result |= Stereo8Bit; + } + } + } + return Result; + +} + +NTSTATUS +WdmAudCapabilities( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + KSP_PIN PinProperty; + KSPROPERTY Property; + KSCOMPONENTID ComponentId; + KSMULTIPLE_ITEM * MultipleItem; + ULONG BytesReturned; + PKSDATARANGE_AUDIO DataRangeAudio; + PKSDATARANGE DataRange; + NTSTATUS Status; + ULONG Index; + ULONG wChannels = 0; + ULONG dwFormats = 0; + ULONG dwSupport = 0; + + Property.Set = KSPROPSETID_General; + Property.Id = KSPROPERTY_GENERAL_COMPONENTID; + Property.Flags = KSPROPERTY_TYPE_GET; + + RtlZeroMemory(&ComponentId, sizeof(KSCOMPONENTID)); + + Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); + if (!NT_SUCCESS(Status)) + { + DPRINT1("KSPROPERTY_GENERAL_COMPONENTID failed with %x\n", Status); + return SetIrpIoStatus(Irp, Status, 0); + } + + PinProperty.PinId = 0; //FIXME + PinProperty.Property.Set = KSPROPSETID_Pin; + PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES; + PinProperty.Property.Flags = KSPROPERTY_TYPE_GET; + + Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)NULL, 0, &BytesReturned); + if (Status != STATUS_BUFFER_TOO_SMALL) + { + DPRINT1("KSPROPERTY_PIN_DATARANGES failed with %x\n", Status); + return SetIrpIoStatus(Irp, Status, 0); + } + + MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned); + if (!MultipleItem) + { + /* no memory */ + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + + Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)MultipleItem, BytesReturned, &BytesReturned); + if (!NT_SUCCESS(Status)) + { + ExFreePool(MultipleItem); + return SetIrpIoStatus(Irp, Status, 0); + } + + DataRange = (PKSDATARANGE) (MultipleItem + 1); + for(Index = 0; Index < MultipleItem->Count; Index++) + { + if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE) + { + if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO)) + { + DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange; + + if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) && + IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) && + IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) + { + dwFormats |= CheckFormatSupport(DataRangeAudio, 11025, WAVE_FORMAT_1M08, WAVE_FORMAT_1S08, WAVE_FORMAT_1M16, WAVE_FORMAT_1S16); + dwFormats |= CheckFormatSupport(DataRangeAudio, 22050, WAVE_FORMAT_2M08, WAVE_FORMAT_2S08, WAVE_FORMAT_2M16, WAVE_FORMAT_2S16); + dwFormats |= CheckFormatSupport(DataRangeAudio, 44100, WAVE_FORMAT_4M08, WAVE_FORMAT_4S08, WAVE_FORMAT_4M16, WAVE_FORMAT_4S16); + dwFormats |= CheckFormatSupport(DataRangeAudio, 48000, WAVE_FORMAT_48M08, WAVE_FORMAT_48S08, WAVE_FORMAT_48M16, WAVE_FORMAT_48S16); + dwFormats |= CheckFormatSupport(DataRangeAudio, 96000, WAVE_FORMAT_96M08, WAVE_FORMAT_96S08, WAVE_FORMAT_96M16, WAVE_FORMAT_96S16); + + wChannels = DataRangeAudio->MaximumChannels; + dwSupport = WAVECAPS_VOLUME; //FIXME get info from nodes + } + } + } + + } + + DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats; + DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport; + DeviceInfo->u.WaveOutCaps.wChannels = wChannels; + DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7; + DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version, ComponentId.Revision); + + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); +}
NTSTATUS NTAPI @@ -386,12 +508,13 @@ return WdmAudControlDeviceState(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_WRITEDATA: return WdmAudControlWriteData(DeviceObject, Irp, DeviceInfo, ClientInfo); - + case IOCTL_GETCAPABILITIES: + return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_CLOSE_WDMAUD: case IOCTL_GETDEVID: case IOCTL_GETVOLUME: case IOCTL_SETVOLUME: - case IOCTL_GETCAPABILITIES: + DPRINT1("Unhandeled %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); break; }
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- 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] Mon Feb 23 14:13:35 2009 @@ -8,55 +8,7 @@ #define YDEBUG #include <debug.h> #include <ksmedia.h> - - -#ifndef MAXPNAMELEN -#define MAXPNAMELEN 32 -#endif - -#ifndef WAVEOUTCAPS - -typedef struct -{ - USHORT wMid; - USHORT wPid; - ULONG vDriverVersion; - WCHAR szPname[MAXPNAMELEN]; - ULONG dwFormats; - USHORT wChannels; - USHORT wReserved1; - ULONG dwSupport; -} WAVEOUTCAPS; - -#endif - -#ifndef AUXCAPS - -typedef struct { - USHORT wMid; - USHORT wPid; - ULONG vDriverVersion; - WCHAR szPname[MAXPNAMELEN]; - USHORT wTechnology; - USHORT wReserved1; - ULONG dwSupport; -} AUXCAPS; - -#endif - -#ifndef WAVEINCAPS - -typedef struct -{ - USHORT wMid; - USHORT wPid; - ULONG vDriverVersion; - WCHAR szPname[MAXPNAMELEN]; - ULONG dwFormats; - USHORT wChannels; - USHORT wReserved1; -} WAVEINCAPS; -#endif +#include <mmsystem.h>
#include "interface.h"