xref: /reactos/dll/win32/sndblst/sndblst.c (revision c2c66aff)
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");
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