mirror of
https://github.com/reactos/reactos.git
synced 2025-05-31 23:18:39 +00:00
- 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 svn path=/trunk/; revision=39719
This commit is contained in:
parent
2bf896ebe5
commit
cb2ab2abe6
6 changed files with 194 additions and 69 deletions
|
@ -47,6 +47,7 @@ main(int argc, char* argv[])
|
|||
|
||||
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 @@ main(int argc, char* argv[])
|
|||
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);
|
||||
|
@ -87,6 +97,9 @@ main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Allocate a buffer for 1 second
|
||||
//
|
||||
|
@ -119,7 +132,7 @@ main(int argc, char* argv[])
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Play our 1-second buffer
|
||||
//
|
||||
|
@ -136,6 +149,8 @@ main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ main(int argc, char* argv[])
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
printf("WDMAUD: STOPPED\n");
|
||||
CloseHandle(hWdmAud);
|
||||
CloseHandle(&Overlapped.hEvent);
|
||||
printf("WDMAUD: COMPLETE\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -128,6 +128,8 @@ typedef struct
|
|||
GUID *Interfaces;
|
||||
KSPIN_FACTORY Factory;
|
||||
KSPROPERTY_SET_LIST FilterPropertySet;
|
||||
|
||||
PPCFILTER_DESCRIPTOR DeviceDescriptor;
|
||||
}SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
|
||||
|
||||
#undef INTERFACE
|
||||
|
|
|
@ -133,27 +133,55 @@ PcPropertyHandler(
|
|||
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 @@ PcPropertyHandler(
|
|||
/* 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 @@ PcPropertyHandler(
|
|||
/* 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;
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ PcCreateSubdeviceDescriptor(
|
|||
Descriptor->Factory.Instances[Index].MinFilterInstanceCount = FilterDescription->Pins[Index].MinFilterInstanceCount;
|
||||
}
|
||||
}
|
||||
|
||||
Descriptor->DeviceDescriptor = FilterDescription;
|
||||
*OutSubdeviceDescriptor = Descriptor;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010,
|
|||
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(
|
||||
IN PIRP Irp,
|
||||
|
@ -324,17 +323,140 @@ WdmAudControlWriteData(
|
|||
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 @@ WdmAudDeviceControl(
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
Loading…
Reference in a new issue