Release 970120
[wine] / multimedia / mmsystem.c
1 /*
2  * MMSYTEM functions
3  *
4  * Copyright 1993 Martin Ayotte
5  */
6 /* FIXME: I think there are some segmented vs. linear pointer weirdnesses 
7  *        and long term pointers to 16 bit space in here
8  */
9
10 #ifndef WINELIB
11
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <fcntl.h>
17 #include <sys/ioctl.h>
18 #include "windows.h"
19 #include "ldt.h"
20 #include "user.h"
21 #include "driver.h"
22 #include "file.h"
23 #include "mmsystem.h"
24 #include "stddebug.h"
25 #include "debug.h"
26 #include "xmalloc.h"
27
28 static int      InstalledCount;
29 static int      InstalledListLen;
30 static LPSTR    lpInstallNames = NULL;
31
32 MCI_OPEN_DRIVER_PARMS   mciDrv[MAXMCIDRIVERS];
33 /* struct below is to remember alias/devicenames for mcistring.c 
34  * FIXME: should use some internal struct ... 
35  */
36 MCI_OPEN_PARMS          mciOpenDrv[MAXMCIDRIVERS];
37
38 UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
39 UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
40 LONG DrvDefDriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
41                       DWORD dwParam1, DWORD dwParam2);
42
43 LONG WAVE_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
44                      DWORD dwParam1, DWORD dwParam2);
45 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
46                      DWORD dwParam1, DWORD dwParam2);
47 LONG CDAUDIO_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
48                         DWORD dwParam1, DWORD dwParam2);
49 LONG ANIM_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
50                      DWORD dwParam1, DWORD dwParam2);
51
52 /**************************************************************************
53 *                               MMSYSTEM_WEP            [MMSYSTEM.1]
54 */
55 int MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
56                  WORD cbHeapSize, LPSTR lpCmdLine)
57 {
58         /* isn't WEP the Windows Exit Procedure ? */
59         printf("MMSYSTEM DLL INIT ... hInst=%04X \n", hInstance);
60         return(TRUE);
61 }
62
63 /**************************************************************************
64 *                               sndPlaySound            [MMSYSTEM.2]
65 */
66 BOOL sndPlaySound(LPCSTR lpszSoundName, UINT uFlags)
67 {
68         HMMIO16                 hmmio;
69         MMCKINFO                mmckInfo;
70         MMCKINFO                ckMainRIFF;
71         HLOCAL16                hFormat;
72         PCMWAVEFORMAT   pcmWaveFormat;
73         int                             count;
74         int                             bufsize;
75         HLOCAL16                hDesc;
76         LPWAVEOPENDESC  lpWaveDesc;
77         HLOCAL16                hWaveHdr;
78         LPWAVEHDR               lpWaveHdr;
79         LPWAVEHDR               lp16WaveHdr;
80         HLOCAL16                hData;
81         DWORD                   dwRet;
82         char                    str[128];
83         LPSTR                   ptr;
84         dprintf_mmsys(stddeb, "sndPlaySound // SoundName='%s' uFlags=%04X !\n", 
85                                                                         lpszSoundName, uFlags);
86         if (lpszSoundName == NULL) {
87                 dprintf_mmsys(stddeb, "sndPlaySound // Stop !\n");
88                 return FALSE;
89                 }
90         hmmio = mmioOpen((LPSTR)lpszSoundName, NULL, 
91                 MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
92         if (hmmio == 0) {
93                 dprintf_mmsys(stddeb, "sndPlaySound // searching in SystemSound List !\n");
94                 GetProfileString32A("Sounds", (LPSTR)lpszSoundName, "", str, sizeof(str));
95                 if (strlen(str) == 0) return FALSE;
96                 if ( (ptr = (LPSTR)strchr(str, ',')) != NULL) *ptr = '\0';
97                 hmmio = mmioOpen(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
98                 if (hmmio == 0) {
99                         dprintf_mmsys(stddeb, "sndPlaySound // can't find SystemSound='%s' !\n", str);
100                         return FALSE;
101                         }
102                 }
103         if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0) != 0) {
104 ErrSND: if (hmmio != 0)   mmioClose(hmmio, 0);
105                 return FALSE;
106                 }
107         dprintf_mmsys(stddeb, "sndPlaySound // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
108                                 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
109                                 ckMainRIFF.cksize);
110         if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
111             (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) goto ErrSND;
112         mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
113         if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) goto ErrSND;
114         dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
115                         (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
116                         mmckInfo.cksize);
117         if (mmioRead(hmmio, (HPSTR) &pcmWaveFormat,
118                 (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) goto ErrSND;
119
120         dprintf_mmsys(stddeb, "sndPlaySound // wFormatTag=%04X !\n", pcmWaveFormat.wf.wFormatTag);
121         dprintf_mmsys(stddeb, "sndPlaySound // nChannels=%d \n", pcmWaveFormat.wf.nChannels);
122         dprintf_mmsys(stddeb, "sndPlaySound // nSamplesPerSec=%ld\n", pcmWaveFormat.wf.nSamplesPerSec);
123         dprintf_mmsys(stddeb, "sndPlaySound // nAvgBytesPerSec=%ld\n", pcmWaveFormat.wf.nAvgBytesPerSec);
124         dprintf_mmsys(stddeb, "sndPlaySound // nBlockAlign=%d \n", pcmWaveFormat.wf.nBlockAlign);
125         dprintf_mmsys(stddeb, "sndPlaySound // wBitsPerSample=%u !\n", pcmWaveFormat.wBitsPerSample);
126
127         mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
128         if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) goto ErrSND;
129         dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
130                         (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
131                         mmckInfo.cksize);
132         hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
133         lpWaveDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
134         lpWaveDesc->hWave = 0;
135         pcmWaveFormat.wf.nAvgBytesPerSec = 
136                 pcmWaveFormat.wf.nSamplesPerSec * pcmWaveFormat.wf.nBlockAlign;
137         hFormat = USER_HEAP_ALLOC(sizeof(PCMWAVEFORMAT));
138         lpWaveDesc->lpFormat = (LPWAVEFORMAT) USER_HEAP_LIN_ADDR(hFormat);
139         memcpy(lpWaveDesc->lpFormat, &pcmWaveFormat, sizeof(PCMWAVEFORMAT));
140         lpWaveDesc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hDesc);
141         dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)lpWaveDesc, CALLBACK_NULL);
142         if (dwRet != MMSYSERR_NOERROR) {
143                 dprintf_mmsys(stddeb, "sndPlaySound // can't open WaveOut device !\n");
144                 goto ErrSND;
145                 }
146         USER_HEAP_FREE(hFormat);
147         hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
148         lpWaveHdr = (LPWAVEHDR) USER_HEAP_LIN_ADDR(hWaveHdr);
149         lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
150         bufsize = 64000;
151         hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
152         lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock16(hData);
153         lpWaveHdr->dwBufferLength = bufsize;
154         lpWaveHdr->dwUser = 0L;
155         lpWaveHdr->dwFlags = 0L;
156         lpWaveHdr->dwLoops = 0L;
157         dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
158         if (dwRet != MMSYSERR_NOERROR) {
159                 dprintf_mmsys(stddeb, "sndPlaySound // can't prepare WaveOut device !\n");
160                 GlobalUnlock16(hData);
161                 GlobalFree16(hData);
162                 USER_HEAP_FREE(hDesc);
163                 USER_HEAP_FREE(hWaveHdr);
164                 goto ErrSND;
165                 }
166         while(TRUE) {
167                 count = mmioRead(hmmio, PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
168                 if (count < 1) break;
169                 lpWaveHdr->dwBufferLength = count;
170 /*              lpWaveHdr->dwBytesRecorded = count; */
171                 wodMessage(0, WODM_WRITE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
172                 }
173         wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
174         wodMessage(0, WODM_CLOSE, 0, 0L, 0L);
175         GlobalUnlock16(hData);
176         GlobalFree16(hData);
177         USER_HEAP_FREE(hDesc);
178         USER_HEAP_FREE(hWaveHdr);
179         if (hmmio != 0)   mmioClose(hmmio, 0);
180         return TRUE;
181 }
182
183 /**************************************************************************
184 *                               mmsystemGetVersion      [MMSYSTEM.5]
185 */
186 WORD mmsystemGetVersion()
187 {
188         dprintf_mmsys(stddeb, "mmsystemGetVersion // 0.4.0 ...?... :-) !\n");
189         return 0x0040;
190 }
191
192 /**************************************************************************
193 *                               DriverProc      [MMSYSTEM.6]
194 */
195 LRESULT DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
196                                                 DWORD dwParam1, DWORD dwParam2)
197 {
198         return DrvDefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
199 }
200
201 /**************************************************************************
202 *                               DriverCallback  [MMSYSTEM.31]
203 */
204 BOOL DriverCallback(DWORD dwCallBack, UINT uFlags, HANDLE16 hDev, 
205                 WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
206 {
207         dprintf_mmsys(stddeb, "DriverCallback(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
208                 dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
209         switch(uFlags & DCB_TYPEMASK) {
210                 case DCB_NULL:
211                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_NULL !\n");
212                         break;
213                 case DCB_WINDOW:
214                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_WINDOW !\n");
215                         break;
216                 case DCB_TASK:
217                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_TASK !\n");
218                         break;
219                 case DCB_FUNCTION:
220                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_FUNCTION !\n");
221                         break;
222                 }
223         return TRUE;
224 }
225
226 /**************************************************************************
227 *                               auxGetNumDevs           [MMSYSTEM.350]
228 */
229 UINT auxGetNumDevs()
230 {
231         UINT    count = 0;
232         dprintf_mmsys(stddeb, "auxGetNumDevs !\n");
233         count += auxMessage(0, AUXDM_GETNUMDEVS, 0L, 0L, 0L);
234         dprintf_mmsys(stddeb, "auxGetNumDevs return %u \n", count);
235         return count;
236 }
237
238 /**************************************************************************
239 *                               auxGetDevCaps           [MMSYSTEM.351]
240 */
241 UINT auxGetDevCaps(UINT uDeviceID, AUXCAPS * lpCaps, UINT uSize)
242 {
243         dprintf_mmsys(stddeb, "auxGetDevCaps(%04X, %p, %d) !\n", 
244                                         uDeviceID, lpCaps, uSize);
245         return auxMessage(uDeviceID, AUXDM_GETDEVCAPS, 
246                                 0L, (DWORD)lpCaps, (DWORD)uSize);
247 }
248
249 /**************************************************************************
250 *                               auxGetVolume            [MMSYSTEM.352]
251 */
252 UINT auxGetVolume(UINT uDeviceID, DWORD * lpdwVolume)
253 {
254         dprintf_mmsys(stddeb, "auxGetVolume(%04X, %p) !\n", uDeviceID, lpdwVolume);
255         return auxMessage(uDeviceID, AUXDM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
256 }
257
258 /**************************************************************************
259 *                               auxSetVolume            [MMSYSTEM.353]
260 */
261 UINT auxSetVolume(UINT uDeviceID, DWORD dwVolume)
262 {
263         dprintf_mmsys(stddeb, "auxSetVolume(%04X, %08lX) !\n", uDeviceID, dwVolume);
264         return auxMessage(uDeviceID, AUXDM_SETVOLUME, 0L, dwVolume, 0L);
265 }
266
267 /**************************************************************************
268 *                               auxOutMessage           [MMSYSTEM.354]
269 */
270 DWORD auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2)
271 {
272         dprintf_mmsys(stddeb, "auxOutMessage(%04X, %04X, %08lX, %08lX)\n", 
273                                 uDeviceID, uMessage, dw1, dw2);
274         return auxMessage(uDeviceID, uMessage, 0L, dw1, dw2);
275 }
276
277 /**************************************************************************
278 *                               mciGetErrorString               [MMSYSTEM.706]
279 */
280 BOOL mciGetErrorString (DWORD wError, LPSTR lpstrBuffer, UINT uLength)
281 {
282         LPSTR   msgptr;
283         dprintf_mmsys(stddeb, "mciGetErrorString(%08lX, %p, %d);\n", wError, lpstrBuffer, uLength);
284         if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE);
285         lpstrBuffer[0] = '\0';
286         switch(wError) {
287                 case MCIERR_INVALID_DEVICE_ID:
288                         msgptr = "Invalid MCI device ID. Use the ID returned when opening the MCI device.";
289                         break;
290                 case MCIERR_UNRECOGNIZED_KEYWORD:
291                         msgptr = "The driver cannot recognize the specified command parameter.";
292                         break;
293                 case MCIERR_UNRECOGNIZED_COMMAND:
294                         msgptr = "The driver cannot recognize the specified command.";
295                         break;
296                 case MCIERR_HARDWARE:
297                         msgptr = "There is a problem with your media device. Make sure it is working correctly or contact the device manufacturer.";
298                         break;
299                 case MCIERR_INVALID_DEVICE_NAME:
300                         msgptr = "The specified device is not open or is not recognized by MCI.";
301                         break;
302                 case MCIERR_OUT_OF_MEMORY:
303                         msgptr = "Not enough memory available for this task. \nQuit one or more applications to increase available memory, and then try again.";
304                         break;
305                 case MCIERR_DEVICE_OPEN:
306                         msgptr = "The device name is already being used as an alias by this application. Use a unique alias.";
307                         break;
308                 case MCIERR_CANNOT_LOAD_DRIVER:
309                         msgptr = "There is an undetectable problem in loading the specified device driver.";
310                         break;
311                 case MCIERR_MISSING_COMMAND_STRING:
312                         msgptr = "No command was specified.";
313                         break;
314                 case MCIERR_PARAM_OVERFLOW:
315                         msgptr = "The output string was to large to fit in the return buffer. Increase the size of the buffer.";
316                         break;
317                 case MCIERR_MISSING_STRING_ARGUMENT:
318                         msgptr = "The specified command requires a character-string parameter. Please provide one.";
319                         break;
320                 case MCIERR_BAD_INTEGER:
321                         msgptr = "The specified integer is invalid for this command.";
322                         break;
323                 case MCIERR_PARSER_INTERNAL:
324                         msgptr = "The device driver returned an invalid return type. Check with the device manufacturer about obtaining a new driver.";
325                         break;
326                 case MCIERR_DRIVER_INTERNAL:
327                         msgptr = "There is a problem with the device driver. Check with the device manufacturer about obtaining a new driver.";
328                         break;
329                 case MCIERR_MISSING_PARAMETER:
330                         msgptr = "The specified command requires a parameter. Please supply one.";
331                         break;
332                 case MCIERR_UNSUPPORTED_FUNCTION:
333                         msgptr = "The MCI device you are using does not support the specified command.";
334                         break;
335                 case MCIERR_FILE_NOT_FOUND:
336                         msgptr = "Cannot find the specified file. Make sure the path and filename are correct.";
337                         break;
338                 case MCIERR_DEVICE_NOT_READY:
339                         msgptr = "The device driver is not ready.";
340                         break;
341                 case MCIERR_INTERNAL:
342                         msgptr = "A problem occurred in initializing MCI. Try restarting Windows.";
343                         break;
344                 case MCIERR_DRIVER:
345                         msgptr = "There is a problem with the device driver. The driver has closed. Cannot access error.";
346                         break;
347                 case MCIERR_CANNOT_USE_ALL:
348                         msgptr = "Cannot use 'all' as the device name with the specified command.";
349                         break;
350                 case MCIERR_MULTIPLE:
351                         msgptr = "Errors occurred in more than one device. Specify each command and device separately to determine which devices caused the error";
352                         break;
353                 case MCIERR_EXTENSION_NOT_FOUND:
354                         msgptr = "Cannot determine the device type from the given filename extension.";
355                         break;
356                 case MCIERR_OUTOFRANGE:
357                         msgptr = "The specified parameter is out of range for the specified command.";
358                         break;
359                 case MCIERR_FLAGS_NOT_COMPATIBLE:
360                         msgptr = "The specified parameters cannot be used together.";
361                         break;
362                 case MCIERR_FILE_NOT_SAVED:
363                         msgptr = "Cannot save the specified file. Make sure you have enough disk space or are still connected to the network.";
364                         break;
365                 case MCIERR_DEVICE_TYPE_REQUIRED:
366                         msgptr = "Cannot find the specified device. Make sure it is installed or that the device name is spelled correctly.";
367                         break;
368                 case MCIERR_DEVICE_LOCKED:
369                         msgptr = "The specified device is now being closed. Wait a few seconds, and then try again.";
370                         break;
371                 case MCIERR_DUPLICATE_ALIAS:
372                         msgptr = "The specified alias is already being used in this application. Use a unique alias.";
373                         break;
374                 case MCIERR_BAD_CONSTANT:
375                         msgptr = "The specified parameter is invalid for this command.";
376                         break;
377                 case MCIERR_MUST_USE_SHAREABLE:
378                         msgptr = "The device driver is already in use. To share it, use the 'shareable' parameter with each 'open' command.";
379                         break;
380                 case MCIERR_MISSING_DEVICE_NAME:
381                         msgptr = "The specified command requires an alias, file, driver, or device name. Please supply one.";
382                         break;
383                 case MCIERR_BAD_TIME_FORMAT:
384                         msgptr = "The specified value for the time format is invalid. Refer to the MCI documentation for valid formats.";
385                         break;
386                 case MCIERR_NO_CLOSING_QUOTE:
387                         msgptr = "A closing double-quotation mark is missing from the parameter value. Please supply one.";
388                         break;
389                 case MCIERR_DUPLICATE_FLAGS:
390                         msgptr = "A parameter or value was specified twice. Only specify it once.";
391                         break;
392                 case MCIERR_INVALID_FILE:
393                         msgptr = "The specified file cannot be played on the specified MCI device. The file may be corrupt, or not in the correct format.";
394                         break;
395                 case MCIERR_NULL_PARAMETER_BLOCK:
396                         msgptr = "A null parameter block was passed to MCI.";
397                         break;
398                 case MCIERR_UNNAMED_RESOURCE:
399                         msgptr = "Cannot save an unnamed file. Supply a filename.";
400                         break;
401                 case MCIERR_NEW_REQUIRES_ALIAS:
402                         msgptr = "You must specify an alias when using the 'new' parameter.";
403                         break;
404                 case MCIERR_NOTIFY_ON_AUTO_OPEN:
405                         msgptr = "Cannot use the 'notify' flag with auto-opened devices.";
406                         break;
407                 case MCIERR_NO_ELEMENT_ALLOWED:
408                         msgptr = "Cannot use a filename with the specified device.";
409                         break;
410                 case MCIERR_NONAPPLICABLE_FUNCTION:
411                         msgptr = "Cannot carry out the commands in the order specified. Correct the command sequence, and then try again.";
412                         break;
413                 case MCIERR_ILLEGAL_FOR_AUTO_OPEN:
414                         msgptr = "Cannot carry out the specified command on an auto-opened device. Wait until the device is closed, and then try again.";
415                         break;
416                 case MCIERR_FILENAME_REQUIRED:
417                         msgptr = "The filename is invalid. Make sure the filename is not longer than 8 characters, followed by a period and an extension.";
418                         break;
419                 case MCIERR_EXTRA_CHARACTERS:
420                         msgptr = "Cannot specify extra characters after a string enclosed in quotation marks.";
421                         break;
422                 case MCIERR_DEVICE_NOT_INSTALLED:
423                         msgptr = "The specified device is not installed on the system. Use the Drivers option in Control Panel to install the device.";
424                         break;
425                 case MCIERR_GET_CD:
426                         msgptr = "Cannot access the specified file or MCI device. Try changing directories or restarting your computer.";
427                         break;
428                 case MCIERR_SET_CD:
429                         msgptr = "Cannot access the specified file or MCI device because the application cannot change directories.";
430                         break;
431                 case MCIERR_SET_DRIVE:
432                         msgptr = "Cannot access specified file or MCI device because the application cannot change drives.";
433                         break;
434                 case MCIERR_DEVICE_LENGTH:
435                         msgptr = "Specify a device or driver name that is less than 79 characters.";
436                         break;
437                 case MCIERR_DEVICE_ORD_LENGTH:
438                         msgptr = "Specify a device or driver name that is less than 69 characters.";
439                         break;
440                 case MCIERR_NO_INTEGER:
441                         msgptr = "The specified command requires an integer parameter. Please provide one.";
442                         break;
443                 case MCIERR_WAVE_OUTPUTSINUSE:
444                         msgptr = "All wave devices that can play files in the current format are in use. Wait until a wave device is free, and then try again.";
445                         break;
446                 case MCIERR_WAVE_SETOUTPUTINUSE:
447                         msgptr = "Cannot set the current wave device for play back because it is in use. Wait until the device is free, and then try again.";
448                         break;
449                 case MCIERR_WAVE_INPUTSINUSE:
450                         msgptr = "All wave devices that can record files in the current format are in use. Wait until a wave device is free, and then try again.";
451                         break;
452                 case MCIERR_WAVE_SETINPUTINUSE:
453                         msgptr = "Cannot set the current wave device for recording because it is in use. Wait until the device is free, and then try again.";
454                         break;
455                 case MCIERR_WAVE_OUTPUTUNSPECIFIED:
456                         msgptr = "Any compatible waveform playback device may be used.";
457                         break;
458                 case MCIERR_WAVE_INPUTUNSPECIFIED:
459                         msgptr = "Any compatible waveform recording device may be used.";
460                         break;
461                 case MCIERR_WAVE_OUTPUTSUNSUITABLE:
462                         msgptr = "No wave device that can play files in the current format is installed. Use the Drivers option to install the wave device.";
463                         break;
464                 case MCIERR_WAVE_SETOUTPUTUNSUITABLE:
465                         msgptr = "The device you are trying to play to cannot recognize the current file format.";
466                         break;
467                 case MCIERR_WAVE_INPUTSUNSUITABLE:
468                         msgptr = "No wave device that can record files in the current format is installed. Use the Drivers option to install the wave device.";
469                         break;
470                 case MCIERR_WAVE_SETINPUTUNSUITABLE:
471                         msgptr = "The device you are trying to record from cannot recognize the current file format.";
472                         break;
473                 case MCIERR_NO_WINDOW:
474                         msgptr = "There is no display window.";
475                         break;
476                 case MCIERR_CREATEWINDOW:
477                         msgptr = "Could not create or use window.";
478                         break;
479                 case MCIERR_FILE_READ:
480                         msgptr = "Cannot read the specified file. Make sure the file is still present, or check your disk or network connection.";
481                         break;
482                 case MCIERR_FILE_WRITE:
483                         msgptr = "Cannot write to the specified file. Make sure you have enough disk space or are still connected to the network.";
484                         break;
485
486 /* 
487 #define MCIERR_SEQ_DIV_INCOMPATIBLE     (MCIERR_BASE + 80)
488 #define MCIERR_SEQ_PORT_INUSE           (MCIERR_BASE + 81)
489 #define MCIERR_SEQ_PORT_NONEXISTENT     (MCIERR_BASE + 82)
490 #define MCIERR_SEQ_PORT_MAPNODEVICE     (MCIERR_BASE + 83)
491 #define MCIERR_SEQ_PORT_MISCERROR       (MCIERR_BASE + 84)
492 #define MCIERR_SEQ_TIMER                (MCIERR_BASE + 85)
493 #define MCIERR_SEQ_PORTUNSPECIFIED      (MCIERR_BASE + 86)
494 #define MCIERR_SEQ_NOMIDIPRESENT        (MCIERR_BASE + 87)
495
496 msg# 513 : vcr
497 msg# 514 : videodisc
498 msg# 515 : overlay
499 msg# 516 : cdaudio
500 msg# 517 : dat
501 msg# 518 : scanner
502 msg# 519 : animation
503 msg# 520 : digitalvideo
504 msg# 521 : other
505 msg# 522 : waveaudio
506 msg# 523 : sequencer
507 msg# 524 : not ready
508 msg# 525 : stopped
509 msg# 526 : playing
510 msg# 527 : recording
511 msg# 528 : seeking
512 msg# 529 : paused
513 msg# 530 : open
514 msg# 531 : false
515 msg# 532 : true
516 msg# 533 : milliseconds
517 msg# 534 : hms
518 msg# 535 : msf
519 msg# 536 : frames
520 msg# 537 : smpte 24
521 msg# 538 : smpte 25
522 msg# 539 : smpte 30
523 msg# 540 : smpte 30 drop
524 msg# 541 : bytes
525 msg# 542 : samples
526 msg# 543 : tmsf
527 */
528                 default:
529                         msgptr = "Unknown MCI Error !\n";
530                         break;
531                 }
532         lstrcpyn32A(lpstrBuffer, msgptr, uLength);
533         return TRUE;
534 }
535
536
537 /**************************************************************************
538 *                               mciDriverNotify                 [MMSYSTEM.711]
539 */
540 BOOL mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus)
541 {
542         dprintf_mmsys(stddeb, "mciDriverNotify(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
543         if (!IsWindow(hWndCallBack)) return FALSE;
544         dprintf_mmsys(stddeb, "mciDriverNotify // before PostMessage\n");
545         PostMessage(hWndCallBack, MM_MCINOTIFY, wStatus, 
546                         MAKELONG(mciDrv[wDevID].wDeviceID, 0));
547         return TRUE;
548 }
549
550 /**************************************************************************
551 *                               mciOpen                                 [internal]
552 */
553
554 #define _MCI_STRDUP_TO_SEG(dest,source) {\
555         HLOCAL16 x;\
556         x=USER_HEAP_ALLOC(strlen(source)+1);\
557         dest=(LPSTR)MAKELONG(x,USER_HeapSel);\
558         strcpy(PTR_SEG_TO_LIN(dest),source);\
559 }
560
561 DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS lp16Parms)
562 {
563         char    str[128];
564         LPMCI_OPEN_PARMS lpParms;
565         UINT    uDevTyp = 0;
566         UINT    wDevID = 0;
567
568         lpParms = PTR_SEG_TO_LIN(lp16Parms);
569         dprintf_mmsys(stddeb, "mciOpen(%08lX, %p (%p))\n", dwParam, lp16Parms, lpParms);
570         if (lp16Parms == NULL) return MCIERR_INTERNAL;
571         while(mciDrv[wDevID].wType != 0) {
572                 if (++wDevID >= MAXMCIDRIVERS) {
573                         dprintf_mmsys(stddeb, "MCI_OPEN // MAXMCIDRIVERS reached !\n");
574                         return MCIERR_INTERNAL;
575                 }
576         }
577         dprintf_mmsys(stddeb, "mciOpen // wDevID=%d \n", wDevID);
578         memcpy(&mciOpenDrv[wDevID],lpParms,sizeof(*lpParms));
579
580         if (dwParam & MCI_OPEN_ELEMENT) {
581                 char    *s,*t;
582
583                 dprintf_mmsys(stddeb,"mciOpen // lpstrElementName='%s'\n",
584                         (char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName)
585                 );
586                 s=(char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
587                 t=strrchr(s,'.');
588                 if (t) {
589                         GetProfileString32A("mci extensions",t+1,"*",str,sizeof(str));
590                         CharUpper32A(str);
591                         if (strcmp(str, "CDAUDIO") == 0) {
592                                 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
593                         } else
594                         if (strcmp(str, "WAVEAUDIO") == 0) {
595                                 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
596                         } else
597                         if (strcmp(str, "SEQUENCER") == 0)      {
598                                 uDevTyp = MCI_DEVTYPE_SEQUENCER;
599                         } else
600                         if (strcmp(str, "ANIMATION1") == 0) {
601                                 uDevTyp = MCI_DEVTYPE_ANIMATION;
602                         } else
603                         if (strcmp(str, "AVIVIDEO") == 0) {
604                                 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
605                         } else 
606                         if (strcmp(str,"*") == 0) {
607                                 dprintf_mmsys(stddeb,"No [mci extensions] entry for %s found.\n",t);
608                                 return MCIERR_EXTENSION_NOT_FOUND;
609                         } else  {
610                                 dprintf_mmsys(stddeb,"[mci extensions] entry %s for %s not supported.\n",str,t);
611                         }
612                 } else
613                         return MCIERR_EXTENSION_NOT_FOUND;
614         }
615
616         if (dwParam & MCI_OPEN_ALIAS) {
617                 dprintf_mmsys(stddeb, "MCI_OPEN // Alias='%s' !\n",
618                         (char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
619                 _MCI_STRDUP_TO_SEG(
620                         mciOpenDrv[wDevID].lpstrAlias,
621                         (char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias)
622                 );
623                 /* mplayer does allocate alias to CDAUDIO */
624         }
625         if (dwParam & MCI_OPEN_TYPE) {
626                 if (dwParam & MCI_OPEN_TYPE_ID) {
627                         dprintf_mmsys(stddeb, "MCI_OPEN // Dev=%p !\n", lpParms->lpstrDeviceType);
628                         uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
629                         mciOpenDrv[wDevID].lpstrDeviceType=lpParms->lpstrDeviceType;
630                 } else {
631                         if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
632                         dprintf_mmsys(stddeb, "MCI_OPEN // Dev='%s' !\n",
633                               (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
634                         _MCI_STRDUP_TO_SEG(
635                                 mciOpenDrv[wDevID].lpstrDeviceType,
636                                 (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType)
637                         );
638                         strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
639                         CharUpper32A(str);
640                         if (strcmp(str, "CDAUDIO") == 0) {
641                                 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
642                         } else
643                         if (strcmp(str, "WAVEAUDIO") == 0) {
644                                 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
645                         } else
646                         if (strcmp(str, "SEQUENCER") == 0)      {
647                                 uDevTyp = MCI_DEVTYPE_SEQUENCER;
648                         } else
649                         if (strcmp(str, "ANIMATION1") == 0) {
650                                 uDevTyp = MCI_DEVTYPE_ANIMATION;
651                         } else
652                         if (strcmp(str, "AVIVIDEO") == 0) {
653                                 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
654                         }
655                 }
656         }
657         mciDrv[wDevID].wType = uDevTyp;
658         mciDrv[wDevID].wDeviceID = wDevID;
659         lpParms->wDeviceID = wDevID;
660         dprintf_mmsys(stddeb, "MCI_OPEN // mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n", 
661                                 wDevID, uDevTyp, lpParms->wDeviceID);
662         switch(uDevTyp) {
663                 case MCI_DEVTYPE_CD_AUDIO:
664 #ifdef WINELIB
665                         WINELIB_UNIMP ("CDAUDIO_DriverProc");
666 #else
667                         return CDAUDIO_DriverProc(0, 0, MCI_OPEN_DRIVER,
668                                                         dwParam, (DWORD)lp16Parms);
669 #endif
670                 case MCI_DEVTYPE_WAVEFORM_AUDIO:
671                         return WAVE_DriverProc(0, 0, MCI_OPEN_DRIVER, 
672                                                                 dwParam, (DWORD)lp16Parms);
673                 case MCI_DEVTYPE_SEQUENCER:
674                         return MIDI_DriverProc(0, 0, MCI_OPEN_DRIVER, 
675                                                                 dwParam, (DWORD)lp16Parms);
676                 case MCI_DEVTYPE_ANIMATION:
677                         return ANIM_DriverProc(0, 0, MCI_OPEN_DRIVER, 
678                                                                 dwParam, (DWORD)lp16Parms);
679                 case MCI_DEVTYPE_DIGITAL_VIDEO:
680                         dprintf_mmsys(stddeb, "MCI_OPEN // No DIGITAL_VIDEO yet !\n");
681                         return MCIERR_DEVICE_NOT_INSTALLED;
682                 default:
683                         dprintf_mmsys(stddeb, "MCI_OPEN // Invalid Device Name '%p' !\n", lpParms->lpstrDeviceType);
684                         return MCIERR_INVALID_DEVICE_NAME;
685                 }
686         return MCIERR_INTERNAL;
687 }
688
689
690 /**************************************************************************
691 *                               mciClose                                [internal]
692 */
693 DWORD mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
694 {
695         DWORD   dwRet = MCIERR_INTERNAL;
696         dprintf_mmsys(stddeb, "mciClose(%u, %08lX, %p)\n", wDevID, dwParam, lpParms);
697         switch(mciDrv[wDevID].wType) {
698                 case MCI_DEVTYPE_CD_AUDIO:
699 #ifndef WINELIB
700                         dwRet = CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
701                                                 MCI_CLOSE, dwParam, (DWORD)lpParms);
702 #endif
703                         break;
704                 case MCI_DEVTYPE_WAVEFORM_AUDIO:
705                         dwRet = WAVE_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
706                                                 MCI_CLOSE, dwParam, (DWORD)lpParms);
707                         break;
708                 case MCI_DEVTYPE_SEQUENCER:
709                         dwRet = MIDI_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
710                                                 MCI_CLOSE, dwParam, (DWORD)lpParms);
711                         break;
712                 case MCI_DEVTYPE_ANIMATION:
713                         dwRet = ANIM_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
714                                                 MCI_CLOSE, dwParam, (DWORD)lpParms);
715                         break;
716                 default:
717                         dprintf_mmsys(stddeb, "mciClose() // unknown device type=%04X !\n", mciDrv[wDevID].wType);
718                 }
719         mciDrv[wDevID].wType = 0;
720         return dwRet;
721 }
722
723
724 /**************************************************************************
725 *                               mciSound                                [internal]
726 */
727 DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS lpParms)
728 {
729         int     len;
730         LPSTR   ptr;
731         LPSTR   lpstrReturn;
732         DWORD   *lpdwRet;
733         LPSTR   SysFile = "SYSTEM.INI";
734         dprintf_mci(stddeb, "mciSysInfo(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
735         lpstrReturn = PTR_SEG_TO_LIN(lpParms->lpstrReturn);
736         switch(dwFlags) {
737                 case MCI_SYSINFO_QUANTITY:
738                         dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_QUANTITY \n");
739                         lpdwRet = (DWORD *)lpstrReturn;
740                         *(lpdwRet) = InstalledCount;            
741                         return 0;
742                 case MCI_SYSINFO_INSTALLNAME:
743                         dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_INSTALLNAME \n");
744                         if (lpInstallNames == NULL) {
745                                 InstalledCount = 0;
746                                 InstalledListLen = 0;
747                                 ptr = lpInstallNames = xmalloc(2048);
748                                 GetPrivateProfileString32A("mci", NULL, "", lpInstallNames, 2000, SysFile);
749                                 while(strlen(ptr) > 0) {
750                                         dprintf_mci(stddeb, "---> '%s' \n", ptr);
751                                         len = strlen(ptr) + 1;
752                                         ptr += len;
753                                         InstalledListLen += len;
754                                         InstalledCount++;
755                                 }
756                         }
757                         if (lpParms->dwRetSize < InstalledListLen)
758                                 lstrcpyn32A(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 1);
759                         else
760                                 strcpy(lpstrReturn, lpInstallNames);
761                         return 0;
762                 case MCI_SYSINFO_NAME:
763                         dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_NAME \n");
764                         return 0;
765                 case MCI_SYSINFO_OPEN:
766                         dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_OPEN \n");
767                         return 0;
768                 }
769         return MMSYSERR_INVALPARAM;
770 }
771
772 /**************************************************************************
773 *                               mciSound                                [internal]
774 */
775 DWORD mciSound(UINT wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
776 {
777         if (lpParms == NULL) return MCIERR_INTERNAL;
778         if (dwParam & MCI_SOUND_NAME)
779                 dprintf_mci(stddeb, "MCI_SOUND // file='%s' !\n", lpParms->lpstrSoundName);
780         return MCIERR_INVALID_DEVICE_ID;
781 }
782
783
784
785 /**************************************************************************
786 *                               mciSendCommand                  [MMSYSTEM.701]
787 */
788 DWORD mciSendCommand(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
789 {
790         HDRVR16 hDrv = 0;
791         dprintf_mci(stddeb, "mciSendCommand(%04X, %04X, %08lX, %08lX)\n", 
792                                         wDevID, wMsg, dwParam1, dwParam2);
793         switch(wMsg) {
794                 case MCI_OPEN:
795                         return mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
796                 case MCI_CLOSE:
797                         return mciClose(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
798                 case MCI_SYSINFO:
799                         return mciSysInfo(dwParam1, (LPMCI_SYSINFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
800                 default:
801                         switch(mciDrv[wDevID].wType) {
802                                 case MCI_DEVTYPE_CD_AUDIO:
803 #ifndef WINELIB
804                                         return CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
805                                                                                         wMsg, dwParam1, dwParam2);
806 #endif
807                                         
808                                 case MCI_DEVTYPE_WAVEFORM_AUDIO:
809                                         return WAVE_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
810                                                                                         wMsg, dwParam1, dwParam2);
811                                 case MCI_DEVTYPE_SEQUENCER:
812                                         return MIDI_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
813                                                                                         wMsg, dwParam1, dwParam2);
814                                 case MCI_DEVTYPE_ANIMATION:
815                                         return ANIM_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
816                                                                                         wMsg, dwParam1, dwParam2);
817                                 default:
818                                         dprintf_mci(stddeb, "mciSendCommand() // unknown device type=%04X !\n", 
819                                                                                         mciDrv[wDevID].wType);
820                                 }
821                 }
822         return MMSYSERR_INVALPARAM;
823 }
824
825 /**************************************************************************
826 *                               mciGetDeviceID          [MMSYSTEM.703]
827 */
828 UINT mciGetDeviceID (LPCSTR lpstrName)
829 {
830     dprintf_mci(stddeb, "mciGetDeviceID(%s)\n", lpstrName);
831     if (lpstrName && !lstrcmpi32A(lpstrName, "ALL"))
832         return MCI_ALL_DEVICE_ID;
833     return 0;
834 }
835
836 /**************************************************************************
837 *                               mciSetYieldProc         [MMSYSTEM.714]
838 */
839 BOOL mciSetYieldProc (UINT uDeviceID, 
840                 YIELDPROC fpYieldProc, DWORD dwYieldData)
841 {
842     return FALSE;
843 }
844
845 /**************************************************************************
846 *                               mciGetDeviceIDFromElementID     [MMSYSTEM.715]
847 */
848 UINT mciGetDeviceIDFromElementID(DWORD dwElementID, LPCSTR lpstrType)
849 {
850     return 0;
851 }
852
853 /**************************************************************************
854 *                               mciGetYieldProc         [MMSYSTEM.716]
855 */
856 YIELDPROC mciGetYieldProc(UINT uDeviceID, DWORD * lpdwYieldData)
857 {
858     return NULL;
859 }
860
861 /**************************************************************************
862 *                               mciGetCreatorTask       [MMSYSTEM.717]
863 */
864 HTASK16 mciGetCreatorTask(UINT uDeviceID)
865 {
866     return 0;
867 }
868
869 /**************************************************************************
870 *                               midiOutGetNumDevs       [MMSYSTEM.201]
871 */
872 UINT midiOutGetNumDevs(void)
873 {
874         UINT    count = 0;
875         dprintf_mmsys(stddeb, "midiOutGetNumDevs\n");
876         count += modMessage(0, MODM_GETNUMDEVS, 0L, 0L, 0L);
877         dprintf_mmsys(stddeb, "midiOutGetNumDevs return %u \n", count);
878         return count;
879 }
880
881 /**************************************************************************
882 *                               midiOutGetDevCaps       [MMSYSTEM.202]
883 */
884 UINT midiOutGetDevCaps(UINT uDeviceID, MIDIOUTCAPS * lpCaps, UINT uSize)
885 {
886         dprintf_mmsys(stddeb, "midiOutGetDevCaps\n");
887         return 0;
888 }
889
890 /**************************************************************************
891 *                               midiOutGetErrorText     [MMSYSTEM.203]
892 */
893 UINT midiOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
894 {
895         dprintf_mmsys(stddeb, "midiOutGetErrorText\n");
896         return midiGetErrorText(uError, lpText, uSize);
897 }
898
899
900 /**************************************************************************
901 *                               midiGetErrorText        [internal]
902 */
903 UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
904 {
905         LPSTR   msgptr;
906         if ((lpText == NULL) || (uSize < 1)) return(FALSE);
907         lpText[0] = '\0';
908         switch(uError) {
909                 case MIDIERR_UNPREPARED:
910                         msgptr = "The MIDI header was not prepared. Use the Prepare function to prepare the header, and then try again.";
911                         break;
912                 case MIDIERR_STILLPLAYING:
913                         msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
914                         break;
915                 case MIDIERR_NOMAP:
916                         msgptr = "A MIDI map was not found. There may be a problem with the driver, or the MIDIMAP.CFG file may be corrupt or missing.";
917                         break;
918                 case MIDIERR_NOTREADY:
919                         msgptr = "The port is transmitting data to the device. Wait until the data has been transmitted, and then try again.";
920                         break;
921                 case MIDIERR_NODEVICE:
922                         msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.";
923                         break;
924                 case MIDIERR_INVALIDSETUP:
925                         msgptr = "The current MIDI setup is damaged. Copy the original MIDIMAP.CFG file to the Windows SYSTEM directory, and then try again.";
926                         break;
927 /*
928 msg# 336 : Cannot use the song-pointer time format and the SMPTE time-format together.
929 msg# 337 : The specified MIDI device is already in use. Wait until it is free, and then try again.
930 msg# 338 : The specified MIDI device is not installed on the system. Use the Drivers option in Control Panel to install the driver.
931 msg# 339 : The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.
932 msg# 340 : An error occurred using the specified port.
933 msg# 341 : All multimedia timers are being used by other applications. Quit one of these applications, and then try again.
934 msg# 342 : There is no current MIDI port.
935 msg# 343 : There are no MIDI devices installed on the system. Use the Drivers option in Control Panel to install the driver.
936 */
937                 default:
938                         msgptr = "Unknown MIDI Error !\n";
939                         break;
940                 }
941         lstrcpyn32A(lpText, msgptr, uSize);
942         return TRUE;
943 }
944
945 /**************************************************************************
946 *                               midiOutOpen             [MMSYSTEM.204]
947 */
948 UINT midiOutOpen(HMIDIOUT16 * lphMidiOut, UINT uDeviceID,
949                  DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
950 {
951         HMIDI16 hMidiOut;
952         LPMIDIOPENDESC  lpDesc;
953         LPMIDIOPENDESC  lp16Desc;
954         DWORD   dwRet = 0;
955         BOOL    bMapperFlg = FALSE;
956         if (lphMidiOut != NULL) *lphMidiOut = 0;
957         dprintf_mmsys(stddeb, "midiOutOpen(%p, %d, %08lX, %08lX, %08lX);\n", 
958                 lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
959         if (uDeviceID == (UINT)MIDI_MAPPER) {
960                 dprintf_mmsys(stddeb, "midiOutOpen      // MIDI_MAPPER mode requested !\n");
961                 bMapperFlg = TRUE;
962                 uDeviceID = 0;
963         }
964         hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
965         if (lphMidiOut != NULL) *lphMidiOut = hMidiOut;
966         lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiOut);
967         lpDesc = (LPMIDIOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
968         if (lpDesc == NULL) return MMSYSERR_NOMEM;
969         lpDesc->hMidi = hMidiOut;
970         lpDesc->dwCallback = dwCallback;
971         lpDesc->dwInstance = dwInstance;
972         while(uDeviceID < MAXMIDIDRIVERS) {
973                 dwRet = modMessage(uDeviceID, MODM_OPEN, 
974                         lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
975                 if (dwRet == MMSYSERR_NOERROR) break;
976                 if (!bMapperFlg) break;
977                 uDeviceID++;
978                 dprintf_mmsys(stddeb, "midiOutOpen      // MIDI_MAPPER mode ! try next driver...\n");
979                 }
980         return dwRet;
981 }
982
983 /**************************************************************************
984 *                               midiOutClose            [MMSYSTEM.205]
985 */
986 UINT midiOutClose(HMIDIOUT16 hMidiOut)
987 {
988         LPMIDIOPENDESC  lpDesc;
989         dprintf_mmsys(stddeb, "midiOutClose(%04X)\n", hMidiOut);
990         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
991         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
992         return modMessage(0, MODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
993 }
994
995 /**************************************************************************
996 *                               midiOutPrepareHeader    [MMSYSTEM.206]
997 */
998 UINT midiOutPrepareHeader(HMIDIOUT16 hMidiOut,
999     MIDIHDR * lpMidiOutHdr, UINT uSize)
1000 {
1001         LPMIDIOPENDESC  lpDesc;
1002         dprintf_mmsys(stddeb, "midiOutPrepareHeader(%04X, %p, %d)\n", 
1003                                         hMidiOut, lpMidiOutHdr, uSize);
1004         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1005         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1006         return modMessage(0, MODM_PREPARE, lpDesc->dwInstance, 
1007                                                 (DWORD)lpMidiOutHdr, (DWORD)uSize);
1008 }
1009
1010 /**************************************************************************
1011 *                               midiOutUnprepareHeader  [MMSYSTEM.207]
1012 */
1013 UINT midiOutUnprepareHeader(HMIDIOUT16 hMidiOut,
1014     MIDIHDR * lpMidiOutHdr, UINT uSize)
1015 {
1016         LPMIDIOPENDESC  lpDesc;
1017         dprintf_mmsys(stddeb, "midiOutUnprepareHeader(%04X, %p, %d)\n", 
1018                                         hMidiOut, lpMidiOutHdr, uSize);
1019         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1020         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1021         return modMessage(0, MODM_UNPREPARE, lpDesc->dwInstance, 
1022                                                 (DWORD)lpMidiOutHdr, (DWORD)uSize);
1023 }
1024
1025 /**************************************************************************
1026 *                               midiOutShortMsg         [MMSYSTEM.208]
1027 */
1028 UINT midiOutShortMsg(HMIDIOUT16 hMidiOut, DWORD dwMsg)
1029 {
1030         LPMIDIOPENDESC  lpDesc;
1031         dprintf_mmsys(stddeb, "midiOutShortMsg(%04X, %08lX)\n", hMidiOut, dwMsg);
1032         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1033         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1034         return modMessage(0, MODM_DATA, lpDesc->dwInstance, dwMsg, 0L);
1035 }
1036
1037 /**************************************************************************
1038 *                               midiOutLongMsg          [MMSYSTEM.209]
1039 */
1040 UINT midiOutLongMsg(HMIDIOUT16 hMidiOut,
1041     MIDIHDR * lpMidiOutHdr, UINT uSize)
1042 {
1043         LPMIDIOPENDESC  lpDesc;
1044         dprintf_mmsys(stddeb, "midiOutLongMsg(%04X, %p, %d)\n", 
1045                                 hMidiOut, lpMidiOutHdr, uSize);
1046         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1047         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1048         return modMessage(0, MODM_LONGDATA, lpDesc->dwInstance, 
1049                                                 (DWORD)lpMidiOutHdr, (DWORD)uSize);
1050 }
1051
1052 /**************************************************************************
1053 *                               midiOutReset            [MMSYSTEM.210]
1054 */
1055 UINT midiOutReset(HMIDIOUT16 hMidiOut)
1056 {
1057         LPMIDIOPENDESC  lpDesc;
1058         dprintf_mmsys(stddeb, "midiOutReset(%04X)\n", hMidiOut);
1059         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1060         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1061         return modMessage(0, MODM_RESET, lpDesc->dwInstance, 0L, 0L);
1062 }
1063
1064 /**************************************************************************
1065 *                               midiOutGetVolume        [MMSYSTEM.211]
1066 */
1067 UINT midiOutGetVolume(UINT uDeviceID, DWORD * lpdwVolume)
1068 {
1069         dprintf_mmsys(stddeb, "midiOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
1070         return modMessage(uDeviceID, MODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
1071         return 0;
1072 }
1073
1074 /**************************************************************************
1075 *                               midiOutSetVolume        [MMSYSTEM.212]
1076 */
1077 UINT midiOutSetVolume(UINT uDeviceID, DWORD dwVolume)
1078 {
1079         dprintf_mmsys(stddeb, "midiOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
1080         return modMessage(uDeviceID, MODM_SETVOLUME, 0L, dwVolume, 0L);
1081         return 0;
1082 }
1083
1084 /**************************************************************************
1085 *                               midiOutCachePatches             [MMSYSTEM.213]
1086 */
1087 UINT midiOutCachePatches(HMIDIOUT16 hMidiOut,
1088     UINT uBank, WORD * lpwPatchArray, UINT uFlags)
1089 {
1090         /* not really necessary to support this */
1091         fprintf(stdnimp, "midiOutCachePatches: not supported yet\n");
1092         return MMSYSERR_NOTSUPPORTED;
1093 }
1094
1095 /**************************************************************************
1096 *                               midiOutCacheDrumPatches [MMSYSTEM.214]
1097 */
1098 UINT midiOutCacheDrumPatches(HMIDIOUT16 hMidiOut,
1099     UINT uPatch, WORD * lpwKeyArray, UINT uFlags)
1100 {
1101         fprintf(stdnimp, "midiOutCacheDrumPatchesi: not supported yet\n");
1102         return MMSYSERR_NOTSUPPORTED;
1103 }
1104
1105 /**************************************************************************
1106 *                               midiOutGetID            [MMSYSTEM.215]
1107 */
1108 UINT midiOutGetID(HMIDIOUT16 hMidiOut, UINT * lpuDeviceID)
1109 {
1110         dprintf_mmsys(stddeb, "midiOutGetID\n");
1111         return 0;
1112 }
1113
1114 /**************************************************************************
1115 *                               midiOutMessage          [MMSYSTEM.216]
1116 */
1117 DWORD midiOutMessage(HMIDIOUT16 hMidiOut, UINT uMessage, 
1118                                                 DWORD dwParam1, DWORD dwParam2)
1119 {
1120         LPMIDIOPENDESC  lpDesc;
1121         dprintf_mmsys(stddeb, "midiOutMessage(%04X, %04X, %08lX, %08lX)\n", 
1122                         hMidiOut, uMessage, dwParam1, dwParam2);
1123         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1124         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1125         return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
1126         return 0;
1127 }
1128
1129 /**************************************************************************
1130 *                               midiInGetNumDevs        [MMSYSTEM.301]
1131 */
1132 UINT midiInGetNumDevs(void)
1133 {
1134         UINT    count = 0;
1135         dprintf_mmsys(stddeb, "midiInGetNumDevs\n");
1136         count += midMessage(0, MIDM_GETNUMDEVS, 0L, 0L, 0L);
1137         dprintf_mmsys(stddeb, "midiInGetNumDevs return %u \n", count);
1138         return count;
1139 }
1140
1141 /**************************************************************************
1142 *                               midiInGetDevCaps        [MMSYSTEM.302]
1143 */
1144 UINT midiInGetDevCaps(UINT uDeviceID,
1145     LPMIDIINCAPS lpCaps, UINT uSize)
1146 {
1147         dprintf_mmsys(stddeb, "midiInGetDevCaps\n");
1148         return 0;
1149 }
1150
1151 /**************************************************************************
1152 *                               midiInGetErrorText              [MMSYSTEM.303]
1153 */
1154 UINT midiInGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
1155 {
1156         dprintf_mmsys(stddeb, "midiInGetErrorText\n");
1157         return (midiGetErrorText(uError, lpText, uSize));
1158 }
1159
1160 /**************************************************************************
1161 *                               midiInOpen              [MMSYSTEM.304]
1162 */
1163 UINT midiInOpen(HMIDIIN16 * lphMidiIn, UINT uDeviceID,
1164     DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
1165 {
1166         HMIDI16 hMidiIn;
1167         LPMIDIOPENDESC  lpDesc;
1168         LPMIDIOPENDESC  lp16Desc;
1169         DWORD   dwRet = 0;
1170         BOOL    bMapperFlg = FALSE;
1171         if (lphMidiIn != NULL) *lphMidiIn = 0;
1172         dprintf_mmsys(stddeb, "midiInOpen(%p, %d, %08lX, %08lX, %08lX);\n", 
1173                 lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
1174         if (uDeviceID == (UINT)MIDI_MAPPER) {
1175                 dprintf_mmsys(stddeb, "midiInOpen       // MIDI_MAPPER mode requested !\n");
1176                 bMapperFlg = TRUE;
1177                 uDeviceID = 0;
1178                 }
1179         hMidiIn = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
1180         if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
1181         lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiIn);
1182         lpDesc = (LPMIDIOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
1183         if (lpDesc == NULL) return MMSYSERR_NOMEM;
1184         lpDesc->hMidi = hMidiIn;
1185         lpDesc->dwCallback = dwCallback;
1186         lpDesc->dwInstance = dwInstance;
1187         while(uDeviceID < MAXMIDIDRIVERS) {
1188                 dwRet = midMessage(uDeviceID, MIDM_OPEN, 
1189                         lpDesc->dwInstance, (DWORD)lpDesc, 0L);
1190                 if (dwRet == MMSYSERR_NOERROR) break;
1191                 if (!bMapperFlg) break;
1192                 uDeviceID++;
1193                 dprintf_mmsys(stddeb, "midiInOpen       // MIDI_MAPPER mode ! try next driver...\n");
1194                 }
1195         return dwRet;
1196 }
1197
1198 /**************************************************************************
1199 *                               midiInClose             [MMSYSTEM.305]
1200 */
1201 UINT midiInClose(HMIDIIN16 hMidiIn)
1202 {
1203         LPMIDIOPENDESC  lpDesc;
1204         dprintf_mmsys(stddeb, "midiInClose(%04X)\n", hMidiIn);
1205         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
1206         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1207         return midMessage(0, MIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
1208 }
1209
1210 /**************************************************************************
1211 *                               midiInPrepareHeader     [MMSYSTEM.306]
1212 */
1213 UINT midiInPrepareHeader(HMIDIIN16 hMidiIn,
1214     MIDIHDR * lpMidiInHdr, UINT uSize)
1215 {
1216         LPMIDIOPENDESC  lpDesc;
1217         dprintf_mmsys(stddeb, "midiInPrepareHeader(%04X, %p, %d)\n", 
1218                                         hMidiIn, lpMidiInHdr, uSize);
1219         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
1220         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1221         return midMessage(0, MIDM_PREPARE, lpDesc->dwInstance, 
1222                                                 (DWORD)lpMidiInHdr, (DWORD)uSize);
1223 }
1224
1225 /**************************************************************************
1226 *                               midiInUnprepareHeader   [MMSYSTEM.307]
1227 */
1228 UINT midiInUnprepareHeader(HMIDIIN16 hMidiIn,
1229     MIDIHDR * lpMidiInHdr, UINT uSize)
1230 {
1231         LPMIDIOPENDESC  lpDesc;
1232         dprintf_mmsys(stddeb, "midiInUnprepareHeader(%04X, %p, %d)\n", 
1233                                         hMidiIn, lpMidiInHdr, uSize);
1234         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
1235         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1236         return midMessage(0, MIDM_UNPREPARE, lpDesc->dwInstance, 
1237                                                 (DWORD)lpMidiInHdr, (DWORD)uSize);
1238 }
1239
1240 /**************************************************************************
1241 *                               midiInAddBuffer         [MMSYSTEM.308]
1242 */
1243 UINT midiInAddBuffer(HMIDIIN16 hMidiIn,
1244     MIDIHDR * lpMidiInHdr, UINT uSize)
1245 {
1246         dprintf_mmsys(stddeb, "midiInAddBuffer\n");
1247         return 0;
1248 }
1249
1250 /**************************************************************************
1251 *                               midiInStart                     [MMSYSTEM.309]
1252 */
1253 UINT midiInStart(HMIDIIN16 hMidiIn)
1254 {
1255         dprintf_mmsys(stddeb, "midiInStart\n");
1256         return 0;
1257 }
1258
1259 /**************************************************************************
1260 *                               midiInStop                      [MMSYSTEM.310]
1261 */
1262 UINT midiInStop(HMIDIIN16 hMidiIn)
1263 {
1264         dprintf_mmsys(stddeb, "midiInStop\n");
1265         return 0;
1266 }
1267
1268 /**************************************************************************
1269 *                               midiInReset                     [MMSYSTEM.311]
1270 */
1271 UINT midiInReset(HMIDIIN16 hMidiIn)
1272 {
1273         dprintf_mmsys(stddeb, "midiInReset\n");
1274         return 0;
1275 }
1276
1277 /**************************************************************************
1278 *                               midiInGetID                     [MMSYSTEM.312]
1279 */
1280 UINT midiInGetID(HMIDIIN16 hMidiIn, UINT * lpuDeviceID)
1281 {
1282         dprintf_mmsys(stddeb, "midiInGetID\n");
1283         return 0;
1284 }
1285
1286 /**************************************************************************
1287 *                               midiInMessage           [MMSYSTEM.313]
1288 */
1289 DWORD midiInMessage(HMIDIIN16 hMidiIn, UINT uMessage, 
1290                                                         DWORD dwParam1, DWORD dwParam2)
1291 {
1292         LPMIDIOPENDESC  lpDesc;
1293         dprintf_mmsys(stddeb, "midiInMessage(%04X, %04X, %08lX, %08lX)\n", 
1294                         hMidiIn, uMessage, dwParam1, dwParam2);
1295         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
1296         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1297         return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
1298 }
1299
1300
1301 /**************************************************************************
1302 *                               waveOutGetNumDevs               [MMSYSTEM.401]
1303 */
1304 UINT waveOutGetNumDevs()
1305 {
1306         UINT    count = 0;
1307         dprintf_mmsys(stddeb, "waveOutGetNumDevs\n");
1308         count += wodMessage(0, WODM_GETNUMDEVS, 0L, 0L, 0L);
1309         dprintf_mmsys(stddeb, "waveOutGetNumDevs return %u \n", count);
1310         return count;
1311 }
1312
1313 /**************************************************************************
1314 *                               waveOutGetDevCaps               [MMSYSTEM.402]
1315 */
1316 UINT waveOutGetDevCaps(UINT uDeviceID, WAVEOUTCAPS * lpCaps, UINT uSize)
1317 {
1318         dprintf_mmsys(stddeb, "waveOutGetDevCaps\n");
1319         return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
1320 }
1321
1322 /**************************************************************************
1323 *                               waveOutGetErrorText     [MMSYSTEM.403]
1324 */
1325 UINT waveOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
1326 {
1327    dprintf_mmsys(stddeb, "waveOutGetErrorText\n");
1328    return(waveGetErrorText(uError, lpText, uSize));
1329 }
1330
1331
1332 /**************************************************************************
1333 *                               waveGetErrorText                [internal]
1334 */
1335 UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
1336 {
1337         LPSTR   msgptr;
1338         dprintf_mmsys(stddeb, "waveGetErrorText(%04X, %p, %d);\n", uError, lpText, uSize);
1339         if ((lpText == NULL) || (uSize < 1)) return(FALSE);
1340         lpText[0] = '\0';
1341         switch(uError) {
1342                 case MMSYSERR_NOERROR:
1343                         msgptr = "The specified command was carried out.";
1344                         break;
1345                 case MMSYSERR_ERROR:
1346                         msgptr = "Undefined external error.";
1347                         break;
1348                 case MMSYSERR_BADDEVICEID:
1349                         msgptr = "A device ID has been used that is out of range for your system.";
1350                         break;
1351                 case MMSYSERR_NOTENABLED:
1352                         msgptr = "The driver was not enabled.";
1353                         break;
1354                 case MMSYSERR_ALLOCATED:
1355                         msgptr = "The specified device is already in use. Wait until it is free, and then try again.";
1356                         break;
1357                 case MMSYSERR_INVALHANDLE:
1358                         msgptr = "The specified device handle is invalid.";
1359                         break;
1360                 case MMSYSERR_NODRIVER:
1361                         msgptr = "There is no driver installed on your system !\n";
1362                         break;
1363                 case MMSYSERR_NOMEM:
1364                         msgptr = "Not enough memory available for this task. Quit one or more applications to increase available memory, and then try again.";
1365                         break;
1366                 case MMSYSERR_NOTSUPPORTED:
1367                         msgptr = "This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports.";
1368                         break;
1369                 case MMSYSERR_BADERRNUM:
1370                         msgptr = "An error number was specified that is not defined in the system.";
1371                         break;
1372                 case MMSYSERR_INVALFLAG:
1373                         msgptr = "An invalid flag was passed to a system function.";
1374                         break;
1375                 case MMSYSERR_INVALPARAM:
1376                         msgptr = "An invalid parameter was passed to a system function.";
1377                         break;
1378                 case WAVERR_BADFORMAT:
1379                         msgptr = "The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats";
1380                         break;
1381                 case WAVERR_STILLPLAYING:
1382                         msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
1383                         break;
1384                 case WAVERR_UNPREPARED:
1385                         msgptr = "The wave header was not prepared. Use the Prepare function to prepare the header, and then try again.";
1386                         break;
1387                 case WAVERR_SYNC:
1388                         msgptr = "Cannot open the device without using the WAVE_ALLOWSYNC flag. Use the flag, and then try again.";
1389                         break;
1390                 default:
1391                         msgptr = "Unknown MMSYSTEM Error !\n";
1392                         break;
1393                 }
1394         lstrcpyn32A(lpText, msgptr, uSize);
1395         return TRUE;
1396 }
1397
1398 /**************************************************************************
1399 *                               waveOutOpen                     [MMSYSTEM.404]
1400 */
1401 UINT waveOutOpen(HWAVEOUT16 * lphWaveOut, UINT uDeviceID,
1402     const LPWAVEFORMAT lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
1403 {
1404         HWAVEOUT16 hWaveOut;
1405         LPWAVEOPENDESC  lpDesc;
1406         LPWAVEOPENDESC  lp16Desc;
1407         DWORD   dwRet = 0;
1408         BOOL    bMapperFlg = FALSE;
1409         dprintf_mmsys(stddeb, "waveOutOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
1410                 lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
1411         if (dwFlags & WAVE_FORMAT_QUERY) {
1412                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_FORMAT_QUERY requested !\n");
1413                 }
1414         if (uDeviceID == (UINT)WAVE_MAPPER) {
1415                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_MAPPER mode requested !\n");
1416                 bMapperFlg = TRUE;
1417                 uDeviceID = 0;
1418                 }
1419         if (lpFormat == NULL) return WAVERR_BADFORMAT;
1420         hWaveOut = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
1421         if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
1422         lp16Desc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hWaveOut);
1423         lpDesc = (LPWAVEOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
1424         if (lpDesc == NULL) return MMSYSERR_NOMEM;
1425         lpDesc->hWave = hWaveOut;
1426         lpDesc->lpFormat = lpFormat;
1427         lpDesc->dwCallBack = dwCallback;
1428         lpDesc->dwInstance = dwInstance;
1429         while(uDeviceID < MAXWAVEDRIVERS) {
1430                 dwRet = wodMessage(uDeviceID, WODM_OPEN, 
1431                         lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
1432                 if (dwRet == MMSYSERR_NOERROR) break;
1433                 if (!bMapperFlg) break;
1434                 uDeviceID++;
1435                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_MAPPER mode ! try next driver...\n");
1436                 }
1437         if (dwFlags & WAVE_FORMAT_QUERY) {
1438                 dprintf_mmsys(stddeb, "waveOutOpen      // End of WAVE_FORMAT_QUERY !\n");
1439                 waveOutClose(hWaveOut);
1440                 }
1441         return dwRet;
1442 }
1443
1444 /**************************************************************************
1445 *                               waveOutClose            [MMSYSTEM.405]
1446 */
1447 UINT waveOutClose(HWAVEOUT16 hWaveOut)
1448 {
1449         LPWAVEOPENDESC  lpDesc;
1450         dprintf_mmsys(stddeb, "waveOutClose(%04X)\n", hWaveOut);
1451         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1452         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1453         return wodMessage(0, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
1454 }
1455
1456 /**************************************************************************
1457 *                               waveOutPrepareHeader    [MMSYSTEM.406]
1458 */
1459 UINT waveOutPrepareHeader(HWAVEOUT16 hWaveOut,
1460      WAVEHDR * lpWaveOutHdr, UINT uSize)
1461 {
1462         LPWAVEOPENDESC  lpDesc;
1463         dprintf_mmsys(stddeb, "waveOutPrepareHeader(%04X, %p, %u);\n", 
1464                                         hWaveOut, lpWaveOutHdr, uSize);
1465         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1466         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1467         return wodMessage(0, WODM_PREPARE, lpDesc->dwInstance, 
1468                                                         (DWORD)lpWaveOutHdr, uSize);
1469 }
1470
1471 /**************************************************************************
1472 *                               waveOutUnprepareHeader  [MMSYSTEM.407]
1473 */
1474 UINT waveOutUnprepareHeader(HWAVEOUT16 hWaveOut,
1475     WAVEHDR * lpWaveOutHdr, UINT uSize)
1476 {
1477         LPWAVEOPENDESC  lpDesc;
1478         dprintf_mmsys(stddeb, "waveOutUnprepareHeader(%04X, %p, %u);\n", 
1479                                                 hWaveOut, lpWaveOutHdr, uSize);
1480         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1481         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1482         return wodMessage(0, WODM_UNPREPARE, lpDesc->dwInstance, 
1483                                                         (DWORD)lpWaveOutHdr, uSize);
1484 }
1485
1486 /**************************************************************************
1487 *                               waveOutWrite            [MMSYSTEM.408]
1488 */
1489 UINT waveOutWrite(HWAVEOUT16 hWaveOut, WAVEHDR * lpWaveOutHdr,  UINT uSize)
1490 {
1491         LPWAVEOPENDESC  lpDesc;
1492         dprintf_mmsys(stddeb, "waveOutWrite(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
1493         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1494         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1495         return wodMessage(0, WODM_WRITE, lpDesc->dwInstance, 
1496                                                         (DWORD)lpWaveOutHdr, uSize);
1497 }
1498
1499 /**************************************************************************
1500 *                               waveOutPause            [MMSYSTEM.409]
1501 */
1502 UINT waveOutPause(HWAVEOUT16 hWaveOut)
1503 {
1504         LPWAVEOPENDESC  lpDesc;
1505         dprintf_mmsys(stddeb, "waveOutPause(%04X)\n", hWaveOut);
1506         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1507         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1508         return wodMessage(0, WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
1509 }
1510
1511 /**************************************************************************
1512 *                               waveOutRestart          [MMSYSTEM.410]
1513 */
1514 UINT waveOutRestart(HWAVEOUT16 hWaveOut)
1515 {
1516         LPWAVEOPENDESC  lpDesc;
1517         dprintf_mmsys(stddeb, "waveOutRestart(%04X)\n", hWaveOut);
1518         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1519         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1520         return wodMessage(0, WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
1521 }
1522
1523 /**************************************************************************
1524 *                               waveOutReset            [MMSYSTEM.411]
1525 */
1526 UINT waveOutReset(HWAVEOUT16 hWaveOut)
1527 {
1528         LPWAVEOPENDESC  lpDesc;
1529         dprintf_mmsys(stddeb, "waveOutReset(%04X)\n", hWaveOut);
1530         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1531         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1532         return wodMessage(0, WODM_RESET, lpDesc->dwInstance, 0L, 0L);
1533 }
1534
1535 /**************************************************************************
1536 *                               waveOutGetPosition      [MMSYSTEM.412]
1537 */
1538 UINT waveOutGetPosition(HWAVEOUT16 hWaveOut, MMTIME * lpTime, UINT uSize)
1539 {
1540         LPWAVEOPENDESC  lpDesc;
1541         dprintf_mmsys(stddeb, "waveOutGetPosition(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
1542         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1543         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1544         return wodMessage(0, WODM_GETPOS, lpDesc->dwInstance, 
1545                                                         (DWORD)lpTime, (DWORD)uSize);
1546 }
1547
1548 /**************************************************************************
1549 *                               waveOutGetPitch         [MMSYSTEM.413]
1550 */
1551 UINT waveOutGetPitch(HWAVEOUT16 hWaveOut, DWORD * lpdwPitch)
1552 {
1553         LPWAVEOPENDESC  lpDesc;
1554         dprintf_mmsys(stddeb, "waveOutGetPitch(%04X, %p);\n", hWaveOut, lpdwPitch);
1555         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1556         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1557         return wodMessage(0, WODM_GETPITCH, lpDesc->dwInstance, 
1558                                                                 (DWORD)lpdwPitch, 0L);
1559 }
1560
1561 /**************************************************************************
1562 *                               waveOutSetPitch         [MMSYSTEM.414]
1563 */
1564 UINT waveOutSetPitch(HWAVEOUT16 hWaveOut, DWORD dwPitch)
1565 {
1566         LPWAVEOPENDESC  lpDesc;
1567         dprintf_mmsys(stddeb, "waveOutSetPitch(%04X, %08lX);\n", hWaveOut, dwPitch);
1568         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1569         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1570         return wodMessage(0, WODM_SETPITCH, lpDesc->dwInstance, (DWORD)dwPitch, 0L);
1571 }
1572
1573 /**************************************************************************
1574 *                               waveOutGetVolume        [MMSYSTEM.415]
1575 */
1576 UINT waveOutGetVolume(UINT uDeviceID, DWORD * lpdwVolume)
1577 {
1578         dprintf_mmsys(stddeb, "waveOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
1579         return wodMessage(uDeviceID, WODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
1580 }
1581
1582 /**************************************************************************
1583 *                               waveOutSetVolume        [MMSYSTEM.416]
1584 */
1585 UINT waveOutSetVolume(UINT uDeviceID, DWORD dwVolume)
1586 {
1587         dprintf_mmsys(stddeb, "waveOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
1588         return wodMessage(uDeviceID, WODM_SETVOLUME, 0L, dwVolume, 0L);
1589 }
1590
1591 /**************************************************************************
1592 *                               waveOutGetPlaybackRate  [MMSYSTEM.417]
1593 */
1594 UINT waveOutGetPlaybackRate(HWAVEOUT16 hWaveOut, DWORD * lpdwRate)
1595 {
1596         LPWAVEOPENDESC  lpDesc;
1597         dprintf_mmsys(stddeb, "waveOutGetPlaybackRate(%04X, %p);\n", hWaveOut, lpdwRate);
1598         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1599         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1600         return wodMessage(0, WODM_GETPLAYBACKRATE, lpDesc->dwInstance, 
1601                                                                 (DWORD)lpdwRate, 0L);
1602 }
1603
1604 /**************************************************************************
1605 *                               waveOutSetPlaybackRate  [MMSYSTEM.418]
1606 */
1607 UINT waveOutSetPlaybackRate(HWAVEOUT16 hWaveOut, DWORD dwRate)
1608 {
1609         LPWAVEOPENDESC  lpDesc;
1610         dprintf_mmsys(stddeb, "waveOutSetPlaybackRate(%04X, %08lX);\n", hWaveOut, dwRate);
1611         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1612         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1613         return wodMessage(0, WODM_SETPLAYBACKRATE, 
1614                 lpDesc->dwInstance, (DWORD)dwRate, 0L);
1615 }
1616
1617 /**************************************************************************
1618 *                               waveOutBreakLoop        [MMSYSTEM.419]
1619 */
1620 UINT waveOutBreakLoop(HWAVEOUT16 hWaveOut)
1621 {
1622         dprintf_mmsys(stddeb, "waveOutBreakLoop(%04X)\n", hWaveOut);
1623         return MMSYSERR_INVALHANDLE;
1624 }
1625
1626 /**************************************************************************
1627 *                               waveOutGetID            [MMSYSTEM.420]
1628 */
1629 UINT waveOutGetID(HWAVEOUT16 hWaveOut, UINT * lpuDeviceID)
1630 {
1631         LPWAVEOPENDESC  lpDesc;
1632         dprintf_mmsys(stddeb, "waveOutGetID(%04X, %p);\n", hWaveOut, lpuDeviceID);
1633         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1634         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1635         if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1636 /*
1637         *lpuDeviceID = lpParms->wDeviceID; 
1638 */
1639         return 0;
1640 }
1641
1642 /**************************************************************************
1643 *                               waveOutMessage          [MMSYSTEM.421]
1644 */
1645 DWORD waveOutMessage(HWAVEOUT16 hWaveOut, UINT uMessage, 
1646                                                         DWORD dwParam1, DWORD dwParam2)
1647 {
1648         LPWAVEOPENDESC  lpDesc;
1649         dprintf_mmsys(stddeb, "waveOutMessage(%04X, %04X, %08lX, %08lX)\n", 
1650                         hWaveOut, uMessage, dwParam1, dwParam2);
1651         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
1652         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1653         return wodMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
1654 }
1655
1656 /**************************************************************************
1657 *                               waveInGetNumDevs                [MMSYSTEM.501]
1658 */
1659 UINT waveInGetNumDevs()
1660 {
1661         UINT    count = 0;
1662         dprintf_mmsys(stddeb, "waveInGetNumDevs\n");
1663         count += widMessage(0, WIDM_GETNUMDEVS, 0L, 0L, 0L);
1664         dprintf_mmsys(stddeb, "waveInGetNumDevs return %u \n", count);
1665         return count;
1666 }
1667
1668
1669 /**************************************************************************
1670 *                               waveInGetDevCaps                [MMSYSTEM.502]
1671 */
1672 UINT waveInGetDevCaps(UINT uDeviceID, WAVEINCAPS * lpCaps, UINT uSize)
1673 {
1674         dprintf_mmsys(stddeb, "waveInGetDevCaps\n");
1675         return widMessage(uDeviceID, WIDM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
1676 }
1677
1678
1679 /**************************************************************************
1680 *                               waveInGetErrorText      [MMSYSTEM.503]
1681 */
1682 UINT waveInGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
1683 {
1684    dprintf_mmsys(stddeb, "waveInGetErrorText\n");
1685    return(waveGetErrorText(uError, lpText, uSize));
1686 }
1687
1688
1689 /**************************************************************************
1690 *                               waveInOpen                      [MMSYSTEM.504]
1691 */
1692 UINT waveInOpen(HWAVEIN16 * lphWaveIn, UINT uDeviceID,
1693     const LPWAVEFORMAT lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
1694 {
1695         HWAVEIN16 hWaveIn;
1696         LPWAVEOPENDESC  lpDesc;
1697         LPWAVEOPENDESC  lp16Desc;
1698         DWORD   dwRet = 0;
1699         BOOL    bMapperFlg = FALSE;
1700         dprintf_mmsys(stddeb, "waveInOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
1701                 lphWaveIn, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
1702         if (dwFlags & WAVE_FORMAT_QUERY) {
1703                 dprintf_mmsys(stddeb, "waveInOpen // WAVE_FORMAT_QUERY requested !\n");
1704                 }
1705         if (uDeviceID == (UINT)WAVE_MAPPER) {
1706                 dprintf_mmsys(stddeb, "waveInOpen       // WAVE_MAPPER mode requested !\n");
1707                 bMapperFlg = TRUE;
1708                 uDeviceID = 0;
1709                 }
1710         if (lpFormat == NULL) return WAVERR_BADFORMAT;
1711         hWaveIn = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
1712         if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
1713         lp16Desc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hWaveIn);
1714         lpDesc = (LPWAVEOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
1715         if (lpDesc == NULL) return MMSYSERR_NOMEM;
1716         lpDesc->hWave = hWaveIn;
1717         lpDesc->lpFormat = lpFormat;
1718         lpDesc->dwCallBack = dwCallback;
1719         lpDesc->dwInstance = dwInstance;
1720         while(uDeviceID < MAXWAVEDRIVERS) {
1721                 dwRet = widMessage(uDeviceID, WIDM_OPEN, 
1722                         lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
1723                 if (dwRet == MMSYSERR_NOERROR) break;
1724                 if (!bMapperFlg) break;
1725                 uDeviceID++;
1726                 dprintf_mmsys(stddeb, "waveInOpen       // WAVE_MAPPER mode ! try next driver...\n");
1727                 }
1728         if (dwFlags & WAVE_FORMAT_QUERY) {
1729                 dprintf_mmsys(stddeb, "waveInOpen       // End of WAVE_FORMAT_QUERY !\n");
1730                 waveInClose(hWaveIn);
1731                 }
1732         return dwRet;
1733 }
1734
1735
1736 /**************************************************************************
1737 *                               waveInClose                     [MMSYSTEM.505]
1738 */
1739 UINT waveInClose(HWAVEIN16 hWaveIn)
1740 {
1741         LPWAVEOPENDESC  lpDesc;
1742         dprintf_mmsys(stddeb, "waveInClose(%04X)\n", hWaveIn);
1743         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1744         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1745         return widMessage(0, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
1746 }
1747
1748
1749 /**************************************************************************
1750 *                               waveInPrepareHeader             [MMSYSTEM.506]
1751 */
1752 UINT waveInPrepareHeader(HWAVEIN16 hWaveIn,
1753     WAVEHDR * lpWaveInHdr, UINT uSize)
1754 {
1755         LPWAVEOPENDESC  lpDesc;
1756         LPWAVEHDR               lp32WaveInHdr;
1757         dprintf_mmsys(stddeb, "waveInPrepareHeader(%04X, %p, %u);\n", 
1758                                         hWaveIn, lpWaveInHdr, uSize);
1759         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1760         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1761         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1762         lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
1763         lp32WaveInHdr->lpNext = NULL;
1764     lp32WaveInHdr->dwBytesRecorded = 0;
1765         dprintf_mmsys(stddeb, "waveInPrepareHeader // lpData=%p size=%lu \n", 
1766                 lp32WaveInHdr->lpData, lp32WaveInHdr->dwBufferLength);
1767         return widMessage(0, WIDM_PREPARE, lpDesc->dwInstance, 
1768                                                         (DWORD)lpWaveInHdr, uSize);
1769 }
1770
1771
1772 /**************************************************************************
1773 *                               waveInUnprepareHeader   [MMSYSTEM.507]
1774 */
1775 UINT waveInUnprepareHeader(HWAVEIN16 hWaveIn,
1776     WAVEHDR * lpWaveInHdr, UINT uSize)
1777 {
1778         LPWAVEOPENDESC  lpDesc;
1779         LPWAVEHDR               lp32WaveInHdr;
1780         dprintf_mmsys(stddeb, "waveInUnprepareHeader(%04X, %p, %u);\n", 
1781                                                 hWaveIn, lpWaveInHdr, uSize);
1782         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1783         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1784         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1785         lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
1786         USER_HEAP_FREE(HIWORD((DWORD)lp32WaveInHdr->lpData));
1787         lp32WaveInHdr->lpData = NULL;
1788         lp32WaveInHdr->lpNext = NULL;
1789         return widMessage(0, WIDM_UNPREPARE, lpDesc->dwInstance, 
1790                                                         (DWORD)lpWaveInHdr, uSize);
1791 }
1792
1793
1794 /**************************************************************************
1795 *                               waveInAddBuffer         [MMSYSTEM.508]
1796 */
1797 UINT waveInAddBuffer(HWAVEIN16 hWaveIn,
1798     WAVEHDR * lpWaveInHdr, UINT uSize)
1799 {
1800         LPWAVEOPENDESC  lpDesc;
1801         LPWAVEHDR               lp32WaveInHdr;
1802         dprintf_mmsys(stddeb, "waveInAddBuffer(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
1803         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1804         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1805         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1806         lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
1807         lp32WaveInHdr->lpNext = NULL;
1808     lp32WaveInHdr->dwBytesRecorded = 0;
1809         dprintf_mmsys(stddeb, "waveInAddBuffer // lpData=%p size=%lu \n", 
1810                 lp32WaveInHdr->lpData, lp32WaveInHdr->dwBufferLength);
1811         return widMessage(0, WIDM_ADDBUFFER, lpDesc->dwInstance,
1812                                                                 (DWORD)lpWaveInHdr, uSize);
1813 }
1814
1815
1816 /**************************************************************************
1817 *                               waveInStart                     [MMSYSTEM.509]
1818 */
1819 UINT waveInStart(HWAVEIN16 hWaveIn)
1820 {
1821         LPWAVEOPENDESC  lpDesc;
1822         dprintf_mmsys(stddeb, "waveInStart(%04X)\n", hWaveIn);
1823         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1824         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1825         return widMessage(0, WIDM_START, lpDesc->dwInstance, 0L, 0L);
1826 }
1827
1828
1829 /**************************************************************************
1830 *                               waveInStop                      [MMSYSTEM.510]
1831 */
1832 UINT waveInStop(HWAVEIN16 hWaveIn)
1833 {
1834         LPWAVEOPENDESC  lpDesc;
1835         dprintf_mmsys(stddeb, "waveInStop(%04X)\n", hWaveIn);
1836         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1837         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1838         return widMessage(0, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
1839 }
1840
1841
1842 /**************************************************************************
1843 *                               waveInReset                     [MMSYSTEM.511]
1844 */
1845 UINT waveInReset(HWAVEIN16 hWaveIn)
1846 {
1847         LPWAVEOPENDESC  lpDesc;
1848         dprintf_mmsys(stddeb, "waveInReset(%04X)\n", hWaveIn);
1849         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1850         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1851         return widMessage(0, WIDM_RESET, lpDesc->dwInstance, 0L, 0L);
1852 }
1853
1854
1855 /**************************************************************************
1856 *                               waveInGetPosition       [MMSYSTEM.512]
1857 */
1858 UINT waveInGetPosition(HWAVEIN16 hWaveIn, MMTIME * lpTime, UINT uSize)
1859 {
1860         LPWAVEOPENDESC  lpDesc;
1861         dprintf_mmsys(stddeb, "waveInGetPosition(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
1862         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1863         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1864         return widMessage(0, WIDM_GETPOS, lpDesc->dwInstance,
1865                           (DWORD)lpTime, (DWORD)uSize);
1866 }
1867
1868
1869 /**************************************************************************
1870 *                               waveInGetID                     [MMSYSTEM.513]
1871 */
1872 UINT waveInGetID(HWAVEIN16 hWaveIn, UINT * lpuDeviceID)
1873 {
1874         dprintf_mmsys(stddeb, "waveInGetID\n");
1875         if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1876         return 0;
1877 }
1878
1879
1880 /**************************************************************************
1881 *                               waveInMessage           [MMSYSTEM.514]
1882 */
1883 DWORD waveInMessage(HWAVEIN16 hWaveIn, UINT uMessage,
1884                     DWORD dwParam1, DWORD dwParam2)
1885 {
1886         LPWAVEOPENDESC  lpDesc;
1887         dprintf_mmsys(stddeb, "waveInMessage(%04X, %04X, %08lX, %08lX)\n", 
1888                         hWaveIn, uMessage, dwParam1, dwParam2);
1889         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
1890         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1891         return widMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
1892 }
1893
1894
1895 /**************************************************************************
1896 *                               mmioOpen                [MMSYSTEM.1210]
1897 */
1898 HMMIO16 mmioOpen(LPSTR szFileName, MMIOINFO * lpmmioinfo, DWORD dwOpenFlags)
1899 {
1900         HFILE32 hFile;
1901         HMMIO16         hmmio;
1902         OFSTRUCT        ofs;
1903         LPMMIOINFO      lpmminfo;
1904         dprintf_mmsys(stddeb, "mmioOpen('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
1905         hFile = OpenFile32(szFileName, &ofs, dwOpenFlags);
1906         if (hFile == -1) return 0;
1907         hmmio = GlobalAlloc16(GMEM_MOVEABLE, sizeof(MMIOINFO));
1908         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
1909         if (lpmminfo == NULL) return 0;
1910         memset(lpmminfo, 0, sizeof(MMIOINFO));
1911         lpmminfo->hmmio = hmmio;
1912         lpmminfo->dwReserved2 = hFile;
1913         GlobalUnlock16(hmmio);
1914         dprintf_mmsys(stddeb, "mmioOpen // return hmmio=%04X\n", hmmio);
1915         return hmmio;
1916 }
1917
1918     
1919 /**************************************************************************
1920 *                               mmioClose               [MMSYSTEM.1211]
1921 */
1922 UINT mmioClose(HMMIO16 hmmio, UINT uFlags)
1923 {
1924         LPMMIOINFO      lpmminfo;
1925         dprintf_mmsys(stddeb, "mmioClose(%04X, %04X);\n", hmmio, uFlags);
1926         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
1927         if (lpmminfo == NULL) return 0;
1928         _lclose32((HFILE32)lpmminfo->dwReserved2);
1929         GlobalUnlock16(hmmio);
1930         GlobalFree16(hmmio);
1931         return 0;
1932 }
1933
1934
1935
1936 /**************************************************************************
1937 *                               mmioRead                [MMSYSTEM.1212]
1938 */
1939 LONG mmioRead(HMMIO16 hmmio, HPSTR pch, LONG cch)
1940 {
1941         LONG            count;
1942         LPMMIOINFO      lpmminfo;
1943         dprintf_mmio(stddeb, "mmioRead(%04X, %p, %ld);\n", hmmio, pch, cch);
1944         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
1945         if (lpmminfo == NULL) return 0;
1946         count = _lread32(LOWORD(lpmminfo->dwReserved2), pch, cch);
1947         GlobalUnlock16(hmmio);
1948         dprintf_mmio(stddeb, "mmioRead // count=%ld\n", count);
1949         return count;
1950 }
1951
1952
1953
1954 /**************************************************************************
1955 *                               mmioWrite               [MMSYSTEM.1213]
1956 */
1957 LONG mmioWrite(HMMIO16 hmmio, HPCSTR pch, LONG cch)
1958 {
1959         LONG            count;
1960         LPMMIOINFO      lpmminfo;
1961         dprintf_mmsys(stddeb, "mmioWrite(%04X, %p, %ld);\n", hmmio, pch, cch);
1962         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
1963         if (lpmminfo == NULL) return 0;
1964         count = _lwrite32(LOWORD(lpmminfo->dwReserved2), (LPSTR)pch, cch);
1965         GlobalUnlock16(hmmio);
1966         return count;
1967 }
1968
1969 /**************************************************************************
1970 *                               mmioSeek                [MMSYSTEM.1214]
1971 */
1972 LONG mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin)
1973 {
1974         int             count;
1975         LPMMIOINFO      lpmminfo;
1976         dprintf_mmsys(stddeb, "mmioSeek(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
1977         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
1978         if (lpmminfo == NULL) {
1979                 dprintf_mmsys(stddeb, "mmioSeek // can't lock hmmio=%04X !\n", hmmio);
1980                 return 0;
1981                 }
1982         count = _llseek32((HFILE32)lpmminfo->dwReserved2, lOffset, iOrigin);
1983         GlobalUnlock16(hmmio);
1984         return count;
1985 }
1986
1987 /**************************************************************************
1988 *                               mmioGetInfo             [MMSYSTEM.1215]
1989 */
1990 UINT mmioGetInfo(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT uFlags)
1991 {
1992         LPMMIOINFO      lpmminfo;
1993         dprintf_mmsys(stddeb, "mmioGetInfo\n");
1994         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
1995         if (lpmminfo == NULL) return 0;
1996         memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO));
1997         GlobalUnlock16(hmmio);
1998         return 0;
1999 }
2000
2001 /**************************************************************************
2002 *                               mmioSetInfo             [MMSYSTEM.1216]
2003 */
2004 UINT mmioSetInfo(HMMIO16 hmmio, const MMIOINFO * lpmmioinfo, UINT uFlags)
2005 {
2006         LPMMIOINFO      lpmminfo;
2007         dprintf_mmsys(stddeb, "mmioSetInfo\n");
2008         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
2009         if (lpmminfo == NULL) return 0;
2010         GlobalUnlock16(hmmio);
2011         return 0;
2012 }
2013
2014 /**************************************************************************
2015 *                               mmioSetBuffer           [MMSYSTEM.1217]
2016 */
2017 UINT mmioSetBuffer(HMMIO16 hmmio, LPSTR pchBuffer, 
2018                                                 LONG cchBuffer, UINT uFlags)
2019 {
2020         dprintf_mmsys(stddeb, "mmioSetBuffer // empty stub \n");
2021         return 0;
2022 }
2023
2024 /**************************************************************************
2025 *                               mmioFlush               [MMSYSTEM.1218]
2026 */
2027 UINT mmioFlush(HMMIO16 hmmio, UINT uFlags)
2028 {
2029         LPMMIOINFO      lpmminfo;
2030         dprintf_mmsys(stddeb, "mmioFlush(%04X, %04X)\n", hmmio, uFlags);
2031         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
2032         if (lpmminfo == NULL) return 0;
2033         GlobalUnlock16(hmmio);
2034         return 0;
2035 }
2036
2037 /**************************************************************************
2038 *                               mmioAdvance             [MMSYSTEM.1219]
2039 */
2040 UINT mmioAdvance(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT uFlags)
2041 {
2042         int             count = 0;
2043         LPMMIOINFO      lpmminfo;
2044         dprintf_mmsys(stddeb, "mmioAdvance\n");
2045         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
2046         if (lpmminfo == NULL) return 0;
2047         if (uFlags == MMIO_READ) {
2048                 count = _lread32(LOWORD(lpmminfo->dwReserved2), 
2049                         lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
2050                 }
2051         if (uFlags == MMIO_WRITE) {
2052                 count = _lwrite32(LOWORD(lpmminfo->dwReserved2),
2053                         lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
2054                 }
2055         lpmmioinfo->pchNext     += count;
2056         GlobalUnlock16(hmmio);
2057         lpmminfo->lDiskOffset = _llseek32((HFILE32)lpmminfo->dwReserved2, 0, SEEK_CUR);
2058         return 0;
2059 }
2060
2061 /**************************************************************************
2062 *                               mmioStringToFOURCC      [MMSYSTEM.1220]
2063 */
2064 FOURCC mmioStringToFOURCC(LPCSTR sz, UINT uFlags)
2065 {
2066         dprintf_mmsys(stddeb, "mmioStringToFOURCC // empty stub \n");
2067         return 0;
2068 }
2069
2070 /**************************************************************************
2071 *                               mmioInstallIOProc       [MMSYSTEM.1221]
2072 */
2073 LPMMIOPROC mmioInstallIOProc(FOURCC fccIOProc, 
2074                                 LPMMIOPROC pIOProc, DWORD dwFlags)
2075 {
2076         dprintf_mmsys(stddeb, "mmioInstallIOProc // empty stub \n");
2077         return 0;
2078 }
2079
2080 /**************************************************************************
2081 *                               mmioSendMessage         [MMSYSTEM.1222]
2082 */
2083 LRESULT mmioSendMessage(HMMIO16 hmmio, UINT uMessage,
2084                                             LPARAM lParam1, LPARAM lParam2)
2085 {
2086         dprintf_mmsys(stddeb, "mmioSendMessage // empty stub \n");
2087         return 0;
2088 }
2089
2090 /**************************************************************************
2091 *                               mmioDescend             [MMSYSTEM.1223]
2092 */
2093 UINT mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
2094                     const MMCKINFO * lpckParent, UINT uFlags)
2095 {
2096         DWORD   dwfcc, dwOldPos;
2097         LPMMIOINFO      lpmminfo;
2098         dprintf_mmio(stddeb, "mmioDescend(%04X, %p, %p, %04X);\n", 
2099                                 hmmio, lpck, lpckParent, uFlags);
2100         if (lpck == NULL) return 0;
2101         lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
2102         if (lpmminfo == NULL) return 0;
2103         dwfcc = lpck->ckid;
2104         dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX\n", dwfcc);
2105         dwOldPos = _llseek32((HFILE32)lpmminfo->dwReserved2, 0, SEEK_CUR);
2106         dprintf_mmio(stddeb, "mmioDescend // dwOldPos=%ld\n", dwOldPos);
2107         if (lpckParent != NULL) {
2108                 dprintf_mmio(stddeb, "mmioDescend // seek inside parent at %ld !\n", lpckParent->dwDataOffset);
2109                 dwOldPos = _llseek32((HFILE32)lpmminfo->dwReserved2,
2110                                         lpckParent->dwDataOffset, SEEK_SET);
2111                 }
2112         if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDRIFF) || 
2113                 (uFlags & MMIO_FINDLIST)) {
2114                 dprintf_mmio(stddeb, "mmioDescend // MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc);
2115                 while (TRUE) {
2116                         if (_lread32((HFILE32)lpmminfo->dwReserved2, (LPSTR)lpck, 
2117                                         sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
2118                                 _llseek32((HFILE32)lpmminfo->dwReserved2, dwOldPos, SEEK_SET);
2119                                 GlobalUnlock16(hmmio);
2120                                 return MMIOERR_CHUNKNOTFOUND;
2121                                 }
2122                         dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX ckid=%08lX cksize=%08lX !\n", 
2123                                                                         dwfcc, lpck->ckid, lpck->cksize);
2124                         if (dwfcc == lpck->ckid) break;
2125                         dwOldPos += lpck->cksize + 2 * sizeof(DWORD);
2126                         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
2127                                 dwOldPos += sizeof(DWORD);
2128                         _llseek32((HFILE32)lpmminfo->dwReserved2, dwOldPos, SEEK_SET);
2129                         }
2130                 }
2131         else {
2132                 if (_lread32(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
2133                                 sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
2134                     _llseek32((HFILE32)lpmminfo->dwReserved2, dwOldPos, SEEK_SET);
2135                         GlobalUnlock16(hmmio);
2136                         return MMIOERR_CHUNKNOTFOUND;
2137                         }
2138                 }
2139         lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
2140         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
2141                 lpck->dwDataOffset += sizeof(DWORD);
2142         lpmminfo->lDiskOffset = _llseek32((HFILE32)lpmminfo->dwReserved2, 
2143                                           lpck->dwDataOffset, SEEK_SET);
2144         GlobalUnlock16(hmmio);
2145         dprintf_mmio(stddeb, "mmioDescend // lpck->ckid=%08lX lpck->cksize=%ld !\n", 
2146                                                                 lpck->ckid, lpck->cksize);
2147         dprintf_mmsys(stddeb, "mmioDescend // lpck->fccType=%08lX !\n", lpck->fccType);
2148         return 0;
2149 }
2150
2151 /**************************************************************************
2152 *                               mmioAscend              [MMSYSTEM.1224]
2153 */
2154 UINT mmioAscend(HMMIO16 hmmio, MMCKINFO * lpck, UINT uFlags)
2155 {
2156         dprintf_mmsys(stddeb, "mmioAscend // empty stub !\n");
2157         return 0;
2158 }
2159
2160 /**************************************************************************
2161 *                               mmioCreateChunk         [MMSYSTEM.1225]
2162 */
2163 UINT mmioCreateChunk(HMMIO16 hmmio, MMCKINFO * lpck, UINT uFlags)
2164 {
2165         dprintf_mmsys(stddeb, "mmioCreateChunk // empty stub \n");
2166         return 0;
2167 }
2168
2169
2170 /**************************************************************************
2171 *                               mmioRename              [MMSYSTEM.1226]
2172 */
2173 UINT mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
2174      MMIOINFO * lpmmioinfo, DWORD dwRenameFlags)
2175 {
2176         dprintf_mmsys(stddeb, "mmioRename('%s', '%s', %p, %08lX); // empty stub \n",
2177                         szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
2178         return 0;
2179 }
2180
2181 /**************************************************************************
2182 *                               DrvOpen                 [MMSYSTEM.1100]
2183 */
2184 HDRVR16 DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
2185 {
2186         dprintf_mmsys(stddeb, "DrvOpen('%s', '%s', %08lX);\n",
2187                 lpDriverName, lpSectionName, lParam);
2188         return OpenDriver(lpDriverName, lpSectionName, lParam);
2189 }
2190
2191
2192 /**************************************************************************
2193 *                               DrvClose                [MMSYSTEM.1101]
2194 */
2195 LRESULT DrvClose(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
2196 {
2197         dprintf_mmsys(stddeb, "DrvClose(%04X, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
2198         return CloseDriver(hDrvr, lParam1, lParam2);
2199 }
2200
2201
2202 /**************************************************************************
2203 *                               DrvSendMessage          [MMSYSTEM.1102]
2204 */
2205 LRESULT DrvSendMessage(HDRVR16 hDriver, WORD msg, LPARAM lParam1, LPARAM lParam2)
2206 {
2207         DWORD   dwDevID = 0;
2208         dprintf_mmsys(stddeb, "DrvSendMessage(%04X, %04X, %08lX, %08lX);\n",
2209                                         hDriver, msg, lParam1, lParam2);
2210 #ifndef WINELIB
2211         return CDAUDIO_DriverProc(dwDevID, hDriver, msg, lParam1, lParam2);
2212 #endif
2213 }
2214
2215 /**************************************************************************
2216 *                               DrvGetModuleHandle      [MMSYSTEM.1103]
2217 */
2218 HANDLE16 DrvGetModuleHandle(HDRVR16 hDrvr)
2219 {
2220         dprintf_mmsys(stddeb, "DrvGetModuleHandle(%04X);\n", hDrvr);
2221         return 0;
2222 }
2223
2224
2225 /**************************************************************************
2226 *                               DrvDefDriverProc        [MMSYSTEM.1104]
2227 */
2228 LRESULT DrvDefDriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
2229                                                 DWORD dwParam1, DWORD dwParam2)
2230 {
2231         return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
2232 }
2233
2234
2235 #endif /* #ifdef WINELIB */
2236