1 /*
2  * PROJECT:     ReactOS Sound System "MME Buddy" Library
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        lib/drivers/sound/mmebuddy/capabilities.c
5  *
6  * PURPOSE:     Queries sound devices for their capabilities.
7  *
8  * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
9 */
10 
11 #include "precomp.h"
12 
13 /*
14     Obtains the capabilities of a sound device. This routine ensures that the
15     supplied CapabilitiesSize parameter at least meets the minimum size of the
16     relevant capabilities structure.
17 
18     Ultimately, it will call the GetCapabilities function specified in the
19     sound device's function table. Note that there are several of these, in a
20     union. This is simply to avoid manually typecasting when implementing the
21     functions.
22 */
23 MMRESULT
GetSoundDeviceCapabilities(IN PSOUND_DEVICE SoundDevice,IN DWORD DeviceId,OUT PVOID Capabilities,IN DWORD CapabilitiesSize)24 GetSoundDeviceCapabilities(
25     IN  PSOUND_DEVICE SoundDevice,
26     IN  DWORD DeviceId,
27     OUT PVOID Capabilities,
28     IN  DWORD CapabilitiesSize)
29 {
30     MMDEVICE_TYPE DeviceType;
31     PMMFUNCTION_TABLE FunctionTable;
32     BOOLEAN GoodSize = FALSE;
33     MMRESULT Result;
34 
35     VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
36     VALIDATE_MMSYS_PARAMETER( Capabilities );
37     VALIDATE_MMSYS_PARAMETER( CapabilitiesSize > 0 );
38 
39     /* Obtain the device type */
40     Result = GetSoundDeviceType(SoundDevice, &DeviceType);
41     SND_ASSERT( Result == MMSYSERR_NOERROR );
42 
43     if ( ! MMSUCCESS(Result) )
44         return TranslateInternalMmResult(Result);
45 
46     /* Obtain the function table */
47     Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
48     SND_ASSERT( Result == MMSYSERR_NOERROR );
49 
50     if ( ! MMSUCCESS(Result) )
51         return TranslateInternalMmResult(Result);
52 
53     SND_ASSERT( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
54 
55     /* Check that the capabilities structure is of a valid size */
56     switch ( DeviceType )
57     {
58         case WAVE_OUT_DEVICE_TYPE :
59         {
60             GoodSize = CapabilitiesSize >= sizeof(WAVEOUTCAPSW);
61             break;
62         }
63         case WAVE_IN_DEVICE_TYPE :
64         {
65             GoodSize = CapabilitiesSize >= sizeof(WAVEINCAPSW);
66             break;
67         }
68         case MIDI_OUT_DEVICE_TYPE :
69         {
70             GoodSize = CapabilitiesSize >= sizeof(MIDIOUTCAPSW);
71             break;
72         }
73         case MIDI_IN_DEVICE_TYPE :
74         {
75             GoodSize = CapabilitiesSize >= sizeof(MIDIINCAPSW);
76             break;
77         }
78         case AUX_DEVICE_TYPE :
79         {
80             GoodSize = CapabilitiesSize >= sizeof(AUXCAPSW);
81             break;
82         }
83         case MIXER_DEVICE_TYPE :
84         {
85             GoodSize = CapabilitiesSize >= sizeof(MIXERCAPSW);
86             break;
87         }
88     };
89 
90     if ( ! GoodSize )
91     {
92         SND_ERR(L"Device capabilities structure too small\n");
93         return MMSYSERR_INVALPARAM;
94     }
95 
96     /* Call the "get capabilities" function within the function table */
97     SND_ASSERT( FunctionTable->GetCapabilities );
98 
99     if ( ! FunctionTable->GetCapabilities )
100         return MMSYSERR_NOTSUPPORTED;
101 
102     return FunctionTable->GetCapabilities(SoundDevice,
103                                           DeviceId,
104                                           Capabilities,
105                                           CapabilitiesSize);
106 }
107