2009-02-20 17:52:47 +00:00
/*
* COPYRIGHT : See COPYING in the top level directory
* PROJECT : ReactOS Kernel Streaming
* FILE : drivers / wdm / audio / legacy / wdmaud / deviface . c
* PURPOSE : System Audio graph builder
* PROGRAMMER : Andrew Greenwood
* Johannes Anderwald
*/
# include "wdmaud.h"
2009-02-23 21:51:41 +00:00
const GUID KSPROPSETID_Pin = { 0x8C134960L , 0x51AD , 0x11CF , { 0x87 , 0x8A , 0x94 , 0xF8 , 0x01 , 0xC1 , 0x00 , 0x00 } } ;
2009-02-21 20:18:44 +00:00
const GUID KSPROPSETID_Connection = { 0x1D58C920L , 0xAC9B , 0x11CF , { 0xA5 , 0xD6 , 0x28 , 0xDB , 0x04 , 0xC1 , 0x00 , 0x00 } } ;
const GUID KSPROPSETID_Sysaudio = { 0xCBE3FAA0L , 0xCC75 , 0x11D0 , { 0xB4 , 0x65 , 0x00 , 0x00 , 0x1A , 0x18 , 0x18 , 0xE6 } } ;
const GUID KSPROPSETID_General = { 0x1464EDA5L , 0x6A8F , 0x11D1 , { 0x9A , 0xA7 , 0x00 , 0xA0 , 0xC9 , 0x22 , 0x31 , 0x96 } } ;
const GUID KSINTERFACESETID_Standard = { 0x1A8766A0L , 0x62CE , 0x11CF , { 0xA5 , 0xD6 , 0x28 , 0xDB , 0x04 , 0xC1 , 0x00 , 0x00 } } ;
const GUID KSMEDIUMSETID_Standard = { 0x4747B320L , 0x62CE , 0x11CF , { 0xA5 , 0xD6 , 0x28 , 0xDB , 0x04 , 0xC1 , 0x00 , 0x00 } } ;
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 (
IN PIRP Irp ,
IN NTSTATUS Status ,
IN ULONG Length )
{
Irp - > IoStatus . Information = Length ;
Irp - > IoStatus . Status = Status ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return Status ;
}
2009-02-27 12:22:18 +00:00
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 ;
}
2009-02-21 20:18:44 +00:00
NTSTATUS
WdmAudControlOpen (
IN PDEVICE_OBJECT DeviceObject ,
IN PIRP Irp ,
IN PWDMAUD_DEVICE_INFO DeviceInfo ,
IN PWDMAUD_CLIENT ClientInfo )
{
PSYSAUDIO_INSTANCE_INFO InstanceInfo ;
ULONG BytesReturned ;
NTSTATUS Status ;
ACCESS_MASK DesiredAccess = 0 ;
HANDLE PinHandle ;
KSPIN_CONNECT * PinConnect ;
2009-03-11 18:32:32 +00:00
ULONG Length , Index ;
2009-02-21 20:18:44 +00:00
KSDATAFORMAT_WAVEFORMATEX * DataFormat ;
2009-02-27 12:22:18 +00:00
ULONG FilterId ;
ULONG PinId ;
2009-02-21 20:18:44 +00:00
2009-02-27 12:22:18 +00:00
if ( DeviceInfo - > DeviceType ! = WAVE_OUT_DEVICE_TYPE & & DeviceInfo - > DeviceType ! = WAVE_IN_DEVICE_TYPE )
2009-02-21 20:18:44 +00:00
{
2009-03-12 22:11:53 +00:00
DPRINT1 ( " FIXME: only waveout / wavein devices are supported \n " ) ;
2009-02-21 20:18:44 +00:00
return SetIrpIoStatus ( Irp , STATUS_UNSUCCESSFUL , 0 ) ;
}
2009-02-27 12:22:18 +00:00
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 ) ;
}
2009-02-22 18:58:51 +00:00
Length = sizeof ( KSDATAFORMAT_WAVEFORMATEX ) + sizeof ( KSPIN_CONNECT ) + sizeof ( SYSAUDIO_INSTANCE_INFO ) ;
InstanceInfo = ExAllocatePool ( NonPagedPool , Length ) ;
2009-02-21 20:18:44 +00:00
if ( ! InstanceInfo )
{
/* no memory */
return SetIrpIoStatus ( Irp , STATUS_NO_MEMORY , 0 ) ;
}
InstanceInfo - > Property . Set = KSPROPSETID_Sysaudio ;
InstanceInfo - > Property . Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO ;
InstanceInfo - > Property . Flags = KSPROPERTY_TYPE_SET ;
InstanceInfo - > Flags = 0 ;
2009-02-27 12:22:18 +00:00
InstanceInfo - > DeviceNumber = FilterId ;
2009-02-21 20:18:44 +00:00
Status = KsSynchronousIoControlDevice ( ClientInfo - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) InstanceInfo , sizeof ( SYSAUDIO_INSTANCE_INFO ) , NULL , 0 , & BytesReturned ) ;
if ( ! NT_SUCCESS ( Status ) )
{
/* failed to acquire audio device */
DPRINT1 ( " KsSynchronousIoControlDevice failed with %x \n " , Status ) ;
ExFreePool ( InstanceInfo ) ;
return SetIrpIoStatus ( Irp , Status , 0 ) ;
}
if ( DeviceInfo - > DeviceType = = WAVE_IN_DEVICE_TYPE | |
DeviceInfo - > DeviceType = = MIDI_IN_DEVICE_TYPE | |
DeviceInfo - > DeviceType = = MIXER_DEVICE_TYPE )
{
DesiredAccess | = GENERIC_READ ;
}
if ( DeviceInfo - > DeviceType = = WAVE_OUT_DEVICE_TYPE | |
DeviceInfo - > DeviceType = = MIDI_OUT_DEVICE_TYPE | |
DeviceInfo - > DeviceType = = AUX_DEVICE_TYPE | |
DeviceInfo - > DeviceType = = MIXER_DEVICE_TYPE )
{
DesiredAccess | = GENERIC_WRITE ;
}
2009-02-22 18:58:51 +00:00
PinConnect = ( KSPIN_CONNECT * ) ( InstanceInfo + 1 ) ;
2009-02-21 20:18:44 +00:00
PinConnect - > Interface . Set = KSINTERFACESETID_Standard ;
PinConnect - > Interface . Id = KSINTERFACE_STANDARD_STREAMING ;
PinConnect - > Interface . Flags = 0 ;
PinConnect - > Medium . Set = KSMEDIUMSETID_Standard ;
PinConnect - > Medium . Id = KSMEDIUM_TYPE_ANYINSTANCE ;
PinConnect - > Medium . Flags = 0 ;
2009-02-27 12:22:18 +00:00
PinConnect - > PinId = PinId ;
2009-02-22 18:58:51 +00:00
PinConnect - > PinToHandle = ClientInfo - > hSysAudio ;
2009-02-21 20:18:44 +00:00
PinConnect - > Priority . PriorityClass = KSPRIORITY_NORMAL ;
PinConnect - > Priority . PrioritySubClass = 1 ;
DataFormat = ( KSDATAFORMAT_WAVEFORMATEX * ) ( PinConnect + 1 ) ;
DataFormat - > WaveFormatEx . wFormatTag = DeviceInfo - > u . WaveFormatEx . wFormatTag ;
DataFormat - > WaveFormatEx . nChannels = DeviceInfo - > u . WaveFormatEx . nChannels ;
DataFormat - > WaveFormatEx . nSamplesPerSec = DeviceInfo - > u . WaveFormatEx . nSamplesPerSec ;
DataFormat - > WaveFormatEx . nBlockAlign = DeviceInfo - > u . WaveFormatEx . nBlockAlign ;
DataFormat - > WaveFormatEx . nAvgBytesPerSec = DeviceInfo - > u . WaveFormatEx . nAvgBytesPerSec ;
DataFormat - > WaveFormatEx . wBitsPerSample = DeviceInfo - > u . WaveFormatEx . wBitsPerSample ;
DataFormat - > WaveFormatEx . cbSize = 0 ;
DataFormat - > DataFormat . FormatSize = sizeof ( KSDATAFORMAT ) + sizeof ( WAVEFORMATEX ) ;
DataFormat - > DataFormat . Flags = 0 ;
DataFormat - > DataFormat . Reserved = 0 ;
DataFormat - > DataFormat . MajorFormat = KSDATAFORMAT_TYPE_AUDIO ;
if ( DeviceInfo - > u . WaveFormatEx . wFormatTag ! = WAVE_FORMAT_PCM )
DPRINT1 ( " FIXME \n " ) ;
DataFormat - > DataFormat . SubFormat = KSDATAFORMAT_SUBTYPE_PCM ;
DataFormat - > DataFormat . Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX ;
DataFormat - > DataFormat . SampleSize = 4 ;
2009-02-22 18:58:51 +00:00
/* ros specific pin creation request */
InstanceInfo - > Property . Id = ( ULONG ) - 1 ;
Status = KsSynchronousIoControlDevice ( ClientInfo - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) InstanceInfo , Length , & PinHandle , sizeof ( HANDLE ) , & BytesReturned ) ;
2009-02-21 20:18:44 +00:00
if ( NT_SUCCESS ( Status ) )
{
2009-03-11 18:32:32 +00:00
PHANDLE Handels ;
for ( Index = 0 ; Index < ClientInfo - > NumPins ; Index + + )
{
if ( ClientInfo - > hPins [ Index ] = = PinHandle )
{
/* the pin handle has been re-used */
DeviceInfo - > hDevice = PinHandle ;
return SetIrpIoStatus ( Irp , Status , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
}
}
Handels = ExAllocatePool ( NonPagedPool , sizeof ( HANDLE ) * ( ClientInfo - > NumPins + 1 ) ) ;
2009-02-22 18:58:51 +00:00
if ( Handels )
{
if ( ClientInfo - > NumPins )
{
RtlMoveMemory ( Handels , ClientInfo - > hPins , sizeof ( HANDLE ) * ClientInfo - > NumPins ) ;
ExFreePool ( ClientInfo - > hPins ) ;
}
ClientInfo - > hPins = Handels ;
ClientInfo - > hPins [ ClientInfo - > NumPins ] = PinHandle ;
ClientInfo - > NumPins + + ;
}
2009-02-21 20:18:44 +00:00
DeviceInfo - > hDevice = PinHandle ;
}
else
{
DeviceInfo - > hDevice = NULL ;
}
return SetIrpIoStatus ( Irp , Status , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
}
NTSTATUS
WdmAudControlDeviceType (
IN PDEVICE_OBJECT DeviceObject ,
IN PIRP Irp ,
IN PWDMAUD_DEVICE_INFO DeviceInfo ,
IN PWDMAUD_CLIENT ClientInfo )
{
2009-02-27 12:22:18 +00:00
KSP_PIN Pin ;
ULONG Count , BytesReturned , Index , SubIndex , Result , NumPins ;
2009-02-21 20:18:44 +00:00
NTSTATUS Status ;
2009-02-27 12:22:18 +00:00
KSPIN_COMMUNICATION Communication ;
KSPIN_DATAFLOW DataFlow ;
2009-02-21 20:18:44 +00:00
2009-02-27 12:22:18 +00:00
if ( DeviceInfo - > DeviceType ! = WAVE_OUT_DEVICE_TYPE & & DeviceInfo - > DeviceType ! = WAVE_IN_DEVICE_TYPE )
2009-02-21 20:18:44 +00:00
{
2009-02-27 12:22:18 +00:00
DPRINT1 ( " FIXME: Unsupported device type %x \n " , DeviceInfo - > DeviceType ) ;
2009-02-21 20:18:44 +00:00
return SetIrpIoStatus ( Irp , STATUS_UNSUCCESSFUL , 0 ) ;
}
2009-02-27 12:22:18 +00:00
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 + + ;
}
}
}
}
2009-02-21 20:18:44 +00:00
if ( NT_SUCCESS ( Status ) )
DeviceInfo - > DeviceCount = Result ;
else
DeviceInfo - > DeviceCount = 0 ;
DPRINT1 ( " WdmAudControlDeviceType Status %x Devices %u \n " , Status , DeviceInfo - > DeviceCount ) ;
return SetIrpIoStatus ( Irp , Status , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
}
NTSTATUS
WdmAudControlDeviceState (
IN PDEVICE_OBJECT DeviceObject ,
IN PIRP Irp ,
IN PWDMAUD_DEVICE_INFO DeviceInfo ,
IN PWDMAUD_CLIENT ClientInfo )
{
KSPROPERTY Property ;
KSSTATE State ;
NTSTATUS Status ;
ULONG BytesReturned ;
PFILE_OBJECT FileObject ;
2009-03-12 22:11:53 +00:00
//DPRINT1("WdmAudControlDeviceState\n");
2009-03-06 19:06:21 +00:00
2009-02-21 20:18:44 +00:00
Status = ObReferenceObjectByHandle ( DeviceInfo - > hDevice , GENERIC_READ | GENERIC_WRITE , IoFileObjectType , KernelMode , ( PVOID * ) & FileObject , NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " Error: invalid device handle provided %p \n " , DeviceInfo - > hDevice ) ;
return SetIrpIoStatus ( Irp , STATUS_UNSUCCESSFUL , 0 ) ;
}
Property . Set = KSPROPSETID_Connection ;
Property . Id = KSPROPERTY_CONNECTION_STATE ;
Property . Flags = KSPROPERTY_TYPE_SET ;
State = DeviceInfo - > State ;
Status = KsSynchronousIoControlDevice ( FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) & Property , sizeof ( KSPROPERTY ) , ( PVOID ) & State , sizeof ( KSSTATE ) , & BytesReturned ) ;
ObDereferenceObject ( FileObject ) ;
2009-03-12 22:11:53 +00:00
//DPRINT1("WdmAudControlDeviceState Status %x\n", Status);
2009-02-21 20:18:44 +00:00
return SetIrpIoStatus ( Irp , Status , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
}
NTSTATUS
NTAPI
WdmAudWriteCompleted (
IN PDEVICE_OBJECT DeviceObject ,
IN PIRP Irp ,
IN PVOID Ctx )
{
PWRITE_CONTEXT Context = ( PWRITE_CONTEXT ) Ctx ;
Context - > Irp - > IoStatus . Information = Context - > Length ;
Context - > Irp - > IoStatus . Status = Irp - > IoStatus . Status ;
IoCompleteRequest ( Context - > Irp , IO_SOUND_INCREMENT ) ;
ExFreePool ( Context ) ;
return STATUS_SUCCESS ;
}
2009-02-23 11:13:35 +00:00
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 ;
}
}
2009-02-24 18:38:39 +00:00
if ( DataRangeAudio - > MinimumBitsPerSample < = 16 & & DataRangeAudio - > MaximumBitsPerSample > = 16 )
2009-02-23 11:13:35 +00:00
{
2009-02-23 13:40:50 +00:00
Result | = Mono16Bit ;
2009-02-23 11:13:35 +00:00
if ( DataRangeAudio - > MaximumChannels > = 2 )
{
Result | = Stereo8Bit ;
}
}
}
return Result ;
2009-02-21 20:18:44 +00:00
}
2009-02-23 11:13:35 +00:00
NTSTATUS
WdmAudCapabilities (
IN PDEVICE_OBJECT DeviceObject ,
IN PIRP Irp ,
IN PWDMAUD_DEVICE_INFO DeviceInfo ,
IN PWDMAUD_CLIENT ClientInfo )
{
2009-02-25 15:55:21 +00:00
NTSTATUS Status = STATUS_UNSUCCESSFUL ;
2009-02-23 11:13:35 +00:00
KSP_PIN PinProperty ;
KSCOMPONENTID ComponentId ;
KSMULTIPLE_ITEM * MultipleItem ;
ULONG BytesReturned ;
PKSDATARANGE_AUDIO DataRangeAudio ;
PKSDATARANGE DataRange ;
ULONG Index ;
ULONG wChannels = 0 ;
ULONG dwFormats = 0 ;
ULONG dwSupport = 0 ;
2009-02-27 12:22:18 +00:00
ULONG FilterId ;
2009-02-23 21:51:41 +00:00
ULONG PinId ;
2009-02-23 11:13:35 +00:00
2009-02-23 21:51:41 +00:00
DPRINT ( " WdmAudCapabilities entered \n " ) ;
2009-02-27 12:22:18 +00:00
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 ;
2009-02-23 21:51:41 +00:00
PinProperty . Property . Set = KSPROPSETID_Sysaudio ;
PinProperty . Property . Id = KSPROPERTY_SYSAUDIO_COMPONENT_ID ;
PinProperty . Property . Flags = KSPROPERTY_TYPE_GET ;
2009-02-21 20:18:44 +00:00
2009-02-23 11:13:35 +00:00
RtlZeroMemory ( & ComponentId , sizeof ( KSCOMPONENTID ) ) ;
2009-02-23 21:51:41 +00:00
Status = KsSynchronousIoControlDevice ( ClientInfo - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) & PinProperty , sizeof ( KSP_PIN ) , ( PVOID ) & ComponentId , sizeof ( KSCOMPONENTID ) , & BytesReturned ) ;
if ( NT_SUCCESS ( Status ) )
2009-02-23 11:13:35 +00:00
{
2009-02-23 21:51:41 +00:00
DeviceInfo - > u . WaveOutCaps . wMid = ComponentId . Manufacturer . Data1 - 0xd5a47fa7 ;
DeviceInfo - > u . WaveOutCaps . vDriverVersion = MAKELONG ( ComponentId . Version , ComponentId . Revision ) ;
2009-02-23 11:13:35 +00:00
}
2009-02-23 21:51:41 +00:00
PinProperty . Reserved = DeviceInfo - > DeviceIndex ;
PinProperty . PinId = PinId ;
2009-02-23 11:13:35 +00:00
PinProperty . Property . Set = KSPROPSETID_Pin ;
PinProperty . Property . Id = KSPROPERTY_PIN_DATARANGES ;
PinProperty . Property . Flags = KSPROPERTY_TYPE_GET ;
2009-02-23 21:51:41 +00:00
BytesReturned = 0 ;
Status = KsSynchronousIoControlDevice ( ClientInfo - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) & PinProperty , sizeof ( KSP_PIN ) , ( PVOID ) NULL , 0 , & BytesReturned ) ;
2009-02-23 11:13:35 +00:00
if ( Status ! = STATUS_BUFFER_TOO_SMALL )
2009-02-23 21:51:41 +00:00
{
2009-02-23 11:13:35 +00:00
return SetIrpIoStatus ( Irp , Status , 0 ) ;
2009-02-23 21:51:41 +00:00
}
2009-02-23 11:13:35 +00:00
MultipleItem = ExAllocatePool ( NonPagedPool , BytesReturned ) ;
if ( ! MultipleItem )
{
/* no memory */
return SetIrpIoStatus ( Irp , STATUS_NO_MEMORY , 0 ) ;
}
2009-02-23 21:51:41 +00:00
Status = KsSynchronousIoControlDevice ( ClientInfo - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) & PinProperty , sizeof ( KSP_PIN ) , ( PVOID ) MultipleItem , BytesReturned , & BytesReturned ) ;
2009-02-23 11:13:35 +00:00
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 ) )
{
2009-02-24 18:38:39 +00:00
DPRINT ( " Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u \n " , DataRangeAudio - > MinimumSampleFrequency , DataRangeAudio - > MaximumSampleFrequency ,
DataRangeAudio - > MinimumBitsPerSample , DataRangeAudio - > MaximumBitsPerSample , DataRangeAudio - > MaximumChannels ) ;
2009-02-23 11:13:35 +00:00
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 ) ;
2009-02-24 18:38:39 +00:00
2009-02-23 11:13:35 +00:00
wChannels = DataRangeAudio - > MaximumChannels ;
dwSupport = WAVECAPS_VOLUME ; //FIXME get info from nodes
}
}
}
2009-02-24 18:38:39 +00:00
DataRange = ( PKSDATARANGE ) ( ( PUCHAR ) DataRange + DataRange - > FormatSize ) ;
2009-02-23 11:13:35 +00:00
}
DeviceInfo - > u . WaveOutCaps . dwFormats = dwFormats ;
DeviceInfo - > u . WaveOutCaps . dwSupport = dwSupport ;
DeviceInfo - > u . WaveOutCaps . wChannels = wChannels ;
2009-02-24 18:38:39 +00:00
DeviceInfo - > u . WaveOutCaps . szPname [ 0 ] = L ' \0 ' ;
2009-02-23 21:51:41 +00:00
2009-02-23 11:13:35 +00:00
2009-02-24 18:38:39 +00:00
ExFreePool ( MultipleItem ) ;
2009-02-23 11:13:35 +00:00
return SetIrpIoStatus ( Irp , Status , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
}
2009-02-20 17:52:47 +00:00
2009-02-25 15:55:21 +00:00
NTSTATUS
NTAPI
WdmAudClose (
IN PDEVICE_OBJECT DeviceObject ,
IN PIRP Irp ,
IN PWDMAUD_DEVICE_INFO DeviceInfo ,
IN PWDMAUD_CLIENT ClientInfo )
{
ULONG Index ;
for ( Index = 0 ; Index < ClientInfo - > NumPins ; Index + + )
{
if ( ClientInfo - > hPins [ Index ] = = DeviceInfo - > hDevice )
{
DPRINT1 ( " Closing device %p \n " , DeviceInfo - > hDevice ) ;
ZwClose ( DeviceInfo - > hDevice ) ;
ClientInfo - > hPins [ Index ] = NULL ;
SetIrpIoStatus ( Irp , STATUS_SUCCESS , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
return STATUS_SUCCESS ;
}
}
SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
return STATUS_INVALID_PARAMETER ;
}
2009-02-20 17:52:47 +00:00
NTSTATUS
NTAPI
WdmAudDeviceControl (
IN PDEVICE_OBJECT DeviceObject ,
IN PIRP Irp )
{
PIO_STACK_LOCATION IoStack ;
2009-02-21 20:18:44 +00:00
PWDMAUD_DEVICE_INFO DeviceInfo ;
PWDMAUD_CLIENT ClientInfo ;
2009-02-20 17:52:47 +00:00
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
2009-03-12 22:11:53 +00:00
DPRINT ( " WdmAudDeviceControl entered \n " ) ;
2009-02-21 20:18:44 +00:00
2009-02-20 17:52:47 +00:00
if ( IoStack - > Parameters . DeviceIoControl . InputBufferLength < sizeof ( WDMAUD_DEVICE_INFO ) )
{
2009-02-21 20:18:44 +00:00
/* invalid parameter */
DPRINT1 ( " Input buffer too small size %u expected %u \n " , IoStack - > Parameters . DeviceIoControl . InputBufferLength , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
return SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , 0 ) ;
2009-02-20 17:52:47 +00:00
}
2009-02-21 20:18:44 +00:00
DeviceInfo = ( PWDMAUD_DEVICE_INFO ) Irp - > AssociatedIrp . SystemBuffer ;
if ( DeviceInfo - > DeviceType < MIN_SOUND_DEVICE_TYPE | | DeviceInfo - > DeviceType > MAX_SOUND_DEVICE_TYPE )
{
/* invalid parameter */
DPRINT1 ( " Error: device type not set \n " ) ;
return SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , 0 ) ;
}
if ( ! IoStack - > FileObject )
{
/* file object parameter */
DPRINT1 ( " Error: file object is not attached \n " ) ;
return SetIrpIoStatus ( Irp , STATUS_UNSUCCESSFUL , 0 ) ;
}
ClientInfo = ( PWDMAUD_CLIENT ) IoStack - > FileObject - > FsContext ;
2009-03-12 22:11:53 +00:00
DPRINT ( " WdmAudDeviceControl entered \n " ) ;
2009-02-20 17:52:47 +00:00
switch ( IoStack - > Parameters . DeviceIoControl . IoControlCode )
{
case IOCTL_OPEN_WDMAUD :
2009-02-21 20:18:44 +00:00
return WdmAudControlOpen ( DeviceObject , Irp , DeviceInfo , ClientInfo ) ;
2009-02-20 17:52:47 +00:00
case IOCTL_GETNUMDEVS_TYPE :
2009-02-21 20:18:44 +00:00
return WdmAudControlDeviceType ( DeviceObject , Irp , DeviceInfo , ClientInfo ) ;
2009-02-20 17:52:47 +00:00
case IOCTL_SETDEVICE_STATE :
2009-02-21 20:18:44 +00:00
return WdmAudControlDeviceState ( DeviceObject , Irp , DeviceInfo , ClientInfo ) ;
2009-02-23 11:13:35 +00:00
case IOCTL_GETCAPABILITIES :
return WdmAudCapabilities ( DeviceObject , Irp , DeviceInfo , ClientInfo ) ;
2009-02-21 20:18:44 +00:00
case IOCTL_CLOSE_WDMAUD :
2009-02-25 15:55:21 +00:00
return WdmAudClose ( DeviceObject , Irp , DeviceInfo , ClientInfo ) ;
2009-02-20 17:52:47 +00:00
case IOCTL_GETDEVID :
case IOCTL_GETVOLUME :
case IOCTL_SETVOLUME :
2009-02-23 11:13:35 +00:00
2009-02-21 20:18:44 +00:00
DPRINT1 ( " Unhandeled %x \n " , IoStack - > Parameters . DeviceIoControl . IoControlCode ) ;
2009-02-20 17:52:47 +00:00
break ;
}
2009-02-21 20:18:44 +00:00
return SetIrpIoStatus ( Irp , STATUS_NOT_IMPLEMENTED , 0 ) ;
2009-02-20 17:52:47 +00:00
}
2009-03-06 19:06:21 +00:00
NTSTATUS
NTAPI
WdmAudWrite (
IN PDEVICE_OBJECT DeviceObject ,
IN PIRP Irp )
{
PIO_STACK_LOCATION IoStack ;
PWDMAUD_DEVICE_INFO DeviceInfo ;
PWDMAUD_CLIENT ClientInfo ;
NTSTATUS Status = STATUS_SUCCESS ;
PUCHAR Buffer ;
PCONTEXT_WRITE Packet ;
PFILE_OBJECT FileObject ;
IO_STATUS_BLOCK IoStatusBlock ;
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
2009-03-09 18:05:56 +00:00
//DPRINT("WdmAudWrite entered\n");
2009-03-06 19:06:21 +00:00
if ( IoStack - > Parameters . Write . Length < sizeof ( WDMAUD_DEVICE_INFO ) )
{
/* invalid parameter */
DPRINT1 ( " Input buffer too small size %u expected %u \n " , IoStack - > Parameters . Write . Length , sizeof ( WDMAUD_DEVICE_INFO ) ) ;
return SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , 0 ) ;
}
DeviceInfo = ( PWDMAUD_DEVICE_INFO ) MmGetMdlVirtualAddress ( Irp - > MdlAddress ) ;
Status = ObReferenceObjectByHandle ( DeviceInfo - > hDevice , GENERIC_WRITE , IoFileObjectType , KernelMode , ( PVOID * ) & FileObject , NULL ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " Invalid buffer handle %x \n " , DeviceInfo - > hDevice ) ;
return SetIrpIoStatus ( Irp , Status , 0 ) ;
}
2009-03-09 18:05:56 +00:00
//DPRINT("DeviceInfo %p %p %p\n", DeviceInfo, Irp->MdlAddress->StartVa, Irp->MdlAddress->MappedSystemVa);
2009-03-06 19:06:21 +00:00
if ( DeviceInfo - > DeviceType < MIN_SOUND_DEVICE_TYPE | | DeviceInfo - > DeviceType > MAX_SOUND_DEVICE_TYPE )
{
/* invalid parameter */
DPRINT1 ( " Error: device type not set \n " ) ;
return SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , 0 ) ;
}
if ( ! IoStack - > FileObject )
{
/* file object parameter */
DPRINT1 ( " Error: file object is not attached \n " ) ;
return SetIrpIoStatus ( Irp , STATUS_UNSUCCESSFUL , 0 ) ;
}
ClientInfo = ( PWDMAUD_CLIENT ) IoStack - > FileObject - > FsContext ;
/* setup stream context */
Packet = ( PCONTEXT_WRITE ) ExAllocatePool ( NonPagedPool , sizeof ( CONTEXT_WRITE ) ) ;
if ( ! Packet )
{
/* no memory */
return SetIrpIoStatus ( Irp , STATUS_NO_MEMORY , 0 ) ;
}
Packet - > Header . FrameExtent = DeviceInfo - > BufferSize ;
Packet - > Header . DataUsed = DeviceInfo - > BufferSize ;
Packet - > Header . Size = sizeof ( KSSTREAM_HEADER ) ;
Packet - > Header . PresentationTime . Numerator = 1 ;
Packet - > Header . PresentationTime . Denominator = 1 ;
Packet - > Irp = Irp ;
Buffer = ExAllocatePool ( NonPagedPool , DeviceInfo - > BufferSize ) ;
if ( ! Buffer )
{
/* no memory */
ExFreePool ( Packet ) ;
return SetIrpIoStatus ( Irp , STATUS_NO_MEMORY , 0 ) ;
}
Packet - > Header . Data = Buffer ;
_SEH2_TRY
{
ProbeForRead ( DeviceInfo - > Buffer , DeviceInfo - > BufferSize , TYPE_ALIGNMENT ( char ) ) ;
RtlMoveMemory ( Buffer , DeviceInfo - > Buffer , DeviceInfo - > BufferSize ) ;
}
_SEH2_EXCEPT ( EXCEPTION_EXECUTE_HANDLER )
{
/* Exception, get the error code */
Status = _SEH2_GetExceptionCode ( ) ;
}
_SEH2_END ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " Invalid buffer supplied \n " ) ;
ExFreePool ( Buffer ) ;
ExFreePool ( Packet ) ;
return SetIrpIoStatus ( Irp , Status , 0 ) ;
}
KsStreamIo ( FileObject , NULL , NULL , NULL , NULL , 0 , & IoStatusBlock , Packet , sizeof ( CONTEXT_WRITE ) , KSSTREAM_WRITE , KernelMode ) ;
2009-03-08 16:25:28 +00:00
return IoStatusBlock . Status ;
2009-03-06 19:06:21 +00:00
}