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