2009-02-20 17:52:47 +00:00
/*
* COPYRIGHT : See COPYING in the top level directory
* PROJECT : ReactOS Kernel Streaming
* FILE : drivers / wdm / audio / sysaudio / control . c
* PURPOSE : System Audio graph builder
* PROGRAMMER : Johannes Anderwald
*/
# include "sysaudio.h"
2013-12-19 22:45:32 +00:00
# define NDEBUG
# include <debug.h>
2009-02-20 17:52:47 +00:00
const GUID KSPROPSETID_Sysaudio = { 0xCBE3FAA0L , 0xCC75 , 0x11D0 , { 0xB4 , 0x65 , 0x00 , 0x00 , 0x1A , 0x18 , 0x18 , 0xE6 } } ;
const GUID KSPROPSETID_Sysaudio_Pin = { 0xA3A53220L , 0xC6E4 , 0x11D0 , { 0xB4 , 0x65 , 0x00 , 0x00 , 0x1A , 0x18 , 0x18 , 0xE6 } } ;
const GUID KSPROPSETID_General = { 0x1464EDA5L , 0x6A8F , 0x11D1 , { 0x9A , 0xA7 , 0x00 , 0xA0 , 0xC9 , 0x22 , 0x31 , 0x96 } } ;
2009-02-22 18:58:51 +00:00
const GUID KSPROPSETID_Pin = { 0x8C134960L , 0x51AD , 0x11CF , { 0x87 , 0x8A , 0x94 , 0xF8 , 0x01 , 0xC1 , 0x00 , 0x00 } } ;
const GUID KSPROPSETID_Connection = { 0x1D58C920L , 0xAC9B , 0x11CF , { 0xA5 , 0xD6 , 0x28 , 0xDB , 0x04 , 0xC1 , 0x00 , 0x00 } } ;
2009-06-08 21:37:20 +00:00
const GUID KSPROPSETID_Topology = { 0x720D4AC0L , 0x7533 , 0x11D0 , { 0xA5 , 0xD6 , 0x28 , 0xDB , 0x04 , 0xC1 , 0x00 , 0x00 } } ;
2009-03-11 09:30:33 +00:00
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 } } ;
2009-02-20 17:52:47 +00:00
NTSTATUS
SetIrpIoStatus (
IN PIRP Irp ,
IN NTSTATUS Status ,
IN ULONG Length )
{
Irp - > IoStatus . Information = Length ;
Irp - > IoStatus . Status = Status ;
2009-03-12 22:11:53 +00:00
if ( Status ! = STATUS_PENDING )
{
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
}
else
{
IoMarkIrpPending ( Irp ) ;
}
2009-02-20 17:52:47 +00:00
return Status ;
}
2009-07-10 15:14:56 +00:00
PKSAUDIO_DEVICE_ENTRY
2009-02-20 17:52:47 +00:00
GetListEntry (
IN PLIST_ENTRY Head ,
IN ULONG Index )
{
2009-07-10 15:14:56 +00:00
PLIST_ENTRY Entry = Head - > Flink ;
2009-02-20 17:52:47 +00:00
2009-07-10 15:14:56 +00:00
while ( Index - - & & Entry ! = Head )
2009-06-07 18:22:24 +00:00
Entry = Entry - > Flink ;
2009-02-20 17:52:47 +00:00
2009-07-10 15:14:56 +00:00
if ( Entry = = Head )
return NULL ;
2009-06-08 21:37:20 +00:00
2009-07-10 15:14:56 +00:00
return ( PKSAUDIO_DEVICE_ENTRY ) CONTAINING_RECORD ( Entry , KSAUDIO_DEVICE_ENTRY , Entry ) ;
2009-02-20 17:52:47 +00:00
}
NTSTATUS
SysAudioOpenVirtualDevice (
IN PIRP Irp ,
IN ULONG DeviceNumber ,
PSYSAUDIODEVEXT DeviceExtension )
{
2009-07-10 15:14:56 +00:00
PKSAUDIO_DEVICE_ENTRY Entry ;
2009-08-10 07:14:04 +00:00
PIO_STACK_LOCATION IoStack ;
2009-02-20 17:52:47 +00:00
2009-08-10 07:14:04 +00:00
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
/* sanity check */
ASSERT ( IoStack - > FileObject ) ;
2009-02-20 17:52:47 +00:00
if ( DeviceNumber > = DeviceExtension - > NumberOfKsAudioDevices )
{
/* invalid device index */
return SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , 0 ) ;
}
2009-03-25 19:14:04 +00:00
/* get device context */
Entry = GetListEntry ( & DeviceExtension - > KsAudioDeviceList , DeviceNumber ) ;
ASSERT ( Entry ! = NULL ) ;
2009-02-25 15:55:21 +00:00
2009-09-12 14:35:27 +00:00
/* store device entry in FsContext
2009-08-10 07:14:04 +00:00
* see pin . c DispatchCreateSysAudioPin for details
*/
2009-09-12 14:35:27 +00:00
IoStack - > FileObject - > FsContext = ( PVOID ) Entry ;
2009-02-22 18:58:51 +00:00
2009-08-10 07:14:04 +00:00
return SetIrpIoStatus ( Irp , STATUS_SUCCESS , 0 ) ;
2009-02-20 17:52:47 +00:00
}
2009-02-27 11:22:16 +00:00
NTSTATUS
HandleSysAudioFilterPinProperties (
PIRP Irp ,
PKSPROPERTY Property ,
PSYSAUDIODEVEXT DeviceExtension )
{
PIO_STACK_LOCATION IoStack ;
NTSTATUS Status ;
2009-07-10 15:14:56 +00:00
PKSAUDIO_DEVICE_ENTRY Entry ;
2009-02-27 11:22:16 +00:00
ULONG BytesReturned ;
// in order to access pin properties of a sysaudio device
// the caller must provide a KSP_PIN struct, where
// Reserved member points to virtual device index
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
if ( IoStack - > Parameters . DeviceIoControl . InputBufferLength < sizeof ( KSP_PIN ) )
{
/* too small buffer */
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , sizeof ( KSPROPERTY ) + sizeof ( ULONG ) ) ;
}
Entry = GetListEntry ( & DeviceExtension - > KsAudioDeviceList , ( ( KSP_PIN * ) Property ) - > Reserved ) ;
if ( ! Entry )
{
/* invalid device index */
return SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , 0 ) ;
}
2010-05-15 19:05:58 +00:00
/* forward request to the filter implementing the property */
Status = KsSynchronousIoControlDevice ( Entry - > FileObject , KernelMode , IOCTL_KS_PROPERTY ,
2009-02-27 11:22:16 +00:00
( PVOID ) IoStack - > Parameters . DeviceIoControl . Type3InputBuffer ,
IoStack - > Parameters . DeviceIoControl . InputBufferLength ,
Irp - > UserBuffer ,
IoStack - > Parameters . DeviceIoControl . OutputBufferLength ,
& BytesReturned ) ;
2010-05-15 19:05:58 +00:00
return SetIrpIoStatus ( Irp , Status , BytesReturned ) ;
2009-02-27 11:22:16 +00:00
}
2009-04-14 14:59:51 +00:00
NTSTATUS
2009-03-12 22:11:53 +00:00
ComputeCompatibleFormat (
2009-07-10 15:14:56 +00:00
IN PKSAUDIO_DEVICE_ENTRY Entry ,
2009-03-12 22:11:53 +00:00
IN ULONG PinId ,
IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat ,
OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat )
2009-03-08 16:25:28 +00:00
{
2009-03-12 22:11:53 +00:00
BOOL bFound ;
2009-03-08 16:25:28 +00:00
ULONG BytesReturned ;
2009-04-14 14:59:51 +00:00
PKSP_PIN PinRequest ;
2009-03-08 16:25:28 +00:00
NTSTATUS Status ;
2009-03-12 22:11:53 +00:00
PKSMULTIPLE_ITEM MultipleItem ;
2009-04-14 14:59:51 +00:00
ULONG Length ;
PKSDATARANGE_AUDIO AudioRange ;
ULONG Index ;
2009-03-08 16:25:28 +00:00
2009-04-14 14:59:51 +00:00
Length = sizeof ( KSP_PIN ) + sizeof ( KSMULTIPLE_ITEM ) + ClientFormat - > DataFormat . FormatSize ;
2010-06-19 07:26:20 +00:00
PinRequest = AllocateItem ( NonPagedPool , Length ) ;
2009-04-14 14:59:51 +00:00
if ( ! PinRequest )
2009-03-12 22:11:53 +00:00
return STATUS_UNSUCCESSFUL ;
2009-04-14 14:59:51 +00:00
PinRequest - > PinId = PinId ;
PinRequest - > Property . Set = KSPROPSETID_Pin ;
PinRequest - > Property . Flags = KSPROPERTY_TYPE_GET ;
PinRequest - > Property . Id = KSPROPERTY_PIN_DATAINTERSECTION ;
MultipleItem = ( PKSMULTIPLE_ITEM ) ( PinRequest + 1 ) ;
MultipleItem - > Count = 1 ;
2009-10-31 18:00:05 +00:00
MultipleItem - > Size = ClientFormat - > DataFormat . FormatSize ;
2009-04-14 14:59:51 +00:00
RtlMoveMemory ( MultipleItem + 1 , ClientFormat , ClientFormat - > DataFormat . FormatSize ) ;
/* Query the miniport data intersection handler */
Status = KsSynchronousIoControlDevice ( Entry - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) PinRequest , Length , ( PVOID ) MixerFormat , sizeof ( KSDATAFORMAT_WAVEFORMATEX ) , & BytesReturned ) ;
DPRINT ( " Status %x \n " , Status ) ;
if ( NT_SUCCESS ( Status ) )
{
2010-06-19 07:26:20 +00:00
FreeItem ( PinRequest ) ;
2009-04-14 14:59:51 +00:00
return Status ;
2009-03-12 22:11:53 +00:00
}
2009-03-08 16:25:28 +00:00
2009-04-14 14:59:51 +00:00
/* Setup request block */
PinRequest - > Property . Id = KSPROPERTY_PIN_DATARANGES ;
/* Query pin data ranges */
Status = KsSynchronousIoControlDevice ( Entry - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) PinRequest , sizeof ( KSP_PIN ) , NULL , 0 , & BytesReturned ) ;
2009-03-11 09:30:33 +00:00
2009-10-06 09:55:19 +00:00
if ( Status ! = STATUS_MORE_ENTRIES )
2009-03-12 22:11:53 +00:00
{
2009-10-31 18:00:05 +00:00
/* Failed to get data ranges */
2009-04-14 14:59:51 +00:00
return Status ;
2009-03-12 22:11:53 +00:00
}
2010-06-19 07:26:20 +00:00
MultipleItem = AllocateItem ( NonPagedPool , BytesReturned ) ;
2009-03-12 22:11:53 +00:00
if ( ! MultipleItem )
{
2010-06-19 07:26:20 +00:00
FreeItem ( PinRequest ) ;
2009-03-12 22:11:53 +00:00
return STATUS_NO_MEMORY ;
}
2009-04-14 14:59:51 +00:00
Status = KsSynchronousIoControlDevice ( Entry - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) PinRequest , sizeof ( KSP_PIN ) , ( PVOID ) MultipleItem , BytesReturned , & BytesReturned ) ;
2009-03-12 22:11:53 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT ( " Property Request KSPROPERTY_PIN_DATARANGES failed with %x \n " , Status ) ;
2010-06-19 07:26:20 +00:00
FreeItem ( MultipleItem ) ;
FreeItem ( PinRequest ) ;
2009-03-12 22:11:53 +00:00
return STATUS_UNSUCCESSFUL ;
}
2009-03-08 16:25:28 +00:00
2009-03-12 22:11:53 +00:00
AudioRange = ( PKSDATARANGE_AUDIO ) ( MultipleItem + 1 ) ;
bFound = FALSE ;
for ( Index = 0 ; Index < MultipleItem - > Count ; Index + + )
{
if ( AudioRange - > DataRange . FormatSize ! = sizeof ( KSDATARANGE_AUDIO ) )
{
2017-02-06 15:49:23 +00:00
UNIMPLEMENTED ;
2009-03-12 22:11:53 +00:00
AudioRange = ( PKSDATARANGE_AUDIO ) ( ( PUCHAR ) AudioRange + AudioRange - > DataRange . FormatSize ) ;
2009-06-28 20:06:45 +00:00
continue ;
2009-03-12 22:11:53 +00:00
}
2009-04-14 14:59:51 +00:00
/* Select best quality available */
2009-04-15 10:41:41 +00:00
2009-03-12 22:11:53 +00:00
MixerFormat - > DataFormat . FormatSize = sizeof ( KSDATAFORMAT ) + sizeof ( WAVEFORMATEX ) ;
MixerFormat - > DataFormat . Flags = 0 ;
MixerFormat - > DataFormat . Reserved = 0 ;
MixerFormat - > DataFormat . MajorFormat = KSDATAFORMAT_TYPE_AUDIO ;
MixerFormat - > DataFormat . SubFormat = KSDATAFORMAT_SUBTYPE_PCM ;
MixerFormat - > DataFormat . Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX ;
MixerFormat - > DataFormat . SampleSize = 4 ;
MixerFormat - > WaveFormatEx . wFormatTag = ClientFormat - > WaveFormatEx . wFormatTag ;
2009-04-15 10:41:41 +00:00
# ifndef NO_AC97_HACK
/* HACK: AC97 does not support mono render / record */
MixerFormat - > WaveFormatEx . nChannels = 2 ;
/*HACK: AC97 only supports 16-Bit Bits */
MixerFormat - > WaveFormatEx . wBitsPerSample = 16 ;
# else
2009-10-31 18:00:05 +00:00
MixerFormat - > WaveFormatEx . nChannels = min ( ClientFormat - > WaveFormatEx . nChannels , AudioRange - > MaximumChannels ) ;
2009-04-14 14:59:51 +00:00
MixerFormat - > WaveFormatEx . wBitsPerSample = AudioRange - > MaximumBitsPerSample ;
2009-04-15 10:41:41 +00:00
# endif
# ifdef KMIXER_RESAMPLING_IMPLEMENTED
MixerFormat - > WaveFormatEx . nSamplesPerSec = AudioRange - > MaximumSampleFrequency ;
# else
MixerFormat - > WaveFormatEx . nSamplesPerSec = max ( AudioRange - > MinimumSampleFrequency , min ( ClientFormat - > WaveFormatEx . nSamplesPerSec , AudioRange - > MaximumSampleFrequency ) ) ;
# endif
2009-03-12 22:11:53 +00:00
MixerFormat - > WaveFormatEx . cbSize = 0 ;
MixerFormat - > WaveFormatEx . nBlockAlign = ( MixerFormat - > WaveFormatEx . nChannels * MixerFormat - > WaveFormatEx . wBitsPerSample ) / 8 ;
MixerFormat - > WaveFormatEx . nAvgBytesPerSec = MixerFormat - > WaveFormatEx . nChannels * MixerFormat - > WaveFormatEx . nSamplesPerSec * ( MixerFormat - > WaveFormatEx . wBitsPerSample / 8 ) ;
bFound = TRUE ;
break ;
AudioRange = ( PKSDATARANGE_AUDIO ) ( ( PUCHAR ) AudioRange + AudioRange - > DataRange . FormatSize ) ;
}
#if 0
2009-04-14 14:59:51 +00:00
DPRINT1 ( " \n Num Max Channels %u Channels %u Old Channels %u \n Max SampleRate %u SampleRate %u Old SampleRate %u \n Max BitsPerSample %u BitsPerSample %u Old BitsPerSample %u \n " ,
AudioRange - > MaximumChannels , MixerFormat - > WaveFormatEx . nChannels , ClientFormat - > WaveFormatEx . nChannels ,
AudioRange - > MaximumSampleFrequency , MixerFormat - > WaveFormatEx . nSamplesPerSec , ClientFormat - > WaveFormatEx . nSamplesPerSec ,
AudioRange - > MaximumBitsPerSample , MixerFormat - > WaveFormatEx . wBitsPerSample , ClientFormat - > WaveFormatEx . wBitsPerSample ) ;
2009-03-12 22:11:53 +00:00
# endif
2010-06-19 07:26:20 +00:00
FreeItem ( MultipleItem ) ;
FreeItem ( PinRequest ) ;
2009-04-14 14:59:51 +00:00
2009-03-12 22:11:53 +00:00
if ( bFound )
return STATUS_SUCCESS ;
else
return STATUS_NOT_IMPLEMENTED ;
2009-03-08 16:25:28 +00:00
}
2009-04-03 17:06:16 +00:00
NTSTATUS
GetPinInstanceCount (
2009-07-10 15:14:56 +00:00
PKSAUDIO_DEVICE_ENTRY Entry ,
2009-04-03 17:06:16 +00:00
PKSPIN_CINSTANCES PinInstances ,
PKSPIN_CONNECT PinConnect )
{
KSP_PIN PinRequest ;
ULONG BytesReturned ;
/* query the instance count */
PinRequest . PinId = PinConnect - > PinId ;
PinRequest . Property . Set = KSPROPSETID_Pin ;
PinRequest . Property . Flags = KSPROPERTY_TYPE_GET ;
PinRequest . Property . Id = KSPROPERTY_PIN_CINSTANCES ;
2010-05-15 19:05:58 +00:00
ASSERT ( Entry - > FileObject ) ;
2009-04-03 17:06:16 +00:00
return KsSynchronousIoControlDevice ( Entry - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) & PinRequest , sizeof ( KSP_PIN ) , ( PVOID ) PinInstances , sizeof ( KSPIN_CINSTANCES ) , & BytesReturned ) ;
}
2009-02-20 17:52:47 +00:00
NTSTATUS
SysAudioHandleProperty (
PDEVICE_OBJECT DeviceObject ,
PIRP Irp )
{
PIO_STACK_LOCATION IoStack ;
NTSTATUS Status = STATUS_NOT_IMPLEMENTED ;
KSPROPERTY PropertyRequest ;
KSCOMPONENTID ComponentId ;
PULONG Index ;
PKSPROPERTY Property ;
PSYSAUDIODEVEXT DeviceExtension ;
2009-07-10 15:14:56 +00:00
PKSAUDIO_DEVICE_ENTRY Entry ;
2009-02-20 17:52:47 +00:00
PSYSAUDIO_INSTANCE_INFO InstanceInfo ;
2009-03-25 19:14:04 +00:00
ULONG BytesReturned ;
2009-02-20 17:52:47 +00:00
UNICODE_STRING GuidString ;
2009-06-08 21:37:20 +00:00
PKSP_PIN Pin ;
2009-08-17 17:23:35 +00:00
LPWSTR DeviceName ;
2009-02-20 17:52:47 +00:00
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
if ( IoStack - > Parameters . DeviceIoControl . InputBufferLength < sizeof ( KSPROPERTY ) )
{
2009-02-27 11:22:16 +00:00
/* buffer must be at least of sizeof KSPROPERTY */
2009-02-20 17:52:47 +00:00
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , sizeof ( KSPROPERTY ) ) ;
}
Property = ( PKSPROPERTY ) IoStack - > Parameters . DeviceIoControl . Type3InputBuffer ;
DeviceExtension = ( PSYSAUDIODEVEXT ) DeviceObject - > DeviceExtension ;
2009-02-23 21:51:41 +00:00
if ( IsEqualGUIDAligned ( & Property - > Set , & KSPROPSETID_Pin ) )
{
2009-02-27 11:22:16 +00:00
return HandleSysAudioFilterPinProperties ( Irp , Property , DeviceExtension ) ;
2009-02-23 21:51:41 +00:00
}
2009-06-08 21:37:20 +00:00
else if ( IsEqualGUIDAligned ( & Property - > Set , & KSPROPSETID_Topology ) )
{
if ( IoStack - > Parameters . DeviceIoControl . InputBufferLength < sizeof ( KSP_PIN ) )
{
/* too small buffer */
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , sizeof ( KSP_PIN ) ) ;
}
Pin = ( PKSP_PIN ) IoStack - > Parameters . DeviceIoControl . Type3InputBuffer ;
Entry = GetListEntry ( & DeviceExtension - > KsAudioDeviceList , Pin - > Reserved ) ;
ASSERT ( Entry ! = NULL ) ;
/* forward request to the filter implementing the property */
Status = KsSynchronousIoControlDevice ( Entry - > FileObject , KernelMode , IOCTL_KS_PROPERTY ,
( PVOID ) IoStack - > Parameters . DeviceIoControl . Type3InputBuffer ,
IoStack - > Parameters . DeviceIoControl . InputBufferLength ,
Irp - > UserBuffer ,
IoStack - > Parameters . DeviceIoControl . OutputBufferLength ,
& BytesReturned ) ;
return SetIrpIoStatus ( Irp , Status , BytesReturned ) ;
}
2009-02-23 21:51:41 +00:00
else if ( IsEqualGUIDAligned ( & Property - > Set , & KSPROPSETID_Sysaudio ) )
2009-02-20 17:52:47 +00:00
{
2009-08-17 17:23:35 +00:00
if ( Property - > Id = = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME )
{
if ( IoStack - > Parameters . DeviceIoControl . InputBufferLength < sizeof ( KSPROPERTY ) + sizeof ( ULONG ) )
{
/* invalid request */
return SetIrpIoStatus ( Irp , STATUS_UNSUCCESSFUL , sizeof ( KSPROPERTY ) + sizeof ( ULONG ) ) ;
}
Index = ( PULONG ) ( Property + 1 ) ;
if ( DeviceExtension - > NumberOfKsAudioDevices < = * Index )
{
/* invalid index */
return SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , 0 ) ;
}
Entry = GetListEntry ( & DeviceExtension - > KsAudioDeviceList , * Index ) ;
ASSERT ( Entry ! = NULL ) ;
BytesReturned = Entry - > DeviceName . Length + sizeof ( WCHAR ) ;
if ( IoStack - > Parameters . DeviceIoControl . OutputBufferLength < BytesReturned )
{
/* too small buffer */
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , BytesReturned ) ;
}
/* copy device name */
DeviceName = ( LPWSTR ) Irp - > UserBuffer ;
RtlMoveMemory ( DeviceName , Entry - > DeviceName . Buffer , Entry - > DeviceName . Length ) ;
DeviceName [ Entry - > DeviceName . Length / sizeof ( WCHAR ) ] = L ' \0 ' ;
return SetIrpIoStatus ( Irp , STATUS_SUCCESS , BytesReturned ) ;
}
2009-02-20 17:52:47 +00:00
if ( Property - > Id = = KSPROPERTY_SYSAUDIO_COMPONENT_ID )
{
if ( IoStack - > Parameters . DeviceIoControl . InputBufferLength < sizeof ( KSPROPERTY ) + sizeof ( ULONG ) )
{
/* too small buffer */
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , sizeof ( KSPROPERTY ) + sizeof ( ULONG ) ) ;
}
if ( IoStack - > Parameters . DeviceIoControl . OutputBufferLength < sizeof ( KSCOMPONENTID ) )
{
/* too small buffer */
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , sizeof ( KSCOMPONENTID ) ) ;
}
Index = ( PULONG ) ( Property + 1 ) ;
if ( DeviceExtension - > NumberOfKsAudioDevices < = * Index )
{
/* invalid index */
return SetIrpIoStatus ( Irp , STATUS_INVALID_PARAMETER , 0 ) ;
}
Entry = GetListEntry ( & DeviceExtension - > KsAudioDeviceList , * Index ) ;
ASSERT ( Entry ! = NULL ) ;
PropertyRequest . Set = KSPROPSETID_General ;
PropertyRequest . Id = KSPROPERTY_GENERAL_COMPONENTID ;
PropertyRequest . Flags = KSPROPERTY_TYPE_GET ;
/* call the filter */
2009-02-23 21:51:41 +00:00
Status = KsSynchronousIoControlDevice ( Entry - > FileObject , KernelMode , IOCTL_KS_PROPERTY , ( PVOID ) & PropertyRequest , sizeof ( KSPROPERTY ) , ( PVOID ) & ComponentId , sizeof ( KSCOMPONENTID ) , & BytesReturned ) ;
2009-02-20 17:52:47 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2009-04-03 17:06:16 +00:00
DPRINT ( " KsSynchronousIoControlDevice failed with %x for KSPROPERTY_GENERAL_COMPONENTID \n " , Status ) ;
2009-02-20 17:52:47 +00:00
return SetIrpIoStatus ( Irp , Status , 0 ) ;
}
RtlMoveMemory ( Irp - > UserBuffer , & ComponentId , sizeof ( KSCOMPONENTID ) ) ;
return SetIrpIoStatus ( Irp , STATUS_SUCCESS , sizeof ( KSCOMPONENTID ) ) ;
}
else if ( Property - > Id = = KSPROPERTY_SYSAUDIO_DEVICE_COUNT )
{
if ( IoStack - > Parameters . DeviceIoControl . OutputBufferLength < sizeof ( ULONG ) )
{
/* too small buffer */
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , sizeof ( ULONG ) ) ;
}
2009-02-27 11:22:16 +00:00
2009-02-20 17:52:47 +00:00
* ( ( PULONG ) Irp - > UserBuffer ) = DeviceExtension - > NumberOfKsAudioDevices ;
return SetIrpIoStatus ( Irp , STATUS_SUCCESS , sizeof ( ULONG ) ) ;
}
else if ( Property - > Id = = KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE )
{
if ( IoStack - > Parameters . DeviceIoControl . OutputBufferLength < sizeof ( ULONG ) )
{
/* too small buffer */
2009-03-25 19:14:04 +00:00
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , sizeof ( ULONG ) ) ;
2009-02-20 17:52:47 +00:00
}
if ( Property - > Flags & KSPROPERTY_TYPE_SET )
{
Index = ( PULONG ) Irp - > UserBuffer ;
return SysAudioOpenVirtualDevice ( Irp , * Index , DeviceExtension ) ;
}
}
else if ( Property - > Id = = KSPROPERTY_SYSAUDIO_INSTANCE_INFO )
{
2009-02-21 20:18:44 +00:00
if ( IoStack - > Parameters . DeviceIoControl . InputBufferLength < sizeof ( SYSAUDIO_INSTANCE_INFO ) )
2009-02-20 17:52:47 +00:00
{
/* too small buffer */
return SetIrpIoStatus ( Irp , STATUS_BUFFER_TOO_SMALL , sizeof ( SYSAUDIO_INSTANCE_INFO ) ) ;
}
/* get input parameter */
InstanceInfo = ( PSYSAUDIO_INSTANCE_INFO ) Property ;
if ( Property - > Flags & KSPROPERTY_TYPE_SET )
{
return SysAudioOpenVirtualDevice ( Irp , InstanceInfo - > DeviceNumber , DeviceExtension ) ;
}
}
}
RtlStringFromGUID ( & Property - > Set , & GuidString ) ;
2016-11-13 15:31:39 +00:00
DPRINT1 ( " Unhandled property Set |%S| Id %u Flags %x \n " , GuidString . Buffer , Property - > Id , Property - > Flags ) ;
2009-02-20 17:52:47 +00:00
RtlFreeUnicodeString ( & GuidString ) ;
2009-02-23 23:24:58 +00:00
return SetIrpIoStatus ( Irp , STATUS_UNSUCCESSFUL , 0 ) ;
2009-02-20 17:52:47 +00:00
}