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