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