ReactOS 0.4.15-dev-7961-gdcf9eb0
common.c
Go to the documentation of this file.
1/*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS Multimedia
5 * FILE: dll/win32/mmdrv/common.c
6 * PURPOSE: Multimedia User Mode Driver (Common functions)
7 * PROGRAMMER: Andrew Greenwood
8 * UPDATE HISTORY:
9 * Jan 14, 2007: Created
10 */
11
12#include "mmdrv.h"
13
14#define NDEBUG
15#include <debug.h>
16
17/*
18 Translates errors to MMRESULT codes.
19*/
20
23{
24 switch ( error_code )
25 {
26 case NO_ERROR :
27 case ERROR_IO_PENDING :
28 return MMSYSERR_NOERROR;
29
30 case ERROR_BUSY :
31 return MMSYSERR_ALLOCATED;
32
36
38 return MMSYSERR_NOMEM;
39
42
45 };
46
47 /* If all else fails, it's just a plain old error */
48
49 return MMSYSERR_ERROR;
50}
51
52
53/*
54 Obtains a device count for a specific kind of device.
55*/
56
59{
60 UINT index = 0;
62
63 /* Cycle through devices until an error occurs */
64
66 {
68 index ++;
69 }
70
71 DPRINT("Found %d devices of type %d\n", index, device_type);
72
73 return index;
74}
75
76
77/*
78 Obtains device capabilities. This could either be done as individual
79 functions for wave, MIDI and aux, or like this. I chose this method as
80 it centralizes everything.
81*/
82
86 UINT device_id,
87 DWORD_PTR capabilities,
88 DWORD capabilities_size)
89{
93 DWORD bytes_returned;
94 BOOL device_io_result;
95
96 ASSERT(capabilities);
97
98 /* Choose the right IOCTL for the job */
99
102 else if ( IsMidiDevice(device_type) )
104 else if ( IsAuxDevice(device_type) )
105 return MMSYSERR_NOTSUPPORTED; /* TODO */
106 else
108
110 device_id,
112 &handle);
113
114 if ( result != MMSYSERR_NOERROR )
115 {
116 DPRINT("Failed to open kernel device\n");
117 return result;
118 }
119
120 device_io_result = DeviceIoControl(handle,
121 ioctl,
122 NULL,
123 0,
124 (LPVOID) capabilities,
125 capabilities_size,
126 &bytes_returned,
127 NULL);
128
129 /* Translate result */
130
131 if ( device_io_result )
133 else
135
136 /* Clean up and return */
137
139
140 return result;
141}
142
143
144/*
145 A wrapper around OpenKernelDevice that creates a session,
146 opens the kernel device, initializes session data and notifies
147 the client (application) that the device has been opened. Again,
148 this supports any device type and the only real difference is
149 the open descriptor.
150*/
151
152DWORD
155 UINT device_id,
156 PVOID open_descriptor,
157 DWORD flags,
158 DWORD_PTR private_handle)
159{
160 SessionInfo* session_info;
163
164 /* This will automatically check for duplicate sessions */
165 result = CreateSession(device_type, device_id, &session_info);
166
167 if ( result != MMSYSERR_NOERROR )
168 {
169 DPRINT("Couldn't allocate session info\n");
170 return result;
171 }
172
174 device_id,
176 &session_info->kernel_device_handle);
177
178 if ( result != MMSYSERR_NOERROR )
179 {
180 DPRINT("Failed to open kernel device\n");
181 DestroySession(session_info);
182 return result;
183 }
184
185 /* Set common session data */
186
187 session_info->flags = flags;
188
189 /* Set wave/MIDI specific data */
190
192 {
193 LPWAVEOPENDESC wave_open_desc = (LPWAVEOPENDESC) open_descriptor;
194 session_info->callback = wave_open_desc->dwCallback;
195 session_info->mme_wave_handle = wave_open_desc->hWave;
196 session_info->app_user_data = wave_open_desc->dwInstance;
197 }
198 else
199 {
200 DPRINT("Only wave devices are supported at present!\n");
201 DestroySession(session_info);
203 }
204
205 /* Start the processing thread */
206
207 result = StartSessionThread(session_info);
208
209 if ( result != MMSYSERR_NOERROR )
210 {
211 DestroySession(session_info);
212 return result;
213 }
214
215 /* Store the session info */
216
217 *((SessionInfo**)private_handle) = session_info;
218
219 /* Send the right message */
220
224 (device_type == MidiInDevice) ? MIM_OPEN : 0xFFFFFFFF;
225
226 NotifyClient(session_info, message, 0, 0);
227
228 return MMSYSERR_NOERROR;
229}
230
231
232/*
233 Attempts to close a device. This can fail if playback/recording has
234 not been stopped. We need to make sure it's safe to destroy the
235 session as well (mainly by killing the session thread.)
236*/
237
238DWORD
240 DWORD_PTR private_handle)
241{
243 SessionInfo* session_info = (SessionInfo*) private_handle;
244 /* TODO: Maybe this is best off inside the playback thread? */
245
246 ASSERT(session_info);
247
248 result = CallSessionThread(session_info, WODM_CLOSE, 0);
249
250 if ( result == MMSYSERR_NOERROR )
251 {
252 /* TODO: Wait for it to be safe to terminate */
253
255
256 DestroySession(session_info);
257 }
258
259 return result;
260}
261
#define index(s, c)
Definition: various.h:29
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_BUSY
Definition: dderror.h:12
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
device_type
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define NULL
Definition: types.h:112
#define CloseHandle
Definition: compat.h:739
#define GENERIC_READ
Definition: compat.h:135
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
DWORD GetDeviceCapabilities(DeviceType device_type, UINT device_id, DWORD_PTR capabilities, DWORD capabilities_size)
Definition: common.c:84
MMRESULT ErrorToMmResult(UINT error_code)
Definition: common.c:22
DWORD CloseDevice(DWORD_PTR private_handle)
Definition: common.c:239
DWORD GetDeviceCount(DeviceType device_type)
Definition: common.c:58
DWORD OpenDevice(DeviceType device_type, UINT device_id, PVOID open_descriptor, DWORD flags, DWORD_PTR private_handle)
Definition: common.c:153
void CloseKernelDevice(HANDLE device_handle)
Definition: kernel.c:132
MMRESULT OpenKernelDevice(DeviceType device_type, UINT device_id, DWORD access, HANDLE *handle)
Definition: kernel.c:84
struct WAVEOPENDESC * LPWAVEOPENDESC
#define WODM_CLOSE
Definition: mmddk.h:111
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
#define IOCTL_WAVE_GET_CAPABILITIES
Definition: mmdef.h:52
#define IOCTL_MIDI_GET_CAPABILITIES
Definition: mmdef.h:69
MMRESULT CallSessionThread(SessionInfo *session_info, ThreadFunction function, PVOID thread_parameter)
Definition: session.c:219
MMRESULT CreateSession(DeviceType device_type, UINT device_id, SessionInfo **session_info)
Definition: session.c:63
DeviceType
Definition: mmdrv.h:42
@ MidiOutDevice
Definition: mmdrv.h:45
@ MidiInDevice
Definition: mmdrv.h:46
@ WaveInDevice
Definition: mmdrv.h:44
@ WaveOutDevice
Definition: mmdrv.h:43
#define IsMidiDevice(devicetype)
Definition: mmdrv.h:53
MMRESULT StartSessionThread(SessionInfo *session_info)
Definition: session.c:154
#define IsWaveDevice(devicetype)
Definition: mmdrv.h:50
BOOL NotifyClient(SessionInfo *session_info, DWORD message, DWORD_PTR parameter1, DWORD_PTR parameter2)
Definition: mme.c:25
#define IsAuxDevice(devicetype)
Definition: mmdrv.h:56
VOID DestroySession(SessionInfo *session)
Definition: session.c:113
#define MIM_OPEN
Definition: mmsystem.h:241
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
UINT MMRESULT
Definition: mmsystem.h:962
#define WOM_OPEN
Definition: mmsystem.h:181
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define MOM_OPEN
Definition: mmsystem.h:247
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MMSYSERR_ALLOCATED
Definition: mmsystem.h:100
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define WIM_OPEN
Definition: mmsystem.h:184
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
#define ASSERT(a)
Definition: mode.c:44
unsigned int UINT
Definition: ndis.h:50
#define DPRINT
Definition: sndvol32.h:71
HWAVE hWave
Definition: mmddk.h:398
DWORD dwInstance
Definition: mmddk.h:401
DWORD dwCallback
Definition: mmddk.h:400
DWORD flags
Definition: mmdrv.h:153
DWORD_PTR app_user_data
Definition: mmdrv.h:150
HWAVE mme_wave_handle
Definition: mmdrv.h:142
DWORD_PTR callback
Definition: mmdrv.h:151
HANDLE kernel_device_handle
Definition: mmdrv.h:136
Definition: tftpd.h:60
uint32_t DWORD_PTR
Definition: typedefs.h:65
static int error_code[8]
Definition: odbccp32.c:61
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ioctl
Definition: wintirpc.h:60