[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 }
121
122 /* Get the capabilities information from the driver */
123 Result = OpenNt4KernelSoundDevice(SoundDevice, TRUE, &DeviceHandle);
124
125 if ( ! MMSUCCESS(Result) )
126 {
127 SND_ERR(L"Failed to open device");
128 return TranslateInternalMmResult(Result);
129 }
130
131 Result = SyncOverlappedDeviceIoControl(DeviceHandle,
132 IoCtl,
133 Capabilities,
134 CapabilitiesSize,
135 NULL,
136 0,
137 NULL);
138
139 CloseKernelSoundDevice(DeviceHandle);
140
141 if ( ! MMSUCCESS(Result) )
142 {
143 SND_ERR(L"Retrieval of capabilities information failed\n");
144 Result = TranslateInternalMmResult(Result);
145 }
146
147 return Result;
148 }
149
150 /*
151 Querying/setting the format of a wave device. Querying format support
152 requires us to first open the device, whereas setting format is done
153 on an already opened device.
154 */
155 MMRESULT
156 QueryNt4WaveDeviceFormatSupport(
157 IN PSOUND_DEVICE SoundDevice,
158 IN LPWAVEFORMATEX Format,
159 IN DWORD FormatSize)
160 {
161 MMRESULT Result;
162 HANDLE Handle;
163
164 SND_TRACE(L"NT4 wave format support querying routine called\n");
165
166 VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
167 VALIDATE_MMSYS_PARAMETER( Format );
168 VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) );
169
170 /* Get the device path */
171 Result = OpenNt4KernelSoundDevice(SoundDevice,
172 FALSE,
173 &Handle);
174
175 if ( ! MMSUCCESS(Result) )
176 {
177 SND_ERR(L"Unable to open kernel sound device\n");
178 return TranslateInternalMmResult(Result);
179 }
180
181 Result = SyncOverlappedDeviceIoControl(Handle,
182 IOCTL_WAVE_QUERY_FORMAT,
183 (LPVOID) Format,
184 FormatSize,
185 NULL,
186 0,
187 NULL);
188
189 if ( ! MMSUCCESS(Result) )
190 {
191 SND_ERR(L"Sync overlapped I/O failed - MMSYS_ERROR %d\n", Result);
192 Result = TranslateInternalMmResult(Result);
193 }
194
195 CloseKernelSoundDevice(Handle);
196
197 return MMSYSERR_NOERROR;
198 }
199
200 MMRESULT
201 SetNt4WaveDeviceFormat(
202 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
203 IN DWORD DeviceId,
204 IN LPWAVEFORMATEX Format,
205 IN DWORD FormatSize)
206 {
207 MMRESULT Result;
208 HANDLE Handle;
209
210 VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
211 VALIDATE_MMSYS_PARAMETER( Format );
212 VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) );
213
214 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
215
216 if ( ! MMSUCCESS(Result) )
217 return TranslateInternalMmResult(Result);
218
219 SND_TRACE(L"Setting wave device format on handle %x\n", Handle);
220
221 Result = SyncOverlappedDeviceIoControl(Handle,
222 IOCTL_WAVE_SET_FORMAT,
223 (LPVOID) Format,
224 FormatSize,
225 NULL,
226 0,
227 NULL);
228
229 if ( ! MMSUCCESS(Result) )
230 return TranslateInternalMmResult(Result);
231
232 return MMSYSERR_NOERROR;
233 }
234
235 #if 0
236 MMRESULT
237 SubmitNt4WaveHeader(
238 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
239 IN PWAVEHDR WaveHeader)
240 {
241 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
242 VALIDATE_MMSYS_PARAMETER( WaveHeader );
243
244 SND_TRACE(L"Submitting wave header %p (in sound thread)\n", WaveHeader);
245
246 /* TODO: This should only submit the header to the device, nothing more! */
247 }
248 #endif