ReactOS 0.4.15-dev-5666-gc548b97
mmewrap.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Sound System "MME Buddy" Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/drivers/sound/mmebuddy/mmewrap.c
5 *
6 * PURPOSE: Interface between MME functions and MME Buddy's own.
7 *
8 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
9*/
10
11#include "precomp.h"
12
13
14/*
15 Sets the device into running or stopped state
16*/
17
20 IN DWORD_PTR PrivateHandle,
21 IN BOOL bStart)
22{
25 PSOUND_DEVICE SoundDevice;
26 PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
27 BOOL OldState;
28
29 VALIDATE_MMSYS_PARAMETER( PrivateHandle );
30 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
31
33
34 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
35 if ( ! MMSUCCESS(Result) )
37
38 /* Get the function table, and validate it */
40 if ( ! MMSUCCESS(Result) )
42
43 SND_ASSERT( FunctionTable->SetState );
44 if ( FunctionTable->SetState == NULL )
45 {
46 /* FIXME */
48 }
49 /* Try change state */
50 Result = FunctionTable->SetState(SoundDeviceInstance, bStart);
51
52 if ( MMSUCCESS(Result) )
53 {
54 /* Get old audio stream state */
55 OldState = SoundDeviceInstance->bPaused;
56
57 /* Store audio stream pause state */
58 SoundDeviceInstance->bPaused = !bStart;
59
60 if (SoundDeviceInstance->bPaused == FALSE && OldState)
61 {
62 InitiateSoundStreaming(SoundDeviceInstance);
63 }
64 }
65
66 return Result;
67}
68
69/*
70 Call the client application when something interesting happens (MME API
71 defines "interesting things" as device open, close, and buffer
72 completion.)
73*/
74VOID
76 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
79{
80 SND_ASSERT( SoundDeviceInstance );
81
82 SND_TRACE(L"MME client callback - message %d, parameter %d\n",
83 (int) Message,
84 (int) Parameter);
85
86 if ( SoundDeviceInstance->WinMM.ClientCallback )
87 {
88 DriverCallback(SoundDeviceInstance->WinMM.ClientCallback,
89 HIWORD(SoundDeviceInstance->WinMM.Flags),
90 SoundDeviceInstance->WinMM.Handle,
91 Message,
92 SoundDeviceInstance->WinMM.ClientCallbackInstanceData,
94 0);
95 }
96}
97
98/*
99 This is a helper function to alleviate some of the repetition involved with
100 implementing the various MME message functions.
101*/
105 IN DWORD DeviceId,
107 IN DWORD CapabilitiesSize)
108{
109 PSOUND_DEVICE SoundDevice;
111
112 SND_TRACE(L"MME *_GETCAPS for device %d of type %d\n", DeviceId, DeviceType);
113
114 /* FIXME: Validate device ID */
117
118 /* Our parameter checks are done elsewhere */
119
120 Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
121
122 if ( ! MMSUCCESS(Result) )
123 return Result;
124
125 return GetSoundDeviceCapabilities(SoundDevice,
126 DeviceId,
128 CapabilitiesSize);
129}
130
134 IN UINT DeviceId,
135 IN LPWAVEOPENDESC OpenParameters,
136 IN DWORD Flags,
137 OUT DWORD_PTR* PrivateHandle)
138{
141 PSOUND_DEVICE SoundDevice;
142 PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
144
145 SND_TRACE(L"Opening device");
146
148 VALIDATE_MMSYS_PARAMETER( OpenParameters );
149
150 Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
151 if ( ! MMSUCCESS(Result) )
153
155 {
156 Format = OpenParameters->lpFormat;
157
158 /* Does this device support the format? */
160 if ( ! MMSUCCESS(Result) )
161 {
162 SND_ERR(L"Format not supported\n");
164 }
165
166 /* If the caller just wanted to know if a format is supported, end here */
167 if ( Flags & WAVE_FORMAT_QUERY )
168 return MMSYSERR_NOERROR;
169 }
170
171 /* Check that winmm gave us a private handle to fill */
172 VALIDATE_MMSYS_PARAMETER( PrivateHandle );
173
174 /* Create a sound device instance and open the sound device */
175 Result = CreateSoundDeviceInstance(SoundDevice, &SoundDeviceInstance);
176 if ( ! MMSUCCESS(Result) )
178
179 Result = SetWaveDeviceFormat(SoundDeviceInstance, DeviceId, Format, sizeof(WAVEFORMATEX));
180 if ( ! MMSUCCESS(Result) )
181 {
182 /* TODO: Destroy sound instance */
184 }
185
186 /* Store the device instance pointer in the private handle */
187 *PrivateHandle = (DWORD_PTR)SoundDeviceInstance;
188
189 /* Store the additional information we were given - FIXME: Need flags! */
190 SetSoundDeviceInstanceMmeData(SoundDeviceInstance,
191 (HDRVR)OpenParameters->hWave, /* works because LPMIXEROPENDESC/etc has also the handle as first member */
192 OpenParameters->dwCallback,
193 OpenParameters->dwInstance,
194 Flags);
195
198 {
199 /* Let the application know the device is open */
200
207 else
209
211
212 NotifyMmeClient(SoundDeviceInstance,
213 Message,
214 0);
215
217 }
218
219 SND_TRACE(L"device now open\n");
220
221 return MMSYSERR_NOERROR;
222}
223
226 IN DWORD_PTR PrivateHandle)
227{
229 PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
230 PSOUND_DEVICE SoundDevice;
232 UINT Message = 0;
233
234 SND_TRACE(L"Closing wave device (WIDM_CLOSE / WODM_CLOSE)\n");
235
236 VALIDATE_MMSYS_PARAMETER( PrivateHandle );
237 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
238
239 if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance) )
241
242 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
243 if ( ! MMSUCCESS(Result) )
245
246 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
247 if ( ! MMSUCCESS(Result) )
249
250
251 /* TODO: Check device is stopped! */
252
253
255 {
257
266
267 /* TODO: Work with MIDI devices too */
268 NotifyMmeClient(SoundDeviceInstance,
269 Message,
270 0);
272 }
273
274 Result = DestroySoundDeviceInstance(SoundDeviceInstance);
275
276 return Result;
277}
278
281 IN DWORD_PTR PrivateHandle)
282{
283 PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
284
285 SND_TRACE(L"Resetting wave device (WODM_RESET)\n");
286
287 VALIDATE_MMSYS_PARAMETER( PrivateHandle );
288 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
289
290 return StopStreaming(SoundDeviceInstance);
291}
292
296 IN DWORD DeviceId,
298 IN DWORD InterfaceLength,
299 OUT DWORD * InterfaceSize)
300{
302 PSOUND_DEVICE SoundDevice;
304
305 Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
306 if ( ! MMSUCCESS(Result) )
308
310 if ( ! MMSUCCESS(Result) )
312
313 if ( FunctionTable->GetDeviceInterfaceString == NULL )
314 {
315 /* querying device interface string / size not supported */
317 }
318
319 /* Call the driver */
320 Result = FunctionTable->GetDeviceInterfaceString(DeviceType, DeviceId, Interface, InterfaceLength, InterfaceSize);
321
322 return Result;
323}
324
325
329 IN DWORD DeviceId,
330 IN DWORD_PTR PrivateHandle,
331 IN MMTIME* Time,
332 IN DWORD Size)
333{
335 PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
336 PSOUND_DEVICE SoundDevice;
338
339 VALIDATE_MMSYS_PARAMETER( PrivateHandle );
340 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
341
342 if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance) )
344
345 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
346 if ( ! MMSUCCESS(Result) )
348
349 if ( Size != sizeof(MMTIME) )
350 return MMSYSERR_INVALPARAM;
351
353 if ( ! MMSUCCESS(Result) )
355
356 if ( FunctionTable->GetPos == NULL )
357 {
358 /* This indicates bad practice, really! If you can open, why not close?! */
360 }
361
362 /* Call the driver */
363 Result = FunctionTable->GetPos(SoundDeviceInstance, Time);
364
365 return Result;
366}
367
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev, UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
static const WCHAR Message[]
Definition: register.c:74
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
_In_ PVOID Parameter
Definition: ldrtypes.h:241
DeviceType
Definition: mmdrv.h:42
struct _SOUND_DEVICE_INSTANCE * PSOUND_DEVICE_INSTANCE
VOID AcquireEntrypointMutex(IN MMDEVICE_TYPE DeviceType)
Definition: reentrancy.c:75
MMRESULT SetSoundDeviceInstanceMmeData(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN HDRVR MmeHandle, IN DWORD_PTR ClientCallback, IN DWORD_PTR ClientCallbackData, IN DWORD Flags)
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
VOID InitiateSoundStreaming(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
Definition: streaming.c:383
MMRESULT GetSoundDeviceCapabilities(IN PSOUND_DEVICE SoundDevice, IN DWORD DeviceId, OUT PVOID Capabilities, IN DWORD CapabilitiesSize)
Definition: capabilities.c:24
MMRESULT GetSoundDeviceFunctionTable(IN PSOUND_DEVICE SoundDevice, OUT PMMFUNCTION_TABLE *FunctionTable)
Definition: functiontable.c:47
MMRESULT SetWaveDeviceFormat(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN DWORD DeviceId, IN LPWAVEFORMATEX Format, IN DWORD FormatSize)
Definition: format.c:49
MMRESULT StopStreaming(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
Definition: streaming.c:334
UCHAR MMDEVICE_TYPE
Definition: mmebuddy.h:88
MMRESULT GetSoundDeviceFromInstance(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, OUT PSOUND_DEVICE *SoundDevice)
MMRESULT TranslateInternalMmResult(IN MMRESULT Result)
Definition: utility.c:132
MMRESULT DestroySoundDeviceInstance(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
MMRESULT GetSoundDeviceType(IN PSOUND_DEVICE SoundDevice, OUT PMMDEVICE_TYPE DeviceType)
Definition: devicelist.c:346
MMRESULT QueryWaveDeviceFormatSupport(IN PSOUND_DEVICE SoundDevice, IN LPWAVEFORMATEX Format, IN DWORD FormatSize)
Definition: format.c:14
#define MMSUCCESS(result)
Definition: mmebuddy.h:80
BOOLEAN IsValidSoundDeviceInstance(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
VOID ReleaseEntrypointMutex(IN MMDEVICE_TYPE DeviceType)
Definition: reentrancy.c:92
MMRESULT CreateSoundDeviceInstance(IN PSOUND_DEVICE SoundDevice, OUT PSOUND_DEVICE_INSTANCE *SoundDeviceInstance)
MMRESULT GetSoundDevice(IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceIndex, OUT PSOUND_DEVICE *Device)
Definition: devicelist.c:289
#define SND_TRACE(...)
#define SND_ERR(...)
#define SND_ASSERT(condition)
MMRESULT MmeOpenDevice(IN MMDEVICE_TYPE DeviceType, IN UINT DeviceId, IN LPWAVEOPENDESC OpenParameters, IN DWORD Flags, OUT DWORD_PTR *PrivateHandle)
Definition: mmewrap.c:132
MMRESULT MmeCloseDevice(IN DWORD_PTR PrivateHandle)
Definition: mmewrap.c:225
MMRESULT MmeGetDeviceInterfaceString(IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceId, IN LPWSTR Interface, IN DWORD InterfaceLength, OUT DWORD *InterfaceSize)
Definition: mmewrap.c:294
MMRESULT MmeGetPosition(IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceId, IN DWORD_PTR PrivateHandle, IN MMTIME *Time, IN DWORD Size)
Definition: mmewrap.c:327
MMRESULT MmeSetState(IN DWORD_PTR PrivateHandle, IN BOOL bStart)
Definition: mmewrap.c:19
VOID NotifyMmeClient(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN UINT Message, IN DWORD_PTR Parameter)
Definition: mmewrap.c:75
MMRESULT MmeResetWavePlayback(IN DWORD_PTR PrivateHandle)
Definition: mmewrap.c:280
MMRESULT MmeGetSoundDeviceCapabilities(IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceId, IN PVOID Capabilities, IN DWORD CapabilitiesSize)
Definition: mmewrap.c:103
#define MIM_OPEN
Definition: mmsystem.h:241
#define MIM_CLOSE
Definition: mmsystem.h:242
UINT MMRESULT
Definition: mmsystem.h:962
#define WOM_OPEN
Definition: mmsystem.h:181
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define WAVE_FORMAT_QUERY
Definition: mmsystem.h:188
#define WOM_CLOSE
Definition: mmsystem.h:182
#define WIM_CLOSE
Definition: mmsystem.h:185
#define MOM_CLOSE
Definition: mmsystem.h:248
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
#define MOM_OPEN
Definition: mmsystem.h:247
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WIM_OPEN
Definition: mmsystem.h:184
static PLARGE_INTEGER Time
Definition: time.c:105
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
@ MIXER_DEVICE_TYPE
Definition: sndtypes.h:33
@ MIDI_OUT_DEVICE_TYPE
Definition: sndtypes.h:31
@ WAVE_IN_DEVICE_TYPE
Definition: sndtypes.h:28
@ WAVE_OUT_DEVICE_TYPE
Definition: sndtypes.h:29
@ MIDI_IN_DEVICE_TYPE
Definition: sndtypes.h:30
#define IS_VALID_SOUND_DEVICE_TYPE(x)
Definition: sndtypes.h:43
#define IS_MIDI_DEVICE_TYPE(x)
Definition: sndtypes.h:49
#define IS_WAVE_DEVICE_TYPE(x)
Definition: sndtypes.h:46
#define IS_MIXER_DEVICE_TYPE(x)
Definition: sndtypes.h:55
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define HIWORD(l)
Definition: typedefs.h:247
#define OUT
Definition: typedefs.h:40
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
static WLX_DISPATCH_VERSION_1_4 FunctionTable
Definition: wlx.c:722
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
WCHAR * LPWSTR
Definition: xmlstorage.h:184