1 /* 2 * PROJECT: ReactOS Sound System "MME Buddy" NT4 Library 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: lib/drivers/sound/mment4/control.c 5 * 6 * PURPOSE: Device control for NT4 audio devices 7 * 8 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org) 9 */ 10 11 #include "precomp.h" 12 13 #include <winioctl.h> 14 #include <ntddsnd.h> 15 16 #include <mmebuddy_debug.h> 17 18 /* 19 Convenience routine for getting the path of a device and opening it. 20 */ 21 MMRESULT 22 OpenNt4KernelSoundDevice( 23 IN PSOUND_DEVICE SoundDevice, 24 IN BOOLEAN ReadOnly, 25 OUT PHANDLE Handle) 26 { 27 PWSTR Path; 28 MMRESULT Result; 29 30 VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) ); 31 VALIDATE_MMSYS_PARAMETER( Handle ); 32 33 Result = GetSoundDeviceIdentifier(SoundDevice, (PVOID*) &Path); 34 if ( ! MMSUCCESS(Result) ) 35 { 36 SND_ERR(L"Unable to get sound device path\n"); 37 return TranslateInternalMmResult(Result); 38 } 39 40 SND_ASSERT( Path ); 41 42 return OpenKernelSoundDeviceByName(Path, ReadOnly, Handle); 43 } 44 45 /* 46 Device open/close. These are basically wrappers for the MME-Buddy 47 open and close routines, which provide a Windows device handle. 48 These may seem simple but as you can return pretty much anything 49 as the handle, we could just as easily return a structure etc. 50 */ 51 MMRESULT 52 OpenNt4SoundDevice( 53 IN PSOUND_DEVICE SoundDevice, 54 OUT PVOID* Handle) 55 { 56 SND_TRACE(L"Opening NT4 style sound device\n"); 57 58 VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) ); 59 VALIDATE_MMSYS_PARAMETER( Handle ); 60 61 return OpenNt4KernelSoundDevice(SoundDevice, FALSE, Handle); 62 } 63 64 MMRESULT 65 CloseNt4SoundDevice( 66 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, 67 IN PVOID Handle) 68 { 69 SND_TRACE(L"Closing NT4 style sound device\n"); 70 71 VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) ); 72 return CloseKernelSoundDevice((HANDLE) Handle); 73 } 74 75 /* 76 Provides an implementation for the "get capabilities" request, 77 using the standard IOCTLs used by NT4 sound drivers. 78 */ 79 MMRESULT 80 GetNt4SoundDeviceCapabilities( 81 IN PSOUND_DEVICE SoundDevice, 82 OUT PVOID Capabilities, 83 IN DWORD CapabilitiesSize) 84 { 85 MMRESULT Result; 86 MMDEVICE_TYPE DeviceType; 87 DWORD IoCtl; 88 HANDLE DeviceHandle; 89 90 /* If these are bad there's an internal error with MME-Buddy! */ 91 SND_ASSERT( SoundDevice ); 92 SND_ASSERT( Capabilities ); 93 SND_ASSERT( CapabilitiesSize > 0 ); 94 95 SND_TRACE(L"NT4 get-capabilities routine called\n"); 96 97 /* Get the device type */ 98 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 99 SND_ASSERT( Result == MMSYSERR_NOERROR ); 100 101 if ( ! MMSUCCESS(Result) ) 102 return TranslateInternalMmResult(Result); 103 104 /* Choose the appropriate IOCTL */ 105 if ( IS_WAVE_DEVICE_TYPE(DeviceType) ) 106 { 107 IoCtl = IOCTL_WAVE_GET_CAPABILITIES; 108 } 109 else if ( IS_MIDI_DEVICE_TYPE(DeviceType) ) 110 { 111 IoCtl = IOCTL_MIDI_GET_CAPABILITIES; 112 } 113 else 114 { 115 /* FIXME - need to support AUX and mixer devices */ 116 SND_ASSERT( FALSE ); 117 IoCtl = 0; 118 } 119 120 /* Get the capabilities information from the driver */ 121 Result = OpenNt4KernelSoundDevice(SoundDevice, TRUE, &DeviceHandle); 122 123 if ( ! MMSUCCESS(Result) ) 124 { 125 SND_ERR(L"Failed to open device\n"); 126 return TranslateInternalMmResult(Result); 127 } 128 129 Result = SyncOverlappedDeviceIoControl(DeviceHandle, 130 IoCtl, 131 Capabilities, 132 CapabilitiesSize, 133 NULL, 134 0, 135 NULL); 136 137 CloseKernelSoundDevice(DeviceHandle); 138 139 if ( ! MMSUCCESS(Result) ) 140 { 141 SND_ERR(L"Retrieval of capabilities information failed\n"); 142 Result = TranslateInternalMmResult(Result); 143 } 144 145 return Result; 146 } 147 148 /* 149 Querying/setting the format of a wave device. Querying format support 150 requires us to first open the device, whereas setting format is done 151 on an already opened device. 152 */ 153 MMRESULT 154 QueryNt4WaveDeviceFormatSupport( 155 IN PSOUND_DEVICE SoundDevice, 156 IN LPWAVEFORMATEX Format, 157 IN DWORD FormatSize) 158 { 159 MMRESULT Result; 160 HANDLE Handle; 161 162 SND_TRACE(L"NT4 wave format support querying routine called\n"); 163 164 VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) ); 165 VALIDATE_MMSYS_PARAMETER( Format ); 166 VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) ); 167 168 /* Get the device path */ 169 Result = OpenNt4KernelSoundDevice(SoundDevice, 170 FALSE, 171 &Handle); 172 173 if ( ! MMSUCCESS(Result) ) 174 { 175 SND_ERR(L"Unable to open kernel sound device\n"); 176 return TranslateInternalMmResult(Result); 177 } 178 179 Result = SyncOverlappedDeviceIoControl(Handle, 180 IOCTL_WAVE_QUERY_FORMAT, 181 (LPVOID) Format, 182 FormatSize, 183 NULL, 184 0, 185 NULL); 186 187 if ( ! MMSUCCESS(Result) ) 188 { 189 SND_ERR(L"Sync overlapped I/O failed - MMSYS_ERROR %d\n", Result); 190 Result = TranslateInternalMmResult(Result); 191 } 192 193 CloseKernelSoundDevice(Handle); 194 195 return MMSYSERR_NOERROR; 196 } 197 198 MMRESULT 199 SetNt4WaveDeviceFormat( 200 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, 201 IN DWORD DeviceId, 202 IN LPWAVEFORMATEX Format, 203 IN DWORD FormatSize) 204 { 205 MMRESULT Result; 206 HANDLE Handle; 207 208 VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) ); 209 VALIDATE_MMSYS_PARAMETER( Format ); 210 VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) ); 211 212 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); 213 214 if ( ! MMSUCCESS(Result) ) 215 return TranslateInternalMmResult(Result); 216 217 SND_TRACE(L"Setting wave device format on handle %x\n", Handle); 218 219 Result = SyncOverlappedDeviceIoControl(Handle, 220 IOCTL_WAVE_SET_FORMAT, 221 (LPVOID) Format, 222 FormatSize, 223 NULL, 224 0, 225 NULL); 226 227 if ( ! MMSUCCESS(Result) ) 228 return TranslateInternalMmResult(Result); 229 230 return MMSYSERR_NOERROR; 231 } 232 233 #if 0 234 MMRESULT 235 SubmitNt4WaveHeader( 236 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, 237 IN PWAVEHDR WaveHeader) 238 { 239 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance ); 240 VALIDATE_MMSYS_PARAMETER( WaveHeader ); 241 242 SND_TRACE(L"Submitting wave header %p (in sound thread)\n", WaveHeader); 243 244 /* TODO: This should only submit the header to the device, nothing more! */ 245 } 246 #endif 247