1 /* 2 * PROJECT: ReactOS Sound System 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/win32/sndblst/sndblst.c 5 * 6 * PURPOSE: Sound Blaster MME User-Mode Driver 7 * 8 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org) 9 * 10 * NOTES: Currently very experimental and being used as a guinea-pig for 11 * changes to the MME-Buddy libraries. 12 * TODO: Adhere to maximum device name length! 13 */ 14 15 #define WIN32_NO_STATUS 16 #define _INC_WINDOWS 17 #define COM_NO_WINDOWS_H 18 19 #include <stdarg.h> 20 21 #include <windef.h> 22 #include <winuser.h> 23 24 //#include <ntddsnd.h> 25 #include <sndtypes.h> 26 #include <mmddk.h> 27 #include <mmebuddy.h> 28 #include <mment4.h> 29 #include <mmebuddy_debug.h> 30 //#include <debug.h> 31 32 /* TODO: Give individual device names if someone has > 1 card */ 33 PWSTR SBWaveOutDeviceName = L"ROS Sound Blaster Wave Out"; 34 PWSTR SBWaveInDeviceName = L"ROS Sound Blaster Wave In"; 35 PWSTR SBMidiOutDeviceName = L"ROS Sound Blaster Midi Out"; 36 PWSTR SBMidiInDeviceName = L"ROS Sound Blaster Midi In"; 37 PWSTR SBAuxDeviceName = L"ROS Sound Blaster Aux"; 38 PWSTR SBMixerDeviceName = L"ROS Sound Blaster Mixer"; 39 /* TODO: Mixer etc */ 40 41 MMRESULT 42 GetSoundBlasterDeviceCapabilities( 43 IN PSOUND_DEVICE SoundDevice, 44 IN DWORD DeviceId, 45 OUT PVOID Capabilities, 46 IN DWORD CapabilitiesSize) 47 { 48 MMRESULT Result; 49 MMDEVICE_TYPE DeviceType; 50 51 SND_ASSERT( SoundDevice ); 52 SND_ASSERT( Capabilities ); 53 54 SND_TRACE(L"Sndblst - GetSoundBlasterDeviceCapabilities\n"); 55 56 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 57 SND_ASSERT( Result == MMSYSERR_NOERROR ); 58 59 /* Use the default method of obtaining device capabilities */ 60 Result = GetNt4SoundDeviceCapabilities(SoundDevice, 61 Capabilities, 62 CapabilitiesSize); 63 64 if ( ! MMSUCCESS(Result) ) 65 return Result; 66 67 /* Inject the appropriate device name */ 68 switch ( DeviceType ) 69 { 70 case WAVE_OUT_DEVICE_TYPE : 71 { 72 LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities; 73 CopyWideString(WaveOutCaps->szPname, SBWaveOutDeviceName); 74 break; 75 } 76 case WAVE_IN_DEVICE_TYPE : 77 { 78 LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities; 79 CopyWideString(WaveInCaps->szPname, SBWaveInDeviceName); 80 break; 81 } 82 case MIDI_OUT_DEVICE_TYPE : 83 { 84 LPMIDIOUTCAPS MidiOutCaps = (LPMIDIOUTCAPS) Capabilities; 85 CopyWideString(MidiOutCaps->szPname, SBMidiOutDeviceName); 86 break; 87 } 88 case MIDI_IN_DEVICE_TYPE : 89 { 90 LPMIDIINCAPS MidiInCaps = (LPMIDIINCAPS) Capabilities; 91 CopyWideString(MidiInCaps->szPname, SBMidiInDeviceName); 92 break; 93 } 94 case AUX_DEVICE_TYPE : 95 { 96 LPAUXCAPS AuxCaps = (LPAUXCAPS) Capabilities; 97 CopyWideString(AuxCaps->szPname, SBAuxDeviceName); 98 break; 99 } 100 case MIXER_DEVICE_TYPE : 101 { 102 LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities; 103 CopyWideString(MixerCaps->szPname, SBMixerDeviceName); 104 break; 105 } 106 } 107 108 return MMSYSERR_NOERROR; 109 } 110 111 BOOLEAN FoundDevice( 112 UCHAR DeviceType, 113 PWSTR DevicePath) 114 { 115 MMRESULT Result; 116 PSOUND_DEVICE SoundDevice = NULL; 117 MMFUNCTION_TABLE FuncTable; 118 PWSTR PathCopy; 119 120 SND_TRACE(L"(Callback) Found device: %wS\n", DevicePath); 121 122 PathCopy = AllocateWideString(wcslen(DevicePath)); 123 124 if ( ! PathCopy ) 125 return FALSE; 126 127 CopyWideString(PathCopy, DevicePath); 128 129 Result = ListSoundDevice(DeviceType, (PVOID) PathCopy, &SoundDevice); 130 131 if ( ! MMSUCCESS(Result) ) 132 return FALSE; 133 134 /* Set up our function table */ 135 ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE)); 136 FuncTable.GetCapabilities = GetSoundBlasterDeviceCapabilities; 137 FuncTable.QueryWaveFormatSupport = QueryNt4WaveDeviceFormatSupport; 138 FuncTable.SetWaveFormat = SetNt4WaveDeviceFormat; 139 FuncTable.Open = OpenNt4SoundDevice; 140 FuncTable.Close = CloseNt4SoundDevice; 141 FuncTable.CommitWaveBuffer = WriteFileEx_Committer; 142 //FuncTable.SubmitWaveHeaderToDevice = SubmitWaveHeaderToDevice; 143 144 SetSoundDeviceFunctionTable(SoundDevice, &FuncTable); 145 146 return TRUE; 147 } 148 149 LONG APIENTRY 150 DriverProc( 151 DWORD DriverId, 152 HANDLE DriverHandle, 153 UINT Message, 154 LONG Parameter1, 155 LONG Parameter2) 156 { 157 MMRESULT Result; 158 159 switch ( Message ) 160 { 161 case DRV_LOAD : 162 { 163 SND_TRACE(L"DRV_LOAD\n"); 164 165 Result = InitEntrypointMutexes(); 166 167 if ( ! MMSUCCESS(Result) ) 168 return 0L; 169 170 Result = EnumerateNt4ServiceSoundDevices(L"sndblst", 171 0, 172 FoundDevice); 173 174 if ( ! MMSUCCESS(Result) ) 175 { 176 CleanupEntrypointMutexes(); 177 178 UnlistAllSoundDevices(); 179 180 return 0L; 181 } 182 183 /* 184 PSOUND_DEVICE snd; 185 GetSoundDevice(WAVE_OUT_DEVICE_TYPE, 0, &snd); 186 GetSoundDevice(AUX_DEVICE_TYPE, 0, &snd); 187 GetSoundDevice(AUX_DEVICE_TYPE, 1, &snd); 188 GetSoundDevice(AUX_DEVICE_TYPE, 2, &snd); 189 */ 190 191 SND_TRACE(L"Initialisation complete\n"); 192 193 return 1L; 194 } 195 196 case DRV_FREE : 197 { 198 SND_TRACE(L"DRV_FREE\n"); 199 200 /* TODO: Clean up the path names! */ 201 UnlistAllSoundDevices(); 202 203 CleanupEntrypointMutexes(); 204 205 SND_TRACE(L"Unfreed memory blocks: %d\n", 206 GetMemoryAllocationCount()); 207 208 return 1L; 209 } 210 211 case DRV_ENABLE : 212 case DRV_DISABLE : 213 { 214 SND_TRACE(L"DRV_ENABLE / DRV_DISABLE\n"); 215 return 1L; 216 } 217 218 case DRV_OPEN : 219 case DRV_CLOSE : 220 { 221 SND_TRACE(L"DRV_OPEN / DRV_CLOSE\n"); 222 return 1L; 223 } 224 225 case DRV_QUERYCONFIGURE : 226 { 227 SND_TRACE(L"DRV_QUERYCONFIGURE\n"); 228 return 0L; 229 } 230 case DRV_CONFIGURE : 231 return DRVCNF_OK; 232 233 default : 234 SND_TRACE(L"Unhandled message %d\n", Message); 235 return DefDriverProc(DriverId, 236 DriverHandle, 237 Message, 238 Parameter1, 239 Parameter2); 240 } 241 } 242 243 BOOL WINAPI DllMain( 244 HINSTANCE hinstDLL, 245 DWORD fdwReason, 246 LPVOID lpvReserved) 247 { 248 switch ( fdwReason ) 249 { 250 case DLL_PROCESS_ATTACH : 251 SND_TRACE(L"DLL_PROCESS_ATTACH\n"); 252 break; 253 case DLL_PROCESS_DETACH : 254 SND_TRACE(L"DLL_PROCESS_DETACH\n"); 255 break; 256 case DLL_THREAD_ATTACH : 257 SND_TRACE(L"DLL_THREAD_ATTACH\n"); 258 break; 259 case DLL_THREAD_DETACH : 260 SND_TRACE(L"DLL_THREAD_DETACH\n"); 261 break; 262 } 263 264 return TRUE; 265 } 266