Release 950817
[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 "callback.h"
21 #include "user.h"
22 #include "driver.h"
23 #include "mmsystem.h"
24 #include "stddebug.h"
25 #include "debug.h"
26
27 static int      InstalledCount;
28 static int      InstalledListLen;
29 static LPSTR    lpInstallNames = NULL;
30
31 static MCI_OPEN_DRIVER_PARMS    mciDrv[MAXMCIDRIVERS];
32 /* FIXME: I need to remember the aliasname of a spec. driver. 
33  *        and this is the easiest way. *sigh*
34  */
35 static MCI_OPEN_PARMS           mciOpenDrv[MAXMCIDRIVERS];
36
37 UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
38 UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
39 LONG DrvDefDriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
40                       DWORD dwParam1, DWORD dwParam2);
41
42 LONG WAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
43                      DWORD dwParam1, DWORD dwParam2);
44 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
45                      DWORD dwParam1, DWORD dwParam2);
46 LONG CDAUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
47                         DWORD dwParam1, DWORD dwParam2);
48 LONG ANIM_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
49                      DWORD dwParam1, DWORD dwParam2);
50
51 /**************************************************************************
52 *                               MMSYSTEM_WEP            [MMSYSTEM.1]
53 */
54 int MMSYSTEM_WEP(HANDLE hInstance, WORD wDataSeg,
55                  WORD cbHeapSize, LPSTR lpCmdLine)
56 {
57         /* isn't WEP the Windows Exit Procedure ? */
58         printf("MMSYSTEM DLL INIT ... hInst=%04X \n", hInstance);
59         return(TRUE);
60 }
61
62 /**************************************************************************
63 *                               sndPlaySound            [MMSYSTEM.2]
64 */
65 BOOL sndPlaySound(LPCSTR lpszSoundName, UINT uFlags)
66 {
67         HMMIO                   hmmio;
68         MMCKINFO                mmckInfo;
69         MMCKINFO                ckMainRIFF;
70         HANDLE                  hFormat;
71         PCMWAVEFORMAT   pcmWaveFormat;
72         int                             count;
73         int                             bufsize;
74         HANDLE                  hDesc;
75         LPWAVEOPENDESC  lpWaveDesc;
76         HANDLE                  hWaveHdr;
77         LPWAVEHDR               lpWaveHdr;
78         LPWAVEHDR               lp16WaveHdr;
79         HANDLE                  hData;
80         DWORD                   dwRet;
81         char                    str[128];
82         LPSTR                   ptr;
83         dprintf_mmsys(stddeb, "sndPlaySound // SoundName='%s' uFlags=%04X !\n", 
84                                                                         lpszSoundName, uFlags);
85         if (lpszSoundName == NULL) {
86                 dprintf_mmsys(stddeb, "sndPlaySound // Stop !\n");
87                 return FALSE;
88                 }
89         hmmio = mmioOpen((LPSTR)lpszSoundName, NULL, 
90                 MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
91         if (hmmio == 0) {
92                 dprintf_mmsys(stddeb, "sndPlaySound // searching in SystemSound List !\n");
93                 GetProfileString("Sounds", (LPSTR)lpszSoundName, "", str, sizeof(str));
94                 if (strlen(str) == 0) return FALSE;
95                 if ( (ptr = (LPSTR)strchr(str, ',')) != NULL) *ptr = '\0';
96                 hmmio = mmioOpen(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
97                 if (hmmio == 0) {
98                         dprintf_mmsys(stddeb, "sndPlaySound // can't find SystemSound='%s' !\n", str);
99                         return FALSE;
100                         }
101                 }
102         if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0) != 0) {
103 ErrSND: if (hmmio != 0)   mmioClose(hmmio, 0);
104                 return FALSE;
105                 }
106         dprintf_mmsys(stddeb, "sndPlaySound // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
107                                 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
108                                 ckMainRIFF.cksize);
109         if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
110             (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) goto ErrSND;
111         mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
112         if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) goto ErrSND;
113         dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
114                         (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
115                         mmckInfo.cksize);
116         if (mmioRead(hmmio, (HPSTR) &pcmWaveFormat,
117                 (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) goto ErrSND;
118
119         dprintf_mmsys(stddeb, "sndPlaySound // wFormatTag=%04X !\n", pcmWaveFormat.wf.wFormatTag);
120         dprintf_mmsys(stddeb, "sndPlaySound // nChannels=%d \n", pcmWaveFormat.wf.nChannels);
121         dprintf_mmsys(stddeb, "sndPlaySound // nSamplesPerSec=%ld\n", pcmWaveFormat.wf.nSamplesPerSec);
122         dprintf_mmsys(stddeb, "sndPlaySound // nAvgBytesPerSec=%ld\n", pcmWaveFormat.wf.nAvgBytesPerSec);
123         dprintf_mmsys(stddeb, "sndPlaySound // nBlockAlign=%d \n", pcmWaveFormat.wf.nBlockAlign);
124         dprintf_mmsys(stddeb, "sndPlaySound // wBitsPerSample=%u !\n", pcmWaveFormat.wBitsPerSample);
125
126         mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
127         if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) goto ErrSND;
128         dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
129                         (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
130                         mmckInfo.cksize);
131         hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
132         lpWaveDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
133         lpWaveDesc->hWave = 0;
134         pcmWaveFormat.wf.nAvgBytesPerSec = 
135                 pcmWaveFormat.wf.nSamplesPerSec * pcmWaveFormat.wf.nBlockAlign;
136         hFormat = USER_HEAP_ALLOC(sizeof(PCMWAVEFORMAT));
137         lpWaveDesc->lpFormat = (LPWAVEFORMAT) USER_HEAP_LIN_ADDR(hFormat);
138         memcpy(lpWaveDesc->lpFormat, &pcmWaveFormat, sizeof(PCMWAVEFORMAT));
139         lpWaveDesc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hDesc);
140         dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)lpWaveDesc, CALLBACK_NULL);
141         if (dwRet != MMSYSERR_NOERROR) {
142                 dprintf_mmsys(stddeb, "sndPlaySound // can't open WaveOut device !\n");
143                 goto ErrSND;
144                 }
145         USER_HEAP_FREE(hFormat);
146         hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
147         lpWaveHdr = (LPWAVEHDR) USER_HEAP_LIN_ADDR(hWaveHdr);
148         lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
149         bufsize = 64000;
150         hData = GlobalAlloc(GMEM_MOVEABLE, bufsize);
151         lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock(hData);
152         lpWaveHdr->dwBufferLength = bufsize;
153         lpWaveHdr->dwUser = 0L;
154         lpWaveHdr->dwFlags = 0L;
155         lpWaveHdr->dwLoops = 0L;
156         dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
157         if (dwRet != MMSYSERR_NOERROR) {
158                 dprintf_mmsys(stddeb, "sndPlaySound // can't prepare WaveOut device !\n");
159                 GlobalUnlock(hData);
160                 GlobalFree(hData);
161                 USER_HEAP_FREE(hDesc);
162                 USER_HEAP_FREE(hWaveHdr);
163                 goto ErrSND;
164                 }
165         while(TRUE) {
166                 count = mmioRead(hmmio, PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
167                 if (count < 1) break;
168                 lpWaveHdr->dwBufferLength = count;
169 /*              lpWaveHdr->dwBytesRecorded = count; */
170                 wodMessage(0, WODM_WRITE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
171                 }
172         wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
173         wodMessage(0, WODM_CLOSE, 0, 0L, 0L);
174         GlobalUnlock(hData);
175         GlobalFree(hData);
176         USER_HEAP_FREE(hDesc);
177         USER_HEAP_FREE(hWaveHdr);
178         if (hmmio != 0)   mmioClose(hmmio, 0);
179         return TRUE;
180 }
181
182 /**************************************************************************
183 *                               mmsystemGetVersion      [MMSYSTEM.5]
184 */
185 WORD mmsystemGetVersion()
186 {
187         dprintf_mmsys(stddeb, "mmsystemGetVersion // 0.4.0 ...?... :-) !\n");
188         return 0x0040;
189 }
190
191 /**************************************************************************
192 *                               DriverProc      [MMSYSTEM.6]
193 */
194 LRESULT DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
195                                                 DWORD dwParam1, DWORD dwParam2)
196 {
197         return DrvDefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
198 }
199
200 /**************************************************************************
201 *                               OutputDebugStr          [MMSYSTEM.30]
202 */
203 void OutputDebugStr(LPCSTR str)
204 {
205         fprintf(stdnimp, "EMPTY STUB !!! OutputDebugStr('%s');\n", str);
206 }
207
208 /**************************************************************************
209 *                               DriverCallback  [MMSYSTEM.31]
210 */
211 BOOL DriverCallback(DWORD dwCallBack, UINT uFlags, HANDLE hDev, 
212                 WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
213 {
214         dprintf_mmsys(stddeb, "DriverCallback(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
215                 dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
216         switch(uFlags & DCB_TYPEMASK) {
217                 case DCB_NULL:
218                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_NULL !\n");
219                         break;
220                 case DCB_WINDOW:
221                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_WINDOW !\n");
222                         break;
223                 case DCB_TASK:
224                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_TASK !\n");
225                         break;
226                 case DCB_FUNCTION:
227                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_FUNCTION !\n");
228                         break;
229                 }
230         return TRUE;
231 }
232
233 /**************************************************************************
234 *                               auxGetNumDevs           [MMSYSTEM.350]
235 */
236 UINT auxGetNumDevs()
237 {
238         UINT    count = 0;
239         dprintf_mmsys(stddeb, "auxGetNumDevs !\n");
240         count += auxMessage(0, AUXDM_GETNUMDEVS, 0L, 0L, 0L);
241         dprintf_mmsys(stddeb, "auxGetNumDevs return %u \n", count);
242         return count;
243 }
244
245 /**************************************************************************
246 *                               auxGetDevCaps           [MMSYSTEM.351]
247 */
248 UINT auxGetDevCaps(UINT uDeviceID, AUXCAPS FAR* lpCaps, UINT uSize)
249 {
250         dprintf_mmsys(stddeb, "auxGetDevCaps(%04X, %p, %d) !\n", 
251                                         uDeviceID, lpCaps, uSize);
252         return auxMessage(uDeviceID, AUXDM_GETDEVCAPS, 
253                                 0L, (DWORD)lpCaps, (DWORD)uSize);
254 }
255
256 /**************************************************************************
257 *                               auxGetVolume            [MMSYSTEM.352]
258 */
259 UINT auxGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume)
260 {
261         dprintf_mmsys(stddeb, "auxGetVolume(%04X, %p) !\n", uDeviceID, lpdwVolume);
262         return auxMessage(uDeviceID, AUXDM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
263 }
264
265 /**************************************************************************
266 *                               auxSetVolume            [MMSYSTEM.353]
267 */
268 UINT auxSetVolume(UINT uDeviceID, DWORD dwVolume)
269 {
270         dprintf_mmsys(stddeb, "auxSetVolume(%04X, %08lX) !\n", uDeviceID, dwVolume);
271         return auxMessage(uDeviceID, AUXDM_SETVOLUME, 0L, dwVolume, 0L);
272 }
273
274 /**************************************************************************
275 *                               auxOutMessage           [MMSYSTEM.354]
276 */
277 DWORD auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2)
278 {
279         dprintf_mmsys(stddeb, "auxOutMessage(%04X, %04X, %08lX, %08lX)\n", 
280                                 uDeviceID, uMessage, dw1, dw2);
281         return auxMessage(uDeviceID, uMessage, 0L, dw1, dw2);
282 }
283
284 /**************************************************************************
285 *                               mciGetErrorString               [MMSYSTEM.706]
286 */
287 BOOL mciGetErrorString (DWORD wError, LPSTR lpstrBuffer, UINT uLength)
288 {
289         LPSTR   msgptr;
290         int             maxbuf;
291         dprintf_mmsys(stddeb, "mciGetErrorString(%08lX, %p, %d);\n", wError, lpstrBuffer, uLength);
292         if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE);
293         lpstrBuffer[0] = '\0';
294         switch(wError) {
295                 case MCIERR_INVALID_DEVICE_ID:
296                         msgptr = "Invalid MCI device ID. Use the ID returned when opening the MCI device.";
297                         break;
298                 case MCIERR_UNRECOGNIZED_KEYWORD:
299                         msgptr = "The driver cannot recognize the specified command parameter.";
300                         break;
301                 case MCIERR_UNRECOGNIZED_COMMAND:
302                         msgptr = "The driver cannot recognize the specified command.";
303                         break;
304                 case MCIERR_HARDWARE:
305                         msgptr = "There is a problem with your media device. Make sure it is working correctly or contact the device manufacturer.";
306                         break;
307                 case MCIERR_INVALID_DEVICE_NAME:
308                         msgptr = "The specified device is not open or is not recognized by MCI.";
309                         break;
310                 case MCIERR_OUT_OF_MEMORY:
311                         msgptr = "Not enough memory available for this task. \nQuit one or more applications to increase available memory, and then try again.";
312                         break;
313                 case MCIERR_DEVICE_OPEN:
314                         msgptr = "The device name is already being used as an alias by this application. Use a unique alias.";
315                         break;
316                 case MCIERR_CANNOT_LOAD_DRIVER:
317                         msgptr = "There is an undetectable problem in loading the specified device driver.";
318                         break;
319                 case MCIERR_MISSING_COMMAND_STRING:
320                         msgptr = "No command was specified.";
321                         break;
322                 case MCIERR_PARAM_OVERFLOW:
323                         msgptr = "The output string was to large to fit in the return buffer. Increase the size of the buffer.";
324                         break;
325                 case MCIERR_MISSING_STRING_ARGUMENT:
326                         msgptr = "The specified command requires a character-string parameter. Please provide one.";
327                         break;
328                 case MCIERR_BAD_INTEGER:
329                         msgptr = "The specified integer is invalid for this command.";
330                         break;
331                 case MCIERR_PARSER_INTERNAL:
332                         msgptr = "The device driver returned an invalid return type. Check with the device manufacturer about obtaining a new driver.";
333                         break;
334                 case MCIERR_DRIVER_INTERNAL:
335                         msgptr = "There is a problem with the device driver. Check with the device manufacturer about obtaining a new driver.";
336                         break;
337                 case MCIERR_MISSING_PARAMETER:
338                         msgptr = "The specified command requires a parameter. Please supply one.";
339                         break;
340                 case MCIERR_UNSUPPORTED_FUNCTION:
341                         msgptr = "The MCI device you are using does not support the specified command.";
342                         break;
343                 case MCIERR_FILE_NOT_FOUND:
344                         msgptr = "Cannot find the specified file. Make sure the path and filename are correct.";
345                         break;
346                 case MCIERR_DEVICE_NOT_READY:
347                         msgptr = "The device driver is not ready.";
348                         break;
349                 case MCIERR_INTERNAL:
350                         msgptr = "A problem occurred in initializing MCI. Try restarting Windows.";
351                         break;
352                 case MCIERR_DRIVER:
353                         msgptr = "There is a problem with the device driver. The driver has closed. Cannot access error.";
354                         break;
355                 case MCIERR_CANNOT_USE_ALL:
356                         msgptr = "Cannot use 'all' as the device name with the specified command.";
357                         break;
358                 case MCIERR_MULTIPLE:
359                         msgptr = "Errors occurred in more than one device. Specify each command and device separately to determine which devices caused the error";
360                         break;
361                 case MCIERR_EXTENSION_NOT_FOUND:
362                         msgptr = "Cannot determine the device type from the given filename extension.";
363                         break;
364                 case MCIERR_OUTOFRANGE:
365                         msgptr = "The specified parameter is out of range for the specified command.";
366                         break;
367                 case MCIERR_FLAGS_NOT_COMPATIBLE:
368                         msgptr = "The specified parameters cannot be used together.";
369                         break;
370                 case MCIERR_FILE_NOT_SAVED:
371                         msgptr = "Cannot save the specified file. Make sure you have enough disk space or are still connected to the network.";
372                         break;
373                 case MCIERR_DEVICE_TYPE_REQUIRED:
374                         msgptr = "Cannot find the specified device. Make sure it is installed or that the device name is spelled correctly.";
375                         break;
376                 case MCIERR_DEVICE_LOCKED:
377                         msgptr = "The specified device is now being closed. Wait a few seconds, and then try again.";
378                         break;
379                 case MCIERR_DUPLICATE_ALIAS:
380                         msgptr = "The specified alias is already being used in this application. Use a unique alias.";
381                         break;
382                 case MCIERR_BAD_CONSTANT:
383                         msgptr = "The specified parameter is invalid for this command.";
384                         break;
385                 case MCIERR_MUST_USE_SHAREABLE:
386                         msgptr = "The device driver is already in use. To share it, use the 'shareable' parameter with each 'open' command.";
387                         break;
388                 case MCIERR_MISSING_DEVICE_NAME:
389                         msgptr = "The specified command requires an alias, file, driver, or device name. Please supply one.";
390                         break;
391                 case MCIERR_BAD_TIME_FORMAT:
392                         msgptr = "The specified value for the time format is invalid. Refer to the MCI documentation for valid formats.";
393                         break;
394                 case MCIERR_NO_CLOSING_QUOTE:
395                         msgptr = "A closing double-quotation mark is missing from the parameter value. Please supply one.";
396                         break;
397                 case MCIERR_DUPLICATE_FLAGS:
398                         msgptr = "A parameter or value was specified twice. Only specify it once.";
399                         break;
400                 case MCIERR_INVALID_FILE:
401                         msgptr = "The specified file cannot be played on the specified MCI device. The file may be corrupt, or not in the correct format.";
402                         break;
403                 case MCIERR_NULL_PARAMETER_BLOCK:
404                         msgptr = "A null parameter block was passed to MCI.";
405                         break;
406                 case MCIERR_UNNAMED_RESOURCE:
407                         msgptr = "Cannot save an unnamed file. Supply a filename.";
408                         break;
409                 case MCIERR_NEW_REQUIRES_ALIAS:
410                         msgptr = "You must specify an alias when using the 'new' parameter.";
411                         break;
412                 case MCIERR_NOTIFY_ON_AUTO_OPEN:
413                         msgptr = "Cannot use the 'notify' flag with auto-opened devices.";
414                         break;
415                 case MCIERR_NO_ELEMENT_ALLOWED:
416                         msgptr = "Cannot use a filename with the specified device.";
417                         break;
418                 case MCIERR_NONAPPLICABLE_FUNCTION:
419                         msgptr = "Cannot carry out the commands in the order specified. Correct the command sequence, and then try again.";
420                         break;
421                 case MCIERR_ILLEGAL_FOR_AUTO_OPEN:
422                         msgptr = "Cannot carry out the specified command on an auto-opened device. Wait until the device is closed, and then try again.";
423                         break;
424                 case MCIERR_FILENAME_REQUIRED:
425                         msgptr = "The filename is invalid. Make sure the filename is not longer than 8 characters, followed by a period and an extension.";
426                         break;
427                 case MCIERR_EXTRA_CHARACTERS:
428                         msgptr = "Cannot specify extra characters after a string enclosed in quotation marks.";
429                         break;
430                 case MCIERR_DEVICE_NOT_INSTALLED:
431                         msgptr = "The specified device is not installed on the system. Use the Drivers option in Control Panel to install the device.";
432                         break;
433                 case MCIERR_GET_CD:
434                         msgptr = "Cannot access the specified file or MCI device. Try changing directories or restarting your computer.";
435                         break;
436                 case MCIERR_SET_CD:
437                         msgptr = "Cannot access the specified file or MCI device because the application cannot change directories.";
438                         break;
439                 case MCIERR_SET_DRIVE:
440                         msgptr = "Cannot access specified file or MCI device because the application cannot change drives.";
441                         break;
442                 case MCIERR_DEVICE_LENGTH:
443                         msgptr = "Specify a device or driver name that is less than 79 characters.";
444                         break;
445                 case MCIERR_DEVICE_ORD_LENGTH:
446                         msgptr = "Specify a device or driver name that is less than 69 characters.";
447                         break;
448                 case MCIERR_NO_INTEGER:
449                         msgptr = "The specified command requires an integer parameter. Please provide one.";
450                         break;
451                 case MCIERR_WAVE_OUTPUTSINUSE:
452                         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.";
453                         break;
454                 case MCIERR_WAVE_SETOUTPUTINUSE:
455                         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.";
456                         break;
457                 case MCIERR_WAVE_INPUTSINUSE:
458                         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.";
459                         break;
460                 case MCIERR_WAVE_SETINPUTINUSE:
461                         msgptr = "Cannot set the current wave device for recording because it is in use. Wait until the device is free, and then try again.";
462                         break;
463                 case MCIERR_WAVE_OUTPUTUNSPECIFIED:
464                         msgptr = "Any compatible waveform playback device may be used.";
465                         break;
466                 case MCIERR_WAVE_INPUTUNSPECIFIED:
467                         msgptr = "Any compatible waveform recording device may be used.";
468                         break;
469                 case MCIERR_WAVE_OUTPUTSUNSUITABLE:
470                         msgptr = "No wave device that can play files in the current format is installed. Use the Drivers option to install the wave device.";
471                         break;
472                 case MCIERR_WAVE_SETOUTPUTUNSUITABLE:
473                         msgptr = "The device you are trying to play to cannot recognize the current file format.";
474                         break;
475                 case MCIERR_WAVE_INPUTSUNSUITABLE:
476                         msgptr = "No wave device that can record files in the current format is installed. Use the Drivers option to install the wave device.";
477                         break;
478                 case MCIERR_WAVE_SETINPUTUNSUITABLE:
479                         msgptr = "The device you are trying to record from cannot recognize the current file format.";
480                         break;
481                 case MCIERR_NO_WINDOW:
482                         msgptr = "There is no display window.";
483                         break;
484                 case MCIERR_CREATEWINDOW:
485                         msgptr = "Could not create or use window.";
486                         break;
487                 case MCIERR_FILE_READ:
488                         msgptr = "Cannot read the specified file. Make sure the file is still present, or check your disk or network connection.";
489                         break;
490                 case MCIERR_FILE_WRITE:
491                         msgptr = "Cannot write to the specified file. Make sure you have enough disk space or are still connected to the network.";
492                         break;
493
494 /* 
495 #define MCIERR_SEQ_DIV_INCOMPATIBLE     (MCIERR_BASE + 80)
496 #define MCIERR_SEQ_PORT_INUSE           (MCIERR_BASE + 81)
497 #define MCIERR_SEQ_PORT_NONEXISTENT     (MCIERR_BASE + 82)
498 #define MCIERR_SEQ_PORT_MAPNODEVICE     (MCIERR_BASE + 83)
499 #define MCIERR_SEQ_PORT_MISCERROR       (MCIERR_BASE + 84)
500 #define MCIERR_SEQ_TIMER                (MCIERR_BASE + 85)
501 #define MCIERR_SEQ_PORTUNSPECIFIED      (MCIERR_BASE + 86)
502 #define MCIERR_SEQ_NOMIDIPRESENT        (MCIERR_BASE + 87)
503
504 msg# 513 : vcr
505 msg# 514 : videodisc
506 msg# 515 : overlay
507 msg# 516 : cdaudio
508 msg# 517 : dat
509 msg# 518 : scanner
510 msg# 519 : animation
511 msg# 520 : digitalvideo
512 msg# 521 : other
513 msg# 522 : waveaudio
514 msg# 523 : sequencer
515 msg# 524 : not ready
516 msg# 525 : stopped
517 msg# 526 : playing
518 msg# 527 : recording
519 msg# 528 : seeking
520 msg# 529 : paused
521 msg# 530 : open
522 msg# 531 : false
523 msg# 532 : true
524 msg# 533 : milliseconds
525 msg# 534 : hms
526 msg# 535 : msf
527 msg# 536 : frames
528 msg# 537 : smpte 24
529 msg# 538 : smpte 25
530 msg# 539 : smpte 30
531 msg# 540 : smpte 30 drop
532 msg# 541 : bytes
533 msg# 542 : samples
534 msg# 543 : tmsf
535 */
536                 default:
537                         msgptr = "Unknown MCI Error !\n";
538                         break;
539                 }
540         maxbuf = min(uLength - 1, strlen(msgptr));
541         if (maxbuf > 0) strncpy(lpstrBuffer, msgptr, maxbuf);
542         lpstrBuffer[maxbuf + 1] = '\0';
543         return(TRUE);
544 }
545
546
547 /**************************************************************************
548 *                               mciDriverNotify                 [MMSYSTEM.711]
549 */
550 BOOL mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus)
551 {
552         dprintf_mmsys(stddeb, "mciDriverNotify(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
553         if (!IsWindow(hWndCallBack)) return FALSE;
554         dprintf_mmsys(stddeb, "mciDriverNotify // before PostMessage\n");
555         PostMessage(hWndCallBack, MM_MCINOTIFY, wStatus, 
556                         MAKELONG(mciDrv[wDevID].wDeviceID, 0));
557         return TRUE;
558 }
559
560 /**************************************************************************
561 *                               mciOpen                                 [internal]
562 */
563 DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS lp16Parms)
564 {
565         char    str[128];
566         LPMCI_OPEN_PARMS lpParms;
567         UINT    uDevTyp = 0;
568         UINT    wDevID = 0;
569         lpParms = PTR_SEG_TO_LIN(lp16Parms);
570         dprintf_mmsys(stddeb, "mciOpen(%08lX, %p (%p))\n", dwParam, lp16Parms, lpParms);
571         if (lp16Parms == NULL) return MCIERR_INTERNAL;
572         while(mciDrv[wDevID].wType != 0) {
573                 if (++wDevID >= MAXMCIDRIVERS) {
574                         dprintf_mmsys(stddeb, "MCI_OPEN // MAXMCIDRIVERS reached !\n");
575                         return MCIERR_INTERNAL;
576                         }
577                 }
578         dprintf_mmsys(stddeb, "mciOpen // wDevID=%d \n", wDevID);
579         if (dwParam & MCI_OPEN_ALIAS) {
580                 dprintf_mmsys(stddeb, "MCI_OPEN // Alias='%s' !\n",
581                         (char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
582                 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
583                 }
584         if (dwParam & MCI_OPEN_TYPE) {
585                 if (dwParam & MCI_OPEN_TYPE_ID) {
586                         dprintf_mmsys(stddeb, "MCI_OPEN // Dev=%p !\n", lpParms->lpstrDeviceType);
587                         uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
588                         }
589                 else {
590                         if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
591                         dprintf_mmsys(stddeb, "MCI_OPEN // Dev='%s' !\n",
592                               (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
593                         strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
594                         AnsiUpper(str);
595                         if (strcmp(str, "CDAUDIO") == 0) {
596                                 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
597                                 }
598                         else
599                         if (strcmp(str, "WAVEAUDIO") == 0) {
600                                 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
601                                 }
602                         else
603                         if (strcmp(str, "SEQUENCER") == 0)      {
604                                 uDevTyp = MCI_DEVTYPE_SEQUENCER;
605                                 }
606                         else
607                         if (strcmp(str, "ANIMATION1") == 0) {
608                                 uDevTyp = MCI_DEVTYPE_ANIMATION;
609                                 }
610                         else
611                         if (strcmp(str, "AVIVIDEO") == 0) {
612                                 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
613                                 }
614                         }
615                 }
616         mciDrv[wDevID].wType = uDevTyp;
617         mciDrv[wDevID].wDeviceID = wDevID;
618         lpParms->wDeviceID = wDevID;
619         dprintf_mmsys(stddeb, "MCI_OPEN // mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n", 
620                                 wDevID, uDevTyp, lpParms->wDeviceID);
621         switch(uDevTyp) {
622                 case MCI_DEVTYPE_CD_AUDIO:
623 #ifdef WINELIB
624                         WINELIB_UNIMP ("CDAUDIO_DriverProc");
625 #else
626                         return CDAUDIO_DriverProc(0, 0, MCI_OPEN_DRIVER,
627                                                         dwParam, (DWORD)lp16Parms);
628 #endif
629                 case MCI_DEVTYPE_WAVEFORM_AUDIO:
630                         return WAVE_DriverProc(0, 0, MCI_OPEN_DRIVER, 
631                                                                 dwParam, (DWORD)lp16Parms);
632                 case MCI_DEVTYPE_SEQUENCER:
633                         return MIDI_DriverProc(0, 0, MCI_OPEN_DRIVER, 
634                                                                 dwParam, (DWORD)lp16Parms);
635                 case MCI_DEVTYPE_ANIMATION:
636                         return ANIM_DriverProc(0, 0, MCI_OPEN_DRIVER, 
637                                                                 dwParam, (DWORD)lp16Parms);
638                 case MCI_DEVTYPE_DIGITAL_VIDEO:
639                         dprintf_mmsys(stddeb, "MCI_OPEN // No DIGITAL_VIDEO yet !\n");
640                         return MCIERR_DEVICE_NOT_INSTALLED;
641                 default:
642                         dprintf_mmsys(stddeb, "MCI_OPEN // Invalid Device Name '%p' !\n", lpParms->lpstrDeviceType);
643                         return MCIERR_INVALID_DEVICE_NAME;
644                 }
645         return MCIERR_INTERNAL;
646 }
647
648
649 /**************************************************************************
650 *                               mciClose                                [internal]
651 */
652 DWORD mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
653 {
654         DWORD   dwRet = MCIERR_INTERNAL;
655         dprintf_mmsys(stddeb, "mciClose(%u, %08lX, %p)\n", wDevID, dwParam, lpParms);
656         switch(mciDrv[wDevID].wType) {
657                 case MCI_DEVTYPE_CD_AUDIO:
658 #ifndef WINELIB
659                         dwRet = CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
660                                                 MCI_CLOSE, dwParam, (DWORD)lpParms);
661 #endif
662                         break;
663                 case MCI_DEVTYPE_WAVEFORM_AUDIO:
664                         dwRet = WAVE_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
665                                                 MCI_CLOSE, dwParam, (DWORD)lpParms);
666                         break;
667                 case MCI_DEVTYPE_SEQUENCER:
668                         dwRet = MIDI_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
669                                                 MCI_CLOSE, dwParam, (DWORD)lpParms);
670                         break;
671                 case MCI_DEVTYPE_ANIMATION:
672                         dwRet = ANIM_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
673                                                 MCI_CLOSE, dwParam, (DWORD)lpParms);
674                         break;
675                 default:
676                         dprintf_mmsys(stddeb, "mciClose() // unknown device type=%04X !\n", mciDrv[wDevID].wType);
677                 }
678         mciDrv[wDevID].wType = 0;
679         return dwRet;
680 }
681
682
683 /**************************************************************************
684 *                               mciSound                                [internal]
685 */
686 DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS lpParms)
687 {
688         int     len;
689         LPSTR   ptr;
690         LPSTR   lpstrReturn;
691         DWORD   *lpdwRet;
692         LPSTR   SysFile = "SYSTEM.INI";
693         dprintf_mci(stddeb, "mciSysInfo(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
694         lpstrReturn = PTR_SEG_TO_LIN(lpParms->lpstrReturn);
695         switch(dwFlags) {
696                 case MCI_SYSINFO_QUANTITY:
697                         dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_QUANTITY \n");
698                         lpdwRet = (DWORD *)lpstrReturn;
699                         *(lpdwRet) = InstalledCount;            
700                         return 0;
701                 case MCI_SYSINFO_INSTALLNAME:
702                         dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_INSTALLNAME \n");
703                         if (lpInstallNames == NULL) {
704                                 InstalledCount = 0;
705                                 InstalledListLen = 0;
706                                 ptr = lpInstallNames = malloc(2048);
707                                 GetPrivateProfileString("mci", NULL, "", lpInstallNames, 2000, SysFile);
708                                 while(strlen(ptr) > 0) {
709                                         dprintf_mci(stddeb, "---> '%s' \n", ptr);
710                                         len = strlen(ptr) + 1;
711                                         ptr += len;
712                                         InstalledListLen += len;
713                                         InstalledCount++;
714                                         }
715                                 }
716                         if (lpParms->dwRetSize < InstalledListLen) {
717                                 strncpy(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 2);
718                                 lpstrReturn[lpParms->dwRetSize - 1] = '\0';
719                                 }
720                         else
721                                 strcpy(lpstrReturn, lpInstallNames);
722                         return 0;
723                 case MCI_SYSINFO_NAME:
724                         dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_NAME \n");
725                         return 0;
726                 case MCI_SYSINFO_OPEN:
727                         dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_OPEN \n");
728                         return 0;
729                 }
730         return MMSYSERR_INVALPARAM;
731 }
732
733 /**************************************************************************
734 *                               mciSound                                [internal]
735 */
736 DWORD mciSound(UINT wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
737 {
738         if (lpParms == NULL) return MCIERR_INTERNAL;
739         if (dwParam & MCI_SOUND_NAME)
740                 dprintf_mci(stddeb, "MCI_SOUND // file='%s' !\n", lpParms->lpstrSoundName);
741         return MCIERR_INVALID_DEVICE_ID;
742 }
743
744
745
746 /**************************************************************************
747 *                               mciSendCommand                  [MMSYSTEM.701]
748 */
749 DWORD mciSendCommand(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
750 {
751         HDRVR   hDrv = 0;
752         dprintf_mci(stddeb, "mciSendCommand(%04X, %04X, %08lX, %08lX)\n", 
753                                         wDevID, wMsg, dwParam1, dwParam2);
754         switch(wMsg) {
755                 case MCI_OPEN:
756                         return mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
757                 case MCI_CLOSE:
758                         return mciClose(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
759                 case MCI_SYSINFO:
760                         return mciSysInfo(dwParam1, (LPMCI_SYSINFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
761                 default:
762                         switch(mciDrv[wDevID].wType) {
763                                 case MCI_DEVTYPE_CD_AUDIO:
764 #ifndef WINELIB
765                                         return CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
766                                                                                         wMsg, dwParam1, dwParam2);
767 #endif
768                                         
769                                 case MCI_DEVTYPE_WAVEFORM_AUDIO:
770                                         return WAVE_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
771                                                                                         wMsg, dwParam1, dwParam2);
772                                 case MCI_DEVTYPE_SEQUENCER:
773                                         return MIDI_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
774                                                                                         wMsg, dwParam1, dwParam2);
775                                 case MCI_DEVTYPE_ANIMATION:
776                                         return ANIM_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
777                                                                                         wMsg, dwParam1, dwParam2);
778                                 default:
779                                         dprintf_mci(stddeb, "mciSendCommand() // unknown device type=%04X !\n", 
780                                                                                         mciDrv[wDevID].wType);
781                                 }
782                 }
783         return MMSYSERR_INVALPARAM;
784 }
785
786 /**************************************************************************
787 *                               mciGetDeviceID                  [MMSYSTEM.703]
788 */
789 UINT mciGetDeviceID (LPCSTR lpstrName)
790 {
791         char    str[128];
792         dprintf_mci(stddeb, "mciGetDeviceID(%s)\n", lpstrName);
793         if (lpstrName != NULL) {
794                 strcpy(str, lpstrName);
795                 AnsiUpper(str);
796                 if (strcmp(str, "ALL") == 0) return MCI_ALL_DEVICE_ID;
797                 }
798         return 0;
799 }
800
801 /* someone was just short of a crisis seeing me putting xxx lines of code
802  * in a single define. Well. What does the code hope for if not for the
803  * care of the optimizer? (Stolen by Terry Pratchett, ok ;)
804  */
805 #define _MCI_STR(s) do {\
806         int __l__;\
807         dprintf_mci(stddeb,"->returns \"%s\"",s);\
808         if (lpstrReturnString) {\
809                 __l__=strlen(s);\
810                 if(__l__>uReturnLength) {\
811                         strncpy(lpstrReturnString,s,uReturnLength-1);\
812                         lpstrReturnString[uReturnLength-1]='\0';\
813                 } else\
814                         strcpy(lpstrReturnString,s);\
815                 dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\
816         }\
817 } while(0)
818 /* calling DriverProc. We need to pass the struct as SEGMENTED POINTER. */
819 #define _MCI_CALL_DRIVER(cmd,params) {\
820         DWORD   xparams;\
821         xparams=MAKE_SEGPTR(&params);\
822         switch(uDevTyp) {\
823         case MCI_DEVTYPE_CD_AUDIO:\
824                 res=CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags, xparams);\
825                 break;\
826         case MCI_DEVTYPE_WAVEFORM_AUDIO:\
827                 res=WAVE_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
828                 break;\
829         case MCI_DEVTYPE_SEQUENCER:\
830                 res=MIDI_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
831                 break;\
832         case MCI_DEVTYPE_ANIMATION:\
833                 res=ANIM_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,xparams);\
834                 break;\
835         case MCI_DEVTYPE_DIGITAL_VIDEO:\
836                 dprintf_mci(stddeb,"_MCI_CALL_DRIVER //No DIGITAL_VIDEO yet !\n");\
837                 res=MCIERR_DEVICE_NOT_INSTALLED;\
838                 break;\
839         default:\
840                 dprintf_mci(stddeb,"_MCI_CALL_DRIVER //Invalid Device Name '%s' !\n",dev);\
841                 res=MCIERR_INVALID_DEVICE_NAME;\
842                 break;\
843         }\
844 }
845 /* yeah, I know this is BAD. but we have to do that for MCI_OPEN_PARMS 
846  * strings.
847  */
848 #define _MCI_STRDUP_TO_SEG(dest,source) {\
849         HANDLE  x;\
850         x=USER_HEAP_ALLOC(strlen(source));\
851         dest=(LPSTR)MAKELONG(x,USER_HeapSel);\
852         strcpy(PTR_SEG_TO_LIN(dest),source);\
853 }
854
855 /**************************************************************************
856 *                               mciSendString                   [MMSYSTEM.702]
857 */
858 /* Well, it's easy. The usercode sends a string with a command (and flags)
859  * expressed in words in it... We do our best to call approbiate drivers,
860  * and return a errorcode AND a readable string (if lpstrRS!=NULL)
861  * Info taken by watching cool134.exe and from Borland's mcistrwh.hlp
862  */
863 DWORD mciSendString (LPCSTR lpstrCommand, LPSTR lpstrReturnString, 
864         UINT uReturnLength, HWND hwndCallback)
865 {
866         char    *cmd,*dev,*args,**keywords;
867         WORD    uDevTyp,wDevID;
868         DWORD   dwFlags;
869         int     track,i,nrofkeywords,res,timef;
870
871         dprintf_mci(stdnimp,"mciSendString('%s', %p, %d, %X)\n", lpstrCommand, 
872                 lpstrReturnString, uReturnLength, hwndCallback
873         );
874         /* format is <command> <device> <optargs> */
875         cmd=strdup(lpstrCommand);
876         dev=strchr(cmd,' ');
877         if (dev==NULL) {
878                 free(cmd);
879                 return MCIERR_MISSING_DEVICE_NAME;
880         }
881         *dev++='\0';
882         args=strchr(dev,' ');
883         if (args!=NULL) *args++='\0';
884         AnsiUpper(dev);
885         AnsiUpper(cmd);
886         if (args!=NULL) {
887                 char    *s;
888                 AnsiUpper(args);
889                 i=1;/* nrofkeywords = nrofspaces+1 */
890                 s=args;
891                 while ((s=strchr(s,' '))!=NULL) i++,s++;
892                 keywords=(char**)malloc(sizeof(char*)*(i+2));
893                 nrofkeywords=i;
894                 s=args;i=0;
895                 while (s && i<nrofkeywords) {
896                         keywords[i++]=s;
897                         s=strchr(s,' ');
898                         if (s) *s++='\0';
899                 }
900                 keywords[i]=NULL;
901         } else {
902                 nrofkeywords=0;
903                 keywords=(char**)malloc(sizeof(char*));
904         }
905         dwFlags = 0; /* default flags */
906         i=0;
907         while (i<nrofkeywords) {
908                 if (!strcmp(keywords[i],"WAIT")) {
909                         dwFlags |= MCI_WAIT;
910                         i++;
911                         continue;
912                 }
913                 if (!strcmp(keywords[i],"NOTIFY")) {
914                         /* how should we callback?  I don't know. */
915                         /*dwFlags |= MCI_NOTIFY;*/
916                         i++;
917                         continue;
918                 }
919                 if (!strcmp(keywords[i],"TRACK")) {
920                         if (i+1<nrofkeywords) {
921                                 sscanf(keywords[i+1],"%d",&track);
922                                 dwFlags |= MCI_TRACK;
923                                 i++;
924                                 /*FALLTHROUGH*/
925                         }
926                         i++;
927                         continue;
928                 }
929                 i++;
930         }
931         if (!strcmp(cmd,"OPEN")) {
932                 char    *s;
933                 MCI_OPEN_PARMS  openParams;
934
935                 openParams.lpstrElementName = NULL;
936                 s=strchr(dev,'!');
937                 if (s!=NULL) {
938                         *s++='\0';
939                         _MCI_STRDUP_TO_SEG(openParams.lpstrElementName,s);
940                 }
941                 if (!strcmp(dev,"CDAUDIO")) {
942                         uDevTyp=MCI_DEVTYPE_CD_AUDIO;
943                 } else if (!strcmp(dev,"WAVEAUDIO")) {
944                         uDevTyp=MCI_DEVTYPE_WAVEFORM_AUDIO;
945                 } else if (!strcmp(dev,"SEQUENCER")) {
946                         uDevTyp=MCI_DEVTYPE_SEQUENCER;
947                 } else if (!strcmp(dev,"ANIMATION1")) {
948                         uDevTyp=MCI_DEVTYPE_ANIMATION;
949                 } else if (!strcmp(dev,"AVIVIDEO")) {
950                         uDevTyp=MCI_DEVTYPE_DIGITAL_VIDEO;
951                 } else {
952                         free(keywords);free(cmd);
953                         return MCIERR_INVALID_DEVICE_NAME;
954                 }
955                 wDevID=0;
956                 while(mciDrv[wDevID].wType) {
957                         if (++wDevID>=MAXMCIDRIVERS) {
958                                 dprintf_mci(stddeb, "MCI_OPEN // MAXMCIDRIVERS reached !\n");
959                                 free(keywords);free(cmd);
960                                 return MCIERR_INTERNAL;
961                         }
962                 }
963                 mciDrv[wDevID].wType            = uDevTyp;
964                 mciDrv[wDevID].wDeviceID        = wDevID;
965                 openParams.dwCallback           = 0;
966                 openParams.wDeviceID            = wDevID;
967                 /* all strings must be copied */
968                 _MCI_STRDUP_TO_SEG(openParams.lpstrDeviceType,dev);
969                 openParams.lpstrAlias           = NULL;
970                 dwFlags |= MCI_OPEN_TYPE;
971                 i=0;
972                 while (i<nrofkeywords) {
973                         if (!strcmp(keywords[i],"SHAREABLE")) {
974                                 dwFlags|=MCI_OPEN_SHAREABLE;
975                                 i++;
976                                 continue;
977                         }
978                         if (!strcmp(keywords[i],"ALIAS") && (i+1<nrofkeywords)) {
979                                 dwFlags|=MCI_OPEN_ALIAS;
980                                 _MCI_STRDUP_TO_SEG(openParams.lpstrAlias,keywords[i]);
981                                 i+=2;
982                                 continue;
983                         }
984                         if (!strcmp(keywords[i],"ELEMENT") && (i+1<nrofkeywords)) {
985                                 dwFlags|=MCI_OPEN_ELEMENT;
986                                 _MCI_STRDUP_TO_SEG(openParams.lpstrElementName,keywords[i]);
987                                 i+=2;
988                                 continue;
989                         }
990                         i++;
991                 }
992                 _MCI_CALL_DRIVER(MCI_OPEN,openParams);
993                 if (res==0)
994                         memcpy(&mciOpenDrv[wDevID],&openParams,sizeof(MCI_OPEN_PARMS));
995                 free(keywords);free(cmd);
996                 return res;
997         }
998         /* all other commands use the alias set in MCI_OPEN or (if not set) 
999          * the devicetype
1000          */
1001         wDevID=0;
1002         while(1) {
1003                 SEGPTR  dname;
1004                 dname=(SEGPTR)mciOpenDrv[wDevID].lpstrAlias;
1005                 if (dname==NULL) 
1006                         dname=(SEGPTR)mciOpenDrv[wDevID].lpstrDeviceType;
1007                 if (!strcasecmp(PTR_SEG_TO_LIN(dname),dev))
1008                         break;
1009                 if (++wDevID >= MAXMCIDRIVERS) {
1010                         dprintf_mci(stddeb, "mciSendString // MAXMCIDRIVERS reached !\n");
1011                         free(keywords);free(cmd);
1012                         return MCIERR_INTERNAL;
1013                 }
1014         }
1015         uDevTyp=mciDrv[wDevID].wType;
1016
1017         if (!strcmp(cmd,"STATUS")) {
1018                 MCI_STATUS_PARMS statusParams;
1019
1020                 if (args==NULL) {
1021                         free(keywords);free(cmd);
1022                         return MCIERR_MISSING_STRING_ARGUMENT;
1023                 }
1024                 statusParams.dwCallback = 0;
1025                 if (dwFlags & MCI_TRACK)
1026                         statusParams.dwTrack = track;
1027                 dwFlags |= MCI_STATUS_ITEM;
1028                 /* we need that later for printing... */
1029                 statusParams.dwItem = MCI_STATUS_TIME_FORMAT;
1030                 _MCI_CALL_DRIVER(MCI_STATUS,statusParams);
1031                 timef=statusParams.dwReturn;
1032                 statusParams.dwReturn=0;
1033                 statusParams.dwItem=0;
1034                 i=0;
1035                 while (i<nrofkeywords) {
1036                         if (    !strcmp(keywords[i],"CURRENT") &&
1037                                 (i+1<nrofkeywords) &&
1038                                 !strcmp(keywords[i+1],"TRACK")
1039                         ) {
1040                                 statusParams.dwItem=MCI_STATUS_CURRENT_TRACK;
1041                                 i+=2;
1042                                 continue;
1043                         }
1044                         if (    !strcmp(keywords[i],"TIME") &&
1045                                 (i+1<nrofkeywords) &&
1046                                 !strcmp(keywords[i+1],"FORMAT")
1047                         ) {
1048                                 statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
1049                                 i+=2;
1050                                 continue;
1051                         }
1052                         if (!strcmp(keywords[i],"READY")) {
1053                                 statusParams.dwItem=MCI_STATUS_READY;
1054                                 i++;
1055                                 continue;
1056                         }
1057                         if (!strcmp(keywords[i],"MODE")) {
1058                                 statusParams.dwItem=MCI_STATUS_MODE;
1059                                 i++;
1060                                 continue;
1061                         }
1062                         if (    !strcmp(keywords[i],"NUMBER") && 
1063                                 (i+2<nrofkeywords) &&
1064                                 !strcmp(keywords[i+1],"OF") &&
1065                                 !strcmp(keywords[i+2],"TRACKS")
1066                         ) {
1067                                 statusParams.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
1068                                 i+=3;
1069                                 continue;
1070                         }
1071                         if (!strcmp(keywords[i],"LENGTH")) {
1072                                 statusParams.dwItem = MCI_STATUS_LENGTH;
1073                                 i++;
1074                                 continue;
1075                         }
1076                         if (!strcmp(keywords[i],"POSITION")) {
1077                                 statusParams.dwItem = MCI_STATUS_POSITION;
1078                                 i++;
1079                                 continue;
1080                         }
1081                         if (    !strcmp(keywords[i],"MEDIA") && 
1082                                 (i+1<nrofkeywords) &&
1083                                 !strcmp(keywords[i+1],"PRESENT")
1084                         ) {
1085                                 statusParams.dwItem = MCI_STATUS_MEDIA_PRESENT;
1086                                 i+=2;
1087                                 continue;
1088                         }
1089                         i++;
1090                 }
1091                 _MCI_CALL_DRIVER(MCI_STATUS,statusParams);
1092                 if (res==0) {
1093                         switch (statusParams.dwItem) {
1094                         case MCI_STATUS_MODE:
1095                                 switch (statusParams.dwReturn) {
1096                                 case MCI_MODE_NOT_READY:_MCI_STR("not ready");break;
1097                                 case MCI_MODE_STOP:_MCI_STR("stopped");break;
1098                                 case MCI_MODE_PLAY:_MCI_STR("playing");break;
1099                                 case MCI_MODE_RECORD:_MCI_STR("recording");break;
1100                                 case MCI_MODE_SEEK:_MCI_STR("seeking");break;
1101                                 case MCI_MODE_PAUSE:_MCI_STR("paused");break;
1102                                 case MCI_MODE_OPEN:_MCI_STR("open");break;
1103                                 default:break;
1104                                 }
1105                                 break;
1106                         case MCI_STATUS_MEDIA_PRESENT:
1107                                 if (statusParams.dwReturn)
1108                                         _MCI_STR("true");
1109                                 else
1110                                         _MCI_STR("false");
1111                                 break;
1112                         case MCI_STATUS_NUMBER_OF_TRACKS:
1113                         case MCI_STATUS_CURRENT_TRACK:
1114                         {       char    buf[16];
1115                                 sprintf(buf,"%ld",statusParams.dwReturn);
1116                                 _MCI_STR(buf);
1117                                 break;
1118                         }
1119                         case MCI_STATUS_POSITION:
1120                         case MCI_STATUS_LENGTH:
1121                         {       char    buf[100];
1122                                 switch (timef) {
1123                                 case MCI_FORMAT_MILLISECONDS:
1124                                 case MCI_FORMAT_FRAMES:
1125                                 case MCI_FORMAT_BYTES:
1126                                 case MCI_FORMAT_SAMPLES:
1127                                         sprintf(buf,"%ld",statusParams.dwReturn);
1128                                         _MCI_STR(buf);
1129                                         break;
1130                                 case MCI_FORMAT_HMS:
1131                                         /* well, the macros have the same content*/
1132                                         /*FALLTRHOUGH*/
1133                                 case MCI_FORMAT_MSF:
1134                                         sprintf(buf,"%d:%d:%d",
1135                                                 MCI_HMS_HOUR(statusParams.dwReturn),
1136                                                 MCI_HMS_MINUTE(statusParams.dwReturn),
1137                                                 MCI_HMS_SECOND(statusParams.dwReturn)
1138                                         );
1139                                         _MCI_STR(buf);
1140                                         break;
1141                                 case MCI_FORMAT_TMSF:
1142                                         sprintf(buf,"%d:%d:%d:%d",
1143                                                 MCI_TMSF_TRACK(statusParams.dwReturn),
1144                                                 MCI_TMSF_MINUTE(statusParams.dwReturn),
1145                                                 MCI_TMSF_SECOND(statusParams.dwReturn),
1146                                                 MCI_TMSF_FRAME(statusParams.dwReturn)
1147                                         );
1148                                         _MCI_STR(buf);
1149                                         break;
1150                                 default:
1151                                         fprintf(stdnimp,"mciSendString:STATUS:missing timeformat for %d, report.\n",timef);
1152                                         break;
1153                                 }
1154                                 break;
1155                         }
1156                         case MCI_STATUS_TIME_FORMAT:
1157                                 switch (timef) {
1158                                 case MCI_FORMAT_MILLISECONDS:_MCI_STR("milliseconds");break;
1159                                 case MCI_FORMAT_FRAMES:_MCI_STR("frames");break;
1160                                 case MCI_FORMAT_BYTES:_MCI_STR("bytes");break;
1161                                 case MCI_FORMAT_SAMPLES:_MCI_STR("samples");break;
1162                                 case MCI_FORMAT_HMS:_MCI_STR("hms");break;
1163                                 case MCI_FORMAT_MSF:_MCI_STR("msf");break;
1164                                 case MCI_FORMAT_TMSF:_MCI_STR("tmsf");break;
1165                                 default:
1166                                         fprintf(stdnimp,"mciSendString:STATUS:missing timeformat for %d, report.\n",timef);
1167                                         break;
1168                                 }
1169                                 break;
1170                         default:
1171                                 fprintf(stdnimp,"mciSendString:STATUS:missing result for %ld, report.\n",statusParams.dwItem);
1172                                 break;
1173                         }
1174                 }
1175                 free(keywords);free(cmd);
1176                 return res;
1177         }
1178         if (!strcmp(cmd,"SET")) {
1179                 MCI_SET_PARMS   setParams;
1180
1181                 if (args==NULL) {
1182                         free(keywords);free(cmd);
1183                         return MCIERR_MISSING_STRING_ARGUMENT;
1184                 }
1185                 setParams.dwCallback = 0;
1186                 i=0;
1187                 while (i<nrofkeywords) {
1188                         if (!strcmp(keywords[i],"DOOR") && i+1<nrofkeywords) {
1189                                 if (!strcmp(keywords[i+1],"OPEN"))
1190                                         dwFlags |= MCI_SET_DOOR_OPEN;
1191                                 if (!strcmp(keywords[i+1],"CLOSED"))
1192                                         dwFlags |= MCI_SET_DOOR_CLOSED;
1193                                 i+=2;
1194                                 continue;
1195                         }
1196                         if (    !strcmp(keywords[i],"TIME") && 
1197                                 (i+2<nrofkeywords) &&
1198                                 !strcmp(keywords[i+1],"FORMAT")
1199                         ) {
1200                                 dwFlags |= MCI_SET_TIME_FORMAT;
1201                                 if (!strcmp(keywords[i+2],"MS"))
1202                                         setParams.dwTimeFormat = MCI_FORMAT_MSF;
1203                                 if (!strcmp(keywords[i+2],"MILLISECONDS"))
1204                                         setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
1205                                 if (!strcmp(keywords[i+2],"MSF"))
1206                                         setParams.dwTimeFormat = MCI_FORMAT_MSF;
1207                                 if (!strcmp(keywords[i+2],"HMS")) /* untested */
1208                                         setParams.dwTimeFormat = MCI_FORMAT_HMS;
1209                                 if (!strcmp(keywords[i+2],"FRAMES")) /* untested */
1210                                         setParams.dwTimeFormat = MCI_FORMAT_FRAMES;
1211                                 if (!strcmp(keywords[i+2],"BYTES")) /* untested */
1212                                         setParams.dwTimeFormat = MCI_FORMAT_BYTES;
1213                                 if (!strcmp(keywords[i+2],"SAMPLES")) /* untested */
1214                                         setParams.dwTimeFormat = MCI_FORMAT_SAMPLES;
1215                                 if (!strcmp(keywords[i+2],"TMSF")) /* untested */
1216                                         setParams.dwTimeFormat = MCI_FORMAT_TMSF;
1217                                 if (!strcmp(keywords[i+2],"SMPTE") && (i+3<nrofkeywords)) {
1218                                         /* all untested */
1219                                         if (!strcmp(keywords[i+3],"24"))
1220                                                 setParams.dwTimeFormat = MCI_FORMAT_SMPTE_24;
1221                                         if (!strcmp(keywords[i+3],"25"))
1222                                                 setParams.dwTimeFormat = MCI_FORMAT_SMPTE_25;
1223                                         if (!strcmp(keywords[i+3],"30"))
1224                                                 setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30;
1225                                         if (!strcmp(keywords[i+3],"30DROP"))
1226                                                 setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30DROP;
1227                                         i++;
1228                                         /*FALLTHROUGH*/
1229                                 }
1230                                 i+=3;
1231                                 continue;
1232                         }
1233                         if (!strcmp(args,"AUDIO") && (i+1<nrofkeywords)) {
1234                                 dwFlags |= MCI_SET_AUDIO;
1235                                 /* I'm not sure if those belong to the flags...
1236                                  * they could belong to setParams.dwAudio
1237                                  */
1238                                 if (!strcmp(args,"ALL"))
1239                                         dwFlags |= MCI_SET_AUDIO_ALL;
1240                                 if (!strcmp(args,"LEFT"))
1241                                         dwFlags |= MCI_SET_AUDIO_LEFT;
1242                                 if (!strcmp(args,"RIGHT"))
1243                                         dwFlags |= MCI_SET_AUDIO_RIGHT;
1244                                 i++;
1245                                 continue;
1246                         }
1247                         if (!strcmp(args,"VIDEO")) {
1248                                 /* how to handle those? */
1249                                 i++;
1250                                 continue;
1251                         }
1252                         if (!strcmp(args,"ON")) {
1253                                 dwFlags |= MCI_SET_ON;
1254                                 i++;
1255                                 continue;
1256                         }
1257                         if (!strcmp(args,"OFF")) {
1258                                 dwFlags |= MCI_SET_ON;
1259                                 i++;
1260                                 continue;
1261                         }
1262                         i++;
1263                 }
1264                 _MCI_CALL_DRIVER(MCI_SET,setParams);
1265                 if (res==0) { /* does set return data? */ }
1266                 free(keywords);free(cmd);
1267                 return res;
1268         }
1269         if (!strcmp(cmd,"CAPABILITY")) {
1270                 MCI_GETDEVCAPS_PARMS    gdcParams;
1271
1272                 gdcParams.dwCallback = 0;
1273                 if (args==NULL) {
1274                         free(keywords);free(cmd);
1275                         return MCIERR_MISSING_STRING_ARGUMENT;
1276                 }
1277                 dwFlags |= MCI_GETDEVCAPS_ITEM;
1278                 gdcParams.dwItem = 0;
1279                 i=0;
1280                 while (i<nrofkeywords) {
1281                         if (    !strcmp(keywords[i],"DEVICE") && 
1282                                 (i+1<nrofkeywords) &&
1283                                 !strcmp(keywords[i+1],"TYPE")
1284                         ) {
1285                                 gdcParams.dwItem = MCI_GETDEVCAPS_DEVICE_TYPE;  
1286                                 i+=2;
1287                                 continue;
1288                         }
1289                         if (    !strcmp(keywords[i],"HAS") &&
1290                                 (i+1<nrofkeywords) &&
1291                                 !strcmp(keywords[i+1],"AUDIO")
1292                         ) {
1293                                 gdcParams.dwItem = MCI_GETDEVCAPS_HAS_AUDIO;    
1294                                 i+=2;
1295                                 continue;
1296                         }
1297                         if (    !strcmp(keywords[i],"HAS") &&
1298                                 (i+1<nrofkeywords) &&
1299                                 !strcmp(keywords[i+1],"VIDEO")
1300                         ) {
1301                                 gdcParams.dwItem = MCI_GETDEVCAPS_HAS_VIDEO;    
1302                                 i+=2;
1303                                 continue;
1304                         }
1305                         if (    !strcmp(keywords[i],"USES") &&
1306                                 (i+1<nrofkeywords) &&
1307                                 !strcmp(keywords[i+1],"FILES")
1308                         ) {
1309                                 gdcParams.dwItem = MCI_GETDEVCAPS_HAS_VIDEO;    
1310                                 i+=2;
1311                                 continue;
1312                         }
1313                         if (    !strcmp(keywords[i],"COMPOUND") &&
1314                                 (i+1<nrofkeywords) &&
1315                                 !strcmp(keywords[i+1],"DEVICE")
1316                         ) {
1317                                 gdcParams.dwItem = MCI_GETDEVCAPS_COMPOUND_DEVICE;      
1318                                 i+=2;
1319                                 continue;
1320                         }
1321                         if (!strcmp(keywords[i],"CAN") && (i+1<nrofkeywords)) {
1322                                 if (!strcmp(keywords[i+1],"RECORD"))
1323                                         gdcParams.dwItem = MCI_GETDEVCAPS_CAN_RECORD;   
1324                                 if (!strcmp(keywords[i+1],"PLAY"))
1325                                         gdcParams.dwItem = MCI_GETDEVCAPS_CAN_PLAY;     
1326                                 if (!strcmp(keywords[i+1],"EJECT"))
1327                                         gdcParams.dwItem = MCI_GETDEVCAPS_CAN_EJECT;    
1328                                 if (!strcmp(keywords[i+1],"SAVE"))
1329                                         gdcParams.dwItem = MCI_GETDEVCAPS_CAN_SAVE;     
1330                                 i+=2;
1331                                 continue;
1332                         }
1333                         i++;
1334                 }
1335                 res=-1;
1336                 _MCI_CALL_DRIVER(MCI_GETDEVCAPS,gdcParams);
1337                 fprintf(stderr,"GETDEVCAPS returned res=%d\n",res);
1338                 if (res==0) {
1339                         switch (gdcParams.dwItem) {
1340                         case MCI_GETDEVCAPS_DEVICE_TYPE:
1341                                 switch (gdcParams.dwReturn) {
1342                                 case MCI_DEVTYPE_VCR:_MCI_STR("vcr");break;
1343                                 case MCI_DEVTYPE_VIDEODISC:_MCI_STR("videodisc");break;
1344                                 case MCI_DEVTYPE_CD_AUDIO:_MCI_STR("cd audio");break;
1345                                 case MCI_DEVTYPE_OVERLAY:_MCI_STR("overlay");break;
1346                                 case MCI_DEVTYPE_DAT:_MCI_STR("dat");break;
1347                                 case MCI_DEVTYPE_SCANNER:_MCI_STR("scanner");break;
1348                                 case MCI_DEVTYPE_ANIMATION:_MCI_STR("animation");break;
1349                                 case MCI_DEVTYPE_DIGITAL_VIDEO:_MCI_STR("digital video");break;
1350                                 case MCI_DEVTYPE_OTHER:_MCI_STR("other");break;
1351                                 case MCI_DEVTYPE_WAVEFORM_AUDIO:_MCI_STR("waveform audio");break;
1352                                 case MCI_DEVTYPE_SEQUENCER:_MCI_STR("sequencer");break;
1353                                 default:fprintf(stdnimp,"mciSendString:GETCAPS_DEVTYPE:unknown type %ld, report.\n",gdcParams.dwReturn);break;
1354                                 }
1355                                 break;
1356                         case MCI_GETDEVCAPS_CAN_PLAY:
1357                         case MCI_GETDEVCAPS_CAN_EJECT:
1358                         case MCI_GETDEVCAPS_CAN_RECORD:
1359                         case MCI_GETDEVCAPS_CAN_SAVE:
1360                         case MCI_GETDEVCAPS_HAS_AUDIO:
1361                         case MCI_GETDEVCAPS_HAS_VIDEO:
1362                         case MCI_GETDEVCAPS_COMPOUND_DEVICE:
1363                         case MCI_GETDEVCAPS_USES_FILES:
1364                                 /* well, is this right? no example here */
1365                                 if (gdcParams.dwReturn)
1366                                         _MCI_STR("true");
1367                                 else
1368                                         _MCI_STR("false");
1369                                 break;
1370                         default:fprintf(stdnimp,"mciSendString:GETDEVCAPS:unknown type %ld, report.\n",gdcParams.dwItem);break;
1371                         }
1372                 }
1373                 free(keywords);free(cmd);
1374                 return res;
1375         }
1376         if (!strcmp(cmd,"PAUSE")) {
1377                 MCI_GENERIC_PARMS       genParams;
1378                 genParams.dwCallback=0;
1379                 _MCI_CALL_DRIVER(MCI_PAUSE,genParams);
1380                 free(keywords);free(cmd);
1381                 return res;
1382         }
1383         if (!strcmp(cmd,"PLAY")) {
1384                 int     nrargs,j,k,a[4];
1385                 char    *parsestr;
1386                 MCI_PLAY_PARMS          playParams;
1387                 MCI_STATUS_PARMS        statusParams;
1388
1389                 statusParams.dwCallback=0;
1390                 statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
1391                 dwFlags |= MCI_STATUS_ITEM;
1392                 _MCI_CALL_DRIVER(MCI_STATUS,statusParams);
1393                 dwFlags &= ~MCI_STATUS_ITEM;
1394                 timef=statusParams.dwReturn;
1395                 switch (timef) {
1396                 case MCI_FORMAT_MILLISECONDS:
1397                 case MCI_FORMAT_FRAMES:
1398                 case MCI_FORMAT_BYTES:
1399                 case MCI_FORMAT_SAMPLES:
1400                         nrargs=1;
1401                         parsestr="%d";
1402                         break;
1403                 case MCI_FORMAT_HMS:
1404                 case MCI_FORMAT_MSF:
1405                         parsestr="%d:%d:%d";
1406                         nrargs=3;
1407                         break;
1408                 case MCI_FORMAT_TMSF:
1409                         parsestr="%d:%d:%d:%d";
1410                         nrargs=4;
1411                         break;
1412                 default:fprintf(stdnimp,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef);
1413                         parsestr="%d";
1414                         nrargs=1;
1415                         break;
1416                 }
1417                 playParams.dwCallback=0;
1418                 i=0;
1419                 while (i<nrofkeywords) {
1420                         if (    !strcmp(keywords[i],"TO") &&
1421                                 (i+1<nrofkeywords)
1422                         ) {
1423                                 dwFlags |= MCI_TO;
1424                                 a[0]=a[1]=a[2]=a[3]=0;
1425                                 j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
1426                                 /* add up all integers we got, if we have more 
1427                                  * shift them. (Well I should use the macros in 
1428                                  * mmsystem.h, right).
1429                                  */
1430                                 playParams.dwTo=0;
1431                                 for (k=0;k<j;k++)
1432                                         playParams.dwTo+=a[k]<<(8*(nrargs-k));
1433                                 i+=2;
1434                                 continue;
1435                         }
1436                         if (    !strcmp(keywords[i],"FROM") &&
1437                                 (i+1<nrofkeywords)
1438                         ) {
1439                                 dwFlags |= MCI_FROM;
1440                                 a[0]=a[1]=a[2]=a[3]=0;
1441                                 j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
1442                                 /* dito. */
1443                                 playParams.dwFrom=0;
1444                                 for (k=0;k<j;k++)
1445                                         playParams.dwFrom+=a[k]<<(8*(nrargs-k));
1446                                 i+=2;
1447                                 continue;
1448                         }
1449                         i++;
1450                 }
1451                 _MCI_CALL_DRIVER(MCI_PLAY,playParams);
1452                 free(keywords);free(cmd);
1453                 return res;
1454         }
1455         if (!strcmp(cmd,"STOP")) {
1456                 MCI_GENERIC_PARMS       genParams;
1457                 genParams.dwCallback=0;
1458                 _MCI_CALL_DRIVER(MCI_STOP,genParams);
1459                 free(keywords);free(cmd);
1460                 return res;
1461         }
1462         if (!strcmp(cmd,"SEEK")) {
1463                 int     nrargs,j,k,a[4];
1464                 char    *parsestr;
1465                 MCI_STATUS_PARMS        statusParams;
1466                 MCI_SEEK_PARMS  seekParams;
1467
1468                 statusParams.dwCallback=0;
1469                 statusParams.dwItem=MCI_STATUS_TIME_FORMAT;
1470                 dwFlags |= MCI_STATUS_ITEM;
1471                 _MCI_CALL_DRIVER(MCI_STATUS,statusParams);
1472                 dwFlags &= ~MCI_STATUS_ITEM;
1473                 timef=statusParams.dwReturn;
1474                 switch (timef) {
1475                 case MCI_FORMAT_MILLISECONDS:
1476                 case MCI_FORMAT_FRAMES:
1477                 case MCI_FORMAT_BYTES:
1478                 case MCI_FORMAT_SAMPLES:
1479                         nrargs=1;
1480                         parsestr="%d";
1481                         break;
1482                 case MCI_FORMAT_HMS:
1483                 case MCI_FORMAT_MSF:
1484                         parsestr="%d:%d:%d";
1485                         nrargs=3;
1486                         break;
1487                 case MCI_FORMAT_TMSF:
1488                         parsestr="%d:%d:%d:%d";
1489                         nrargs=4;
1490                         break;
1491                 default:fprintf(stdnimp,"mciSendString:SEEK:unknown timeformat %d, please report.\n",timef);
1492                         parsestr="%d";
1493                         nrargs=1;
1494                         break;
1495                 }
1496                 seekParams.dwCallback=0;
1497                 i=0;
1498                 while (i<nrofkeywords) {
1499                         if (    !strcmp(keywords[i],"TO") &&
1500                                 (i+1<nrofkeywords)
1501                         ) {
1502                                 if (!strcmp(keywords[i+1],"START")) {
1503                                         dwFlags=MCI_SEEK_TO_START;
1504                                         seekParams.dwTo=0;
1505                                         i+=2;
1506                                         continue;
1507                                 }
1508                                 if (!strcmp(keywords[i+1],"END")) {
1509                                         dwFlags=MCI_SEEK_TO_END;
1510                                         seekParams.dwTo=0;
1511                                         i+=2;
1512                                         continue;
1513                                 }
1514                                 dwFlags=MCI_TO;
1515                                 i+=2;
1516                                 a[0]=a[1]=a[2]=a[3]=0;
1517                                 j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
1518                                 seekParams.dwTo=0;
1519                                 for (k=0;k<j;k++)
1520                                         seekParams.dwTo+=a[k]<<(8*(nrargs-k));
1521                                 continue;
1522                         }
1523                         i++;
1524                 }
1525                 _MCI_CALL_DRIVER(MCI_SEEK,seekParams);
1526                 free(keywords);free(cmd);
1527                 return res;
1528         }
1529         if (!strcmp(cmd,"CLOSE")) {
1530                 MCI_GENERIC_PARMS       closeParams;
1531
1532                 closeParams.dwCallback=0;
1533                 _MCI_CALL_DRIVER(MCI_CLOSE,closeParams);
1534                 free(keywords);free(cmd);
1535                 return res;
1536         }
1537         if (!strcmp(cmd,"INFO")) {
1538                 MCI_INFO_PARMS  infoParams;
1539
1540                 dwFlags=-1;
1541                 while (i<nrofkeywords) {
1542                         if (!strcmp(keywords[i],"PRODUCT")) {
1543                                 dwFlags=MCI_INFO_PRODUCT;
1544                                 i++;
1545                                 continue;
1546                         }
1547                         if (!strcmp(keywords[i],"FILE")) {
1548                                 dwFlags=MCI_INFO_FILE;
1549                                 i++;
1550                                 continue;
1551                         }
1552                         i++;
1553                 }
1554                 if (dwFlags==-1) {
1555                         free(keywords);free(cmd);
1556                         return MCIERR_MISSING_STRING_ARGUMENT;
1557                 }
1558                 _MCI_CALL_DRIVER(MCI_INFO,infoParams);
1559                 if (res==0) {
1560                         _MCI_STR(infoParams.lpstrReturn);
1561                 }
1562                 free(cmd);free(keywords);
1563                 return res;
1564         }
1565         fprintf(stdnimp, "mciSendString('%s', %p, %u, %X) // unimplemented, please report.\n", lpstrCommand, 
1566                 lpstrReturnString, uReturnLength, hwndCallback
1567         );
1568         free(keywords);free(cmd);
1569         return MCIERR_MISSING_COMMAND_STRING;
1570 }
1571
1572 /**************************************************************************
1573 *                               mciSetYieldProc         [MMSYSTEM.714]
1574 */
1575 BOOL mciSetYieldProc (UINT uDeviceID, 
1576                 YIELDPROC fpYieldProc, DWORD dwYieldData)
1577 {
1578     return FALSE;
1579 }
1580
1581 /**************************************************************************
1582 *                               mciGetDeviceIDFromElementID     [MMSYSTEM.715]
1583 */
1584 UINT mciGetDeviceIDFromElementID(DWORD dwElementID, LPCSTR lpstrType)
1585 {
1586     return 0;
1587 }
1588
1589 /**************************************************************************
1590 *                               mciGetYieldProc         [MMSYSTEM.716]
1591 */
1592 YIELDPROC mciGetYieldProc(UINT uDeviceID, DWORD FAR* lpdwYieldData)
1593 {
1594     return NULL;
1595 }
1596
1597 /**************************************************************************
1598 *                               mciGetCreatorTask       [MMSYSTEM.717]
1599 */
1600 HTASK mciGetCreatorTask(UINT uDeviceID)
1601 {
1602     return 0;
1603 }
1604
1605 /**************************************************************************
1606 *                               midiOutGetNumDevs       [MMSYSTEM.201]
1607 */
1608 UINT midiOutGetNumDevs(void)
1609 {
1610         UINT    count = 0;
1611         dprintf_mmsys(stddeb, "midiOutGetNumDevs\n");
1612         count += modMessage(0, MODM_GETNUMDEVS, 0L, 0L, 0L);
1613         dprintf_mmsys(stddeb, "midiOutGetNumDevs return %u \n", count);
1614         return count;
1615 }
1616
1617 /**************************************************************************
1618 *                               midiOutGetDevCaps       [MMSYSTEM.202]
1619 */
1620 UINT midiOutGetDevCaps(UINT uDeviceID, MIDIOUTCAPS FAR* lpCaps, UINT uSize)
1621 {
1622         dprintf_mmsys(stddeb, "midiOutGetDevCaps\n");
1623         return 0;
1624 }
1625
1626 /**************************************************************************
1627 *                               midiOutGetErrorText     [MMSYSTEM.203]
1628 */
1629 UINT midiOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
1630 {
1631         dprintf_mmsys(stddeb, "midiOutGetErrorText\n");
1632         return midiGetErrorText(uError, lpText, uSize);
1633 }
1634
1635
1636 /**************************************************************************
1637 *                               midiGetErrorText                [internal]
1638 */
1639 UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
1640 {
1641         LPSTR   msgptr;
1642         int             maxbuf;
1643         if ((lpText == NULL) || (uSize < 1)) return(FALSE);
1644         lpText[0] = '\0';
1645         switch(uError) {
1646                 case MIDIERR_UNPREPARED:
1647                         msgptr = "The MIDI header was not prepared. Use the Prepare function to prepare the header, and then try again.";
1648                         break;
1649                 case MIDIERR_STILLPLAYING:
1650                         msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
1651                         break;
1652                 case MIDIERR_NOMAP:
1653                         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.";
1654                         break;
1655                 case MIDIERR_NOTREADY:
1656                         msgptr = "The port is transmitting data to the device. Wait until the data has been transmitted, and then try again.";
1657                         break;
1658                 case MIDIERR_NODEVICE:
1659                         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.";
1660                         break;
1661                 case MIDIERR_INVALIDSETUP:
1662                         msgptr = "The current MIDI setup is damaged. Copy the original MIDIMAP.CFG file to the Windows SYSTEM directory, and then try again.";
1663                         break;
1664 /*
1665 msg# 336 : Cannot use the song-pointer time format and the SMPTE time-format together.
1666 msg# 337 : The specified MIDI device is already in use. Wait until it is free, and then try again.
1667 msg# 338 : The specified MIDI device is not installed on the system. Use the Drivers option in Control Panel to install the driver.
1668 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.
1669 msg# 340 : An error occurred using the specified port.
1670 msg# 341 : All multimedia timers are being used by other applications. Quit one of these applications, and then try again.
1671 msg# 342 : There is no current MIDI port.
1672 msg# 343 : There are no MIDI devices installed on the system. Use the Drivers option in Control Panel to install the driver.
1673 */
1674                 default:
1675                         msgptr = "Unknown MIDI Error !\n";
1676                         break;
1677                 }
1678         maxbuf = min(uSize - 1, strlen(msgptr));
1679         if (maxbuf > 0) strncpy(lpText, msgptr, maxbuf);
1680         lpText[maxbuf + 1] = '\0';
1681         return(TRUE);
1682 }
1683
1684 /**************************************************************************
1685 *                               midiOutOpen                     [MMSYSTEM.204]
1686 */
1687 UINT midiOutOpen(HMIDIOUT FAR* lphMidiOut, UINT uDeviceID,
1688     DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
1689 {
1690         HMIDI   hMidiOut;
1691         LPMIDIOPENDESC  lpDesc;
1692         LPMIDIOPENDESC  lp16Desc;
1693         DWORD   dwRet = 0;
1694         BOOL    bMapperFlg = FALSE;
1695         if (lphMidiOut != NULL) *lphMidiOut = 0;
1696         dprintf_mmsys(stddeb, "midiOutOpen(%p, %d, %08lX, %08lX, %08lX);\n", 
1697                 lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
1698         if (uDeviceID == (UINT)MIDI_MAPPER) {
1699                 dprintf_mmsys(stddeb, "midiOutOpen      // MIDI_MAPPER mode requested !\n");
1700                 bMapperFlg = TRUE;
1701                 uDeviceID = 0;
1702                 }
1703         hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
1704         if (lphMidiOut != NULL) *lphMidiOut = hMidiOut;
1705         lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiOut);
1706         lpDesc = (LPMIDIOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
1707         if (lpDesc == NULL) return MMSYSERR_NOMEM;
1708         lpDesc->hMidi = hMidiOut;
1709         lpDesc->dwCallback = dwCallback;
1710         lpDesc->dwInstance = dwInstance;
1711         while(uDeviceID < MAXMIDIDRIVERS) {
1712                 dwRet = modMessage(uDeviceID, MODM_OPEN, 
1713                         lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
1714                 if (dwRet == MMSYSERR_NOERROR) break;
1715                 if (!bMapperFlg) break;
1716                 uDeviceID++;
1717                 dprintf_mmsys(stddeb, "midiOutOpen      // MIDI_MAPPER mode ! try next driver...\n");
1718                 }
1719         return dwRet;
1720 }
1721
1722 /**************************************************************************
1723 *                               midiOutClose            [MMSYSTEM.205]
1724 */
1725 UINT midiOutClose(HMIDIOUT hMidiOut)
1726 {
1727         LPMIDIOPENDESC  lpDesc;
1728         dprintf_mmsys(stddeb, "midiOutClose(%04X)\n", hMidiOut);
1729         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1730         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1731         return modMessage(0, MODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
1732 }
1733
1734 /**************************************************************************
1735 *                               midiOutPrepareHeader    [MMSYSTEM.206]
1736 */
1737 UINT midiOutPrepareHeader(HMIDIOUT hMidiOut,
1738     MIDIHDR FAR* lpMidiOutHdr, UINT uSize)
1739 {
1740         LPMIDIOPENDESC  lpDesc;
1741         dprintf_mmsys(stddeb, "midiOutPrepareHeader(%04X, %p, %d)\n", 
1742                                         hMidiOut, lpMidiOutHdr, uSize);
1743         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1744         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1745         return modMessage(0, MODM_PREPARE, lpDesc->dwInstance, 
1746                                                 (DWORD)lpMidiOutHdr, (DWORD)uSize);
1747 }
1748
1749 /**************************************************************************
1750 *                               midiOutUnprepareHeader  [MMSYSTEM.207]
1751 */
1752 UINT midiOutUnprepareHeader(HMIDIOUT hMidiOut,
1753     MIDIHDR FAR* lpMidiOutHdr, UINT uSize)
1754 {
1755         LPMIDIOPENDESC  lpDesc;
1756         dprintf_mmsys(stddeb, "midiOutUnprepareHeader(%04X, %p, %d)\n", 
1757                                         hMidiOut, lpMidiOutHdr, uSize);
1758         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1759         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1760         return modMessage(0, MODM_UNPREPARE, lpDesc->dwInstance, 
1761                                                 (DWORD)lpMidiOutHdr, (DWORD)uSize);
1762 }
1763
1764 /**************************************************************************
1765 *                               midiOutShortMsg         [MMSYSTEM.208]
1766 */
1767 UINT midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
1768 {
1769         LPMIDIOPENDESC  lpDesc;
1770         dprintf_mmsys(stddeb, "midiOutShortMsg(%04X, %08lX)\n", hMidiOut, dwMsg);
1771         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1772         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1773         return modMessage(0, MODM_DATA, lpDesc->dwInstance, dwMsg, 0L);
1774 }
1775
1776 /**************************************************************************
1777 *                               midiOutLongMsg          [MMSYSTEM.209]
1778 */
1779 UINT midiOutLongMsg(HMIDIOUT hMidiOut,
1780     MIDIHDR FAR* lpMidiOutHdr, UINT uSize)
1781 {
1782         LPMIDIOPENDESC  lpDesc;
1783         dprintf_mmsys(stddeb, "midiOutLongMsg(%04X, %p, %d)\n", 
1784                                 hMidiOut, lpMidiOutHdr, uSize);
1785         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1786         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1787         return modMessage(0, MODM_LONGDATA, lpDesc->dwInstance, 
1788                                                 (DWORD)lpMidiOutHdr, (DWORD)uSize);
1789 }
1790
1791 /**************************************************************************
1792 *                               midiOutReset            [MMSYSTEM.210]
1793 */
1794 UINT midiOutReset(HMIDIOUT hMidiOut)
1795 {
1796         LPMIDIOPENDESC  lpDesc;
1797         dprintf_mmsys(stddeb, "midiOutReset(%04X)\n", hMidiOut);
1798         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1799         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1800         return modMessage(0, MODM_RESET, lpDesc->dwInstance, 0L, 0L);
1801 }
1802
1803 /**************************************************************************
1804 *                               midiOutGetVolume        [MMSYSTEM.211]
1805 */
1806 UINT midiOutGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume)
1807 {
1808         dprintf_mmsys(stddeb, "midiOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
1809         return modMessage(uDeviceID, MODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
1810         return 0;
1811 }
1812
1813 /**************************************************************************
1814 *                               midiOutSetVolume        [MMSYSTEM.212]
1815 */
1816 UINT midiOutSetVolume(UINT uDeviceID, DWORD dwVolume)
1817 {
1818         dprintf_mmsys(stddeb, "midiOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
1819         return modMessage(uDeviceID, MODM_SETVOLUME, 0L, dwVolume, 0L);
1820         return 0;
1821 }
1822
1823 /**************************************************************************
1824 *                               midiOutCachePatches             [MMSYSTEM.213]
1825 */
1826 UINT midiOutCachePatches(HMIDIOUT hMidiOut,
1827     UINT uBank, WORD FAR* lpwPatchArray, UINT uFlags)
1828 {
1829         dprintf_mmsys(stddeb, "midiOutCachePatches\n");
1830         return 0;
1831 }
1832
1833 /**************************************************************************
1834 *                               midiOutCacheDrumPatches [MMSYSTEM.214]
1835 */
1836 UINT midiOutCacheDrumPatches(HMIDIOUT hMidiOut,
1837     UINT uPatch, WORD FAR* lpwKeyArray, UINT uFlags)
1838 {
1839         dprintf_mmsys(stddeb, "midiOutCacheDrumPatches\n");
1840         return 0;
1841 }
1842
1843 /**************************************************************************
1844 *                               midiOutGetID            [MMSYSTEM.215]
1845 */
1846 UINT midiOutGetID(HMIDIOUT hMidiOut, UINT FAR* lpuDeviceID)
1847 {
1848         dprintf_mmsys(stddeb, "midiOutGetID\n");
1849         return 0;
1850 }
1851
1852 /**************************************************************************
1853 *                               midiOutMessage          [MMSYSTEM.216]
1854 */
1855 DWORD midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage, 
1856                                                 DWORD dwParam1, DWORD dwParam2)
1857 {
1858         LPMIDIOPENDESC  lpDesc;
1859         dprintf_mmsys(stddeb, "midiOutMessage(%04X, %04X, %08lX, %08lX)\n", 
1860                         hMidiOut, uMessage, dwParam1, dwParam2);
1861         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1862         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1863         return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
1864         return 0;
1865 }
1866
1867 /**************************************************************************
1868 *                               midiInGetNumDevs        [MMSYSTEM.301]
1869 */
1870 UINT midiInGetNumDevs(void)
1871 {
1872         UINT    count = 0;
1873         dprintf_mmsys(stddeb, "midiInGetNumDevs\n");
1874         count += midMessage(0, MIDM_GETNUMDEVS, 0L, 0L, 0L);
1875         dprintf_mmsys(stddeb, "midiInGetNumDevs return %u \n", count);
1876         return count;
1877 }
1878
1879 /**************************************************************************
1880 *                               midiInGetDevCaps        [MMSYSTEM.302]
1881 */
1882 UINT midiInGetDevCaps(UINT uDeviceID,
1883     LPMIDIINCAPS lpCaps, UINT uSize)
1884 {
1885         dprintf_mmsys(stddeb, "midiInGetDevCaps\n");
1886         return 0;
1887 }
1888
1889 /**************************************************************************
1890 *                               midiInGetErrorText              [MMSYSTEM.303]
1891 */
1892 UINT midiInGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
1893 {
1894         dprintf_mmsys(stddeb, "midiInGetErrorText\n");
1895         return (midiGetErrorText(uError, lpText, uSize));
1896 }
1897
1898 /**************************************************************************
1899 *                               midiInOpen              [MMSYSTEM.304]
1900 */
1901 UINT midiInOpen(HMIDIIN FAR* lphMidiIn, UINT uDeviceID,
1902     DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
1903 {
1904         HMIDI   hMidiIn;
1905         LPMIDIOPENDESC  lpDesc;
1906         LPMIDIOPENDESC  lp16Desc;
1907         DWORD   dwRet = 0;
1908         BOOL    bMapperFlg = FALSE;
1909         if (lphMidiIn != NULL) *lphMidiIn = 0;
1910         dprintf_mmsys(stddeb, "midiInOpen(%p, %d, %08lX, %08lX, %08lX);\n", 
1911                 lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
1912         if (uDeviceID == (UINT)MIDI_MAPPER) {
1913                 dprintf_mmsys(stddeb, "midiInOpen       // MIDI_MAPPER mode requested !\n");
1914                 bMapperFlg = TRUE;
1915                 uDeviceID = 0;
1916                 }
1917         hMidiIn = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
1918         if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
1919         lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiIn);
1920         lpDesc = (LPMIDIOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
1921         if (lpDesc == NULL) return MMSYSERR_NOMEM;
1922         lpDesc->hMidi = hMidiIn;
1923         lpDesc->dwCallback = dwCallback;
1924         lpDesc->dwInstance = dwInstance;
1925         while(uDeviceID < MAXMIDIDRIVERS) {
1926                 dwRet = midMessage(uDeviceID, MIDM_OPEN, 
1927                         lpDesc->dwInstance, (DWORD)lpDesc, 0L);
1928                 if (dwRet == MMSYSERR_NOERROR) break;
1929                 if (!bMapperFlg) break;
1930                 uDeviceID++;
1931                 dprintf_mmsys(stddeb, "midiInOpen       // MIDI_MAPPER mode ! try next driver...\n");
1932                 }
1933         return dwRet;
1934 }
1935
1936 /**************************************************************************
1937 *                               midiInClose             [MMSYSTEM.305]
1938 */
1939 UINT midiInClose(HMIDIIN hMidiIn)
1940 {
1941         LPMIDIOPENDESC  lpDesc;
1942         dprintf_mmsys(stddeb, "midiInClose(%04X)\n", hMidiIn);
1943         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
1944         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1945         return midMessage(0, MIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
1946 }
1947
1948 /**************************************************************************
1949 *                               midiInPrepareHeader     [MMSYSTEM.306]
1950 */
1951 UINT midiInPrepareHeader(HMIDIIN hMidiIn,
1952     MIDIHDR FAR* lpMidiInHdr, UINT uSize)
1953 {
1954         LPMIDIOPENDESC  lpDesc;
1955         dprintf_mmsys(stddeb, "midiInPrepareHeader(%04X, %p, %d)\n", 
1956                                         hMidiIn, lpMidiInHdr, uSize);
1957         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
1958         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1959         return midMessage(0, MIDM_PREPARE, lpDesc->dwInstance, 
1960                                                 (DWORD)lpMidiInHdr, (DWORD)uSize);
1961 }
1962
1963 /**************************************************************************
1964 *                               midiInUnprepareHeader   [MMSYSTEM.307]
1965 */
1966 UINT midiInUnprepareHeader(HMIDIIN hMidiIn,
1967     MIDIHDR FAR* lpMidiInHdr, UINT uSize)
1968 {
1969         LPMIDIOPENDESC  lpDesc;
1970         dprintf_mmsys(stddeb, "midiInUnprepareHeader(%04X, %p, %d)\n", 
1971                                         hMidiIn, lpMidiInHdr, uSize);
1972         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
1973         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1974         return midMessage(0, MIDM_UNPREPARE, lpDesc->dwInstance, 
1975                                                 (DWORD)lpMidiInHdr, (DWORD)uSize);
1976 }
1977
1978 /**************************************************************************
1979 *                               midiInAddBuffer         [MMSYSTEM.308]
1980 */
1981 UINT midiInAddBuffer(HMIDIIN hMidiIn,
1982     MIDIHDR FAR* lpMidiInHdr, UINT uSize)
1983 {
1984         dprintf_mmsys(stddeb, "midiInAddBuffer\n");
1985         return 0;
1986 }
1987
1988 /**************************************************************************
1989 *                               midiInStart                     [MMSYSTEM.309]
1990 */
1991 UINT midiInStart(HMIDIIN hMidiIn)
1992 {
1993         dprintf_mmsys(stddeb, "midiInStart\n");
1994         return 0;
1995 }
1996
1997 /**************************************************************************
1998 *                               midiInStop                      [MMSYSTEM.310]
1999 */
2000 UINT midiInStop(HMIDIIN hMidiIn)
2001 {
2002         dprintf_mmsys(stddeb, "midiInStop\n");
2003         return 0;
2004 }
2005
2006 /**************************************************************************
2007 *                               midiInReset                     [MMSYSTEM.311]
2008 */
2009 UINT midiInReset(HMIDIIN hMidiIn)
2010 {
2011         dprintf_mmsys(stddeb, "midiInReset\n");
2012         return 0;
2013 }
2014
2015 /**************************************************************************
2016 *                               midiInGetID                     [MMSYSTEM.312]
2017 */
2018 UINT midiInGetID(HMIDIIN hMidiIn, UINT FAR* lpuDeviceID)
2019 {
2020         dprintf_mmsys(stddeb, "midiInGetID\n");
2021         return 0;
2022 }
2023
2024 /**************************************************************************
2025 *                               midiInMessage           [MMSYSTEM.313]
2026 */
2027 DWORD midiInMessage(HMIDIIN hMidiIn, UINT uMessage, 
2028                                                         DWORD dwParam1, DWORD dwParam2)
2029 {
2030         LPMIDIOPENDESC  lpDesc;
2031         dprintf_mmsys(stddeb, "midiInMessage(%04X, %04X, %08lX, %08lX)\n", 
2032                         hMidiIn, uMessage, dwParam1, dwParam2);
2033         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2034         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2035         return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2036 }
2037
2038
2039 /**************************************************************************
2040 *                               waveOutGetNumDevs               [MMSYSTEM.401]
2041 */
2042 UINT waveOutGetNumDevs()
2043 {
2044         UINT    count = 0;
2045         dprintf_mmsys(stddeb, "waveOutGetNumDevs\n");
2046         count += wodMessage(0, WODM_GETNUMDEVS, 0L, 0L, 0L);
2047         dprintf_mmsys(stddeb, "waveOutGetNumDevs return %u \n", count);
2048         return count;
2049 }
2050
2051 /**************************************************************************
2052 *                               waveOutGetDevCaps               [MMSYSTEM.402]
2053 */
2054 UINT waveOutGetDevCaps(UINT uDeviceID, WAVEOUTCAPS FAR* lpCaps, UINT uSize)
2055 {
2056         dprintf_mmsys(stddeb, "waveOutGetDevCaps\n");
2057         return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
2058 }
2059
2060 /**************************************************************************
2061 *                               waveOutGetErrorText     [MMSYSTEM.403]
2062 */
2063 UINT waveOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
2064 {
2065    dprintf_mmsys(stddeb, "waveOutGetErrorText\n");
2066    return(waveGetErrorText(uError, lpText, uSize));
2067 }
2068
2069
2070 /**************************************************************************
2071 *                               waveGetErrorText                [internal]
2072 */
2073 UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
2074 {
2075         LPSTR   msgptr;
2076         int             maxbuf;
2077         dprintf_mmsys(stddeb, "waveGetErrorText(%04X, %p, %d);\n", uError, lpText, uSize);
2078         if ((lpText == NULL) || (uSize < 1)) return(FALSE);
2079         lpText[0] = '\0';
2080         switch(uError) {
2081                 case MMSYSERR_NOERROR:
2082                         msgptr = "The specified command was carried out.";
2083                         break;
2084                 case MMSYSERR_ERROR:
2085                         msgptr = "Undefined external error.";
2086                         break;
2087                 case MMSYSERR_BADDEVICEID:
2088                         msgptr = "A device ID has been used that is out of range for your system.";
2089                         break;
2090                 case MMSYSERR_NOTENABLED:
2091                         msgptr = "The driver was not enabled.";
2092                         break;
2093                 case MMSYSERR_ALLOCATED:
2094                         msgptr = "The specified device is already in use. Wait until it is free, and then try again.";
2095                         break;
2096                 case MMSYSERR_INVALHANDLE:
2097                         msgptr = "The specified device handle is invalid.";
2098                         break;
2099                 case MMSYSERR_NODRIVER:
2100                         msgptr = "There is no driver installed on your system !\n";
2101                         break;
2102                 case MMSYSERR_NOMEM:
2103                         msgptr = "Not enough memory available for this task. Quit one or more applications to increase available memory, and then try again.";
2104                         break;
2105                 case MMSYSERR_NOTSUPPORTED:
2106                         msgptr = "This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports.";
2107                         break;
2108                 case MMSYSERR_BADERRNUM:
2109                         msgptr = "An error number was specified that is not defined in the system.";
2110                         break;
2111                 case MMSYSERR_INVALFLAG:
2112                         msgptr = "An invalid flag was passed to a system function.";
2113                         break;
2114                 case MMSYSERR_INVALPARAM:
2115                         msgptr = "An invalid parameter was passed to a system function.";
2116                         break;
2117                 case WAVERR_BADFORMAT:
2118                         msgptr = "The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats";
2119                         break;
2120                 case WAVERR_STILLPLAYING:
2121                         msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
2122                         break;
2123                 case WAVERR_UNPREPARED:
2124                         msgptr = "The wave header was not prepared. Use the Prepare function to prepare the header, and then try again.";
2125                         break;
2126                 case WAVERR_SYNC:
2127                         msgptr = "Cannot open the device without using the WAVE_ALLOWSYNC flag. Use the flag, and then try again.";
2128                         break;
2129                 default:
2130                         msgptr = "Unknown MMSYSTEM Error !\n";
2131                         break;
2132                 }
2133         maxbuf = min(uSize - 1, strlen(msgptr));
2134         if (maxbuf > 0) strncpy(lpText, msgptr, maxbuf);
2135         lpText[maxbuf + 1] = '\0';
2136         return(TRUE);
2137 }
2138
2139 /**************************************************************************
2140 *                               waveOutOpen                     [MMSYSTEM.404]
2141 */
2142 UINT waveOutOpen(HWAVEOUT FAR* lphWaveOut, UINT uDeviceID,
2143     const LPWAVEFORMAT lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
2144 {
2145         HWAVE   hWaveOut;
2146         LPWAVEOPENDESC  lpDesc;
2147         LPWAVEOPENDESC  lp16Desc;
2148         DWORD   dwRet = 0;
2149         BOOL    bMapperFlg = FALSE;
2150         dprintf_mmsys(stddeb, "waveOutOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
2151                 lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
2152         if (dwFlags & WAVE_FORMAT_QUERY) {
2153                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_FORMAT_QUERY requested !\n");
2154                 }
2155         if (uDeviceID == (UINT)WAVE_MAPPER) {
2156                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_MAPPER mode requested !\n");
2157                 bMapperFlg = TRUE;
2158                 uDeviceID = 0;
2159                 }
2160         if (lpFormat == NULL) return WAVERR_BADFORMAT;
2161         hWaveOut = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
2162         if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
2163         lp16Desc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hWaveOut);
2164         lpDesc = (LPWAVEOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
2165         if (lpDesc == NULL) return MMSYSERR_NOMEM;
2166         lpDesc->hWave = hWaveOut;
2167         lpDesc->lpFormat = lpFormat;
2168         lpDesc->dwCallBack = dwCallback;
2169         lpDesc->dwInstance = dwInstance;
2170         while(uDeviceID < MAXWAVEDRIVERS) {
2171                 dwRet = wodMessage(uDeviceID, WODM_OPEN, 
2172                         lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
2173                 if (dwRet == MMSYSERR_NOERROR) break;
2174                 if (!bMapperFlg) break;
2175                 uDeviceID++;
2176                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_MAPPER mode ! try next driver...\n");
2177                 }
2178         if (dwFlags & WAVE_FORMAT_QUERY) {
2179                 dprintf_mmsys(stddeb, "waveOutOpen      // End of WAVE_FORMAT_QUERY !\n");
2180                 waveOutClose(hWaveOut);
2181                 }
2182         return dwRet;
2183 }
2184
2185 /**************************************************************************
2186 *                               waveOutClose            [MMSYSTEM.405]
2187 */
2188 UINT waveOutClose(HWAVEOUT hWaveOut)
2189 {
2190         LPWAVEOPENDESC  lpDesc;
2191         dprintf_mmsys(stddeb, "waveOutClose(%04X)\n", hWaveOut);
2192         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2193         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2194         return wodMessage(0, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
2195 }
2196
2197 /**************************************************************************
2198 *                               waveOutPrepareHeader    [MMSYSTEM.406]
2199 */
2200 UINT waveOutPrepareHeader(HWAVEOUT hWaveOut,
2201      WAVEHDR FAR* lpWaveOutHdr, UINT uSize)
2202 {
2203         LPWAVEOPENDESC  lpDesc;
2204         dprintf_mmsys(stddeb, "waveOutPrepareHeader(%04X, %p, %u);\n", 
2205                                         hWaveOut, lpWaveOutHdr, uSize);
2206         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2207         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2208         return wodMessage(0, WODM_PREPARE, lpDesc->dwInstance, 
2209                                                         (DWORD)lpWaveOutHdr, uSize);
2210 }
2211
2212 /**************************************************************************
2213 *                               waveOutUnprepareHeader  [MMSYSTEM.407]
2214 */
2215 UINT waveOutUnprepareHeader(HWAVEOUT hWaveOut,
2216     WAVEHDR FAR* lpWaveOutHdr, UINT uSize)
2217 {
2218         LPWAVEOPENDESC  lpDesc;
2219         dprintf_mmsys(stddeb, "waveOutUnprepareHeader(%04X, %p, %u);\n", 
2220                                                 hWaveOut, lpWaveOutHdr, uSize);
2221         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2222         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2223         return wodMessage(0, WODM_UNPREPARE, lpDesc->dwInstance, 
2224                                                         (DWORD)lpWaveOutHdr, uSize);
2225 }
2226
2227 /**************************************************************************
2228 *                               waveOutWrite            [MMSYSTEM.408]
2229 */
2230 UINT waveOutWrite(HWAVEOUT hWaveOut, WAVEHDR FAR* lpWaveOutHdr,  UINT uSize)
2231 {
2232         LPWAVEOPENDESC  lpDesc;
2233         dprintf_mmsys(stddeb, "waveOutWrite(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2234         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2235         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2236         return wodMessage(0, WODM_WRITE, lpDesc->dwInstance, 
2237                                                         (DWORD)lpWaveOutHdr, uSize);
2238 }
2239
2240 /**************************************************************************
2241 *                               waveOutPause            [MMSYSTEM.409]
2242 */
2243 UINT waveOutPause(HWAVEOUT hWaveOut)
2244 {
2245         LPWAVEOPENDESC  lpDesc;
2246         dprintf_mmsys(stddeb, "waveOutPause(%04X)\n", hWaveOut);
2247         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2248         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2249         return wodMessage(0, WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
2250 }
2251
2252 /**************************************************************************
2253 *                               waveOutRestart          [MMSYSTEM.410]
2254 */
2255 UINT waveOutRestart(HWAVEOUT hWaveOut)
2256 {
2257         LPWAVEOPENDESC  lpDesc;
2258         dprintf_mmsys(stddeb, "waveOutRestart(%04X)\n", hWaveOut);
2259         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2260         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2261         return wodMessage(0, WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
2262 }
2263
2264 /**************************************************************************
2265 *                               waveOutReset            [MMSYSTEM.411]
2266 */
2267 UINT waveOutReset(HWAVEOUT hWaveOut)
2268 {
2269         LPWAVEOPENDESC  lpDesc;
2270         dprintf_mmsys(stddeb, "waveOutReset(%04X)\n", hWaveOut);
2271         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2272         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2273         return wodMessage(0, WODM_RESET, lpDesc->dwInstance, 0L, 0L);
2274 }
2275
2276 /**************************************************************************
2277 *                               waveOutGetPosition      [MMSYSTEM.412]
2278 */
2279 UINT waveOutGetPosition(HWAVEOUT hWaveOut, MMTIME FAR* lpTime, UINT uSize)
2280 {
2281         LPWAVEOPENDESC  lpDesc;
2282         dprintf_mmsys(stddeb, "waveOutGetPosition(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
2283         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2284         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2285         return wodMessage(0, WODM_GETPOS, lpDesc->dwInstance, 
2286                                                         (DWORD)lpTime, (DWORD)uSize);
2287 }
2288
2289 /**************************************************************************
2290 *                               waveOutGetPitch         [MMSYSTEM.413]
2291 */
2292 UINT waveOutGetPitch(HWAVEOUT hWaveOut, DWORD FAR* lpdwPitch)
2293 {
2294         LPWAVEOPENDESC  lpDesc;
2295         dprintf_mmsys(stddeb, "waveOutGetPitch(%04X, %p);\n", hWaveOut, lpdwPitch);
2296         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2297         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2298         return wodMessage(0, WODM_GETPITCH, lpDesc->dwInstance, 
2299                                                                 (DWORD)lpdwPitch, 0L);
2300 }
2301
2302 /**************************************************************************
2303 *                               waveOutSetPitch         [MMSYSTEM.414]
2304 */
2305 UINT waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dwPitch)
2306 {
2307         LPWAVEOPENDESC  lpDesc;
2308         dprintf_mmsys(stddeb, "waveOutSetPitch(%04X, %08lX);\n", hWaveOut, dwPitch);
2309         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2310         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2311         return wodMessage(0, WODM_SETPITCH, lpDesc->dwInstance, (DWORD)dwPitch, 0L);
2312 }
2313
2314 /**************************************************************************
2315 *                               waveOutGetVolume        [MMSYSTEM.415]
2316 */
2317 UINT waveOutGetVolume(UINT uDeviceID, DWORD FAR* lpdwVolume)
2318 {
2319         dprintf_mmsys(stddeb, "waveOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
2320         return wodMessage(uDeviceID, WODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
2321 }
2322
2323 /**************************************************************************
2324 *                               waveOutSetVolume        [MMSYSTEM.416]
2325 */
2326 UINT waveOutSetVolume(UINT uDeviceID, DWORD dwVolume)
2327 {
2328         dprintf_mmsys(stddeb, "waveOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
2329         return wodMessage(uDeviceID, WODM_SETVOLUME, 0L, dwVolume, 0L);
2330 }
2331
2332 /**************************************************************************
2333 *                               waveOutGetPlaybackRate  [MMSYSTEM.417]
2334 */
2335 UINT waveOutGetPlaybackRate(HWAVEOUT hWaveOut, DWORD FAR* lpdwRate)
2336 {
2337         LPWAVEOPENDESC  lpDesc;
2338         dprintf_mmsys(stddeb, "waveOutGetPlaybackRate(%04X, %p);\n", hWaveOut, lpdwRate);
2339         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2340         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2341         return wodMessage(0, WODM_GETPLAYBACKRATE, lpDesc->dwInstance, 
2342                                                                 (DWORD)lpdwRate, 0L);
2343 }
2344
2345 /**************************************************************************
2346 *                               waveOutSetPlaybackRate  [MMSYSTEM.418]
2347 */
2348 UINT waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dwRate)
2349 {
2350         LPWAVEOPENDESC  lpDesc;
2351         dprintf_mmsys(stddeb, "waveOutSetPlaybackRate(%04X, %08lX);\n", hWaveOut, dwRate);
2352         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2353         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2354         return wodMessage(0, WODM_SETPLAYBACKRATE, 
2355                 lpDesc->dwInstance, (DWORD)dwRate, 0L);
2356 }
2357
2358 /**************************************************************************
2359 *                               waveOutBreakLoop        [MMSYSTEM.419]
2360 */
2361 UINT waveOutBreakLoop(HWAVEOUT hWaveOut)
2362 {
2363         dprintf_mmsys(stddeb, "waveOutBreakLoop(%04X)\n", hWaveOut);
2364         return MMSYSERR_INVALHANDLE;
2365 }
2366
2367 /**************************************************************************
2368 *                               waveOutGetID            [MMSYSTEM.420]
2369 */
2370 UINT waveOutGetID(HWAVEOUT hWaveOut, UINT FAR* lpuDeviceID)
2371 {
2372         LPWAVEOPENDESC  lpDesc;
2373         dprintf_mmsys(stddeb, "waveOutGetID(%04X, %p);\n", hWaveOut, lpuDeviceID);
2374         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2375         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2376         if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
2377 /*
2378         *lpuDeviceID = lpParms->wDeviceID; 
2379 */
2380         return 0;
2381 }
2382
2383 /**************************************************************************
2384 *                               waveOutMessage          [MMSYSTEM.421]
2385 */
2386 DWORD waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, 
2387                                                         DWORD dwParam1, DWORD dwParam2)
2388 {
2389         LPWAVEOPENDESC  lpDesc;
2390         dprintf_mmsys(stddeb, "waveOutMessage(%04X, %04X, %08lX, %08lX)\n", 
2391                         hWaveOut, uMessage, dwParam1, dwParam2);
2392         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2393         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2394         return wodMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2395 }
2396
2397 /**************************************************************************
2398 *                               waveInGetNumDevs                [MMSYSTEM.501]
2399 */
2400 UINT waveInGetNumDevs()
2401 {
2402         UINT    count = 0;
2403         dprintf_mmsys(stddeb, "waveInGetNumDevs\n");
2404         count += widMessage(0, WIDM_GETNUMDEVS, 0L, 0L, 0L);
2405         dprintf_mmsys(stddeb, "waveInGetNumDevs return %u \n", count);
2406         return count;
2407 }
2408
2409
2410 /**************************************************************************
2411 *                               waveInGetDevCaps                [MMSYSTEM.502]
2412 */
2413 UINT waveInGetDevCaps(UINT uDeviceID, WAVEINCAPS FAR* lpCaps, UINT uSize)
2414 {
2415         dprintf_mmsys(stddeb, "waveInGetDevCaps\n");
2416         return widMessage(uDeviceID, WIDM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
2417 }
2418
2419
2420 /**************************************************************************
2421 *                               waveInGetErrorText      [MMSYSTEM.503]
2422 */
2423 UINT waveInGetErrorText(UINT uError, LPSTR lpText, UINT uSize)
2424 {
2425    dprintf_mmsys(stddeb, "waveInGetErrorText\n");
2426    return(waveGetErrorText(uError, lpText, uSize));
2427 }
2428
2429
2430 /**************************************************************************
2431 *                               waveInOpen                      [MMSYSTEM.504]
2432 */
2433 UINT waveInOpen(HWAVEIN FAR* lphWaveIn, UINT uDeviceID,
2434     const LPWAVEFORMAT lpFormat, DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
2435 {
2436         HWAVE   hWaveIn;
2437         LPWAVEOPENDESC  lpDesc;
2438         LPWAVEOPENDESC  lp16Desc;
2439         DWORD   dwRet = 0;
2440         BOOL    bMapperFlg = FALSE;
2441         dprintf_mmsys(stddeb, "waveInOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
2442                 lphWaveIn, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
2443         if (dwFlags & WAVE_FORMAT_QUERY) {
2444                 dprintf_mmsys(stddeb, "waveInOpen // WAVE_FORMAT_QUERY requested !\n");
2445                 }
2446         if (uDeviceID == (UINT)WAVE_MAPPER) {
2447                 dprintf_mmsys(stddeb, "waveInOpen       // WAVE_MAPPER mode requested !\n");
2448                 bMapperFlg = TRUE;
2449                 uDeviceID = 0;
2450                 }
2451         if (lpFormat == NULL) return WAVERR_BADFORMAT;
2452         hWaveIn = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
2453         if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
2454         lp16Desc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hWaveIn);
2455         lpDesc = (LPWAVEOPENDESC) PTR_SEG_TO_LIN(lp16Desc);
2456         if (lpDesc == NULL) return MMSYSERR_NOMEM;
2457         lpDesc->hWave = hWaveIn;
2458         lpDesc->lpFormat = lpFormat;
2459         lpDesc->dwCallBack = dwCallback;
2460         lpDesc->dwInstance = dwInstance;
2461         while(uDeviceID < MAXWAVEDRIVERS) {
2462                 dwRet = widMessage(uDeviceID, WIDM_OPEN, 
2463                         lpDesc->dwInstance, (DWORD)lp16Desc, 0L);
2464                 if (dwRet == MMSYSERR_NOERROR) break;
2465                 if (!bMapperFlg) break;
2466                 uDeviceID++;
2467                 dprintf_mmsys(stddeb, "waveInOpen       // WAVE_MAPPER mode ! try next driver...\n");
2468                 }
2469         if (dwFlags & WAVE_FORMAT_QUERY) {
2470                 dprintf_mmsys(stddeb, "waveInOpen       // End of WAVE_FORMAT_QUERY !\n");
2471                 waveInClose(hWaveIn);
2472                 }
2473         return dwRet;
2474 }
2475
2476
2477 /**************************************************************************
2478 *                               waveInClose                     [MMSYSTEM.505]
2479 */
2480 UINT waveInClose(HWAVEIN hWaveIn)
2481 {
2482         LPWAVEOPENDESC  lpDesc;
2483         dprintf_mmsys(stddeb, "waveInClose(%04X)\n", hWaveIn);
2484         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2485         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2486         return widMessage(0, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
2487 }
2488
2489
2490 /**************************************************************************
2491 *                               waveInPrepareHeader             [MMSYSTEM.506]
2492 */
2493 UINT waveInPrepareHeader(HWAVEIN hWaveIn,
2494     WAVEHDR FAR* lpWaveInHdr, UINT uSize)
2495 {
2496         LPWAVEOPENDESC  lpDesc;
2497         LPWAVEHDR               lp32WaveInHdr;
2498         dprintf_mmsys(stddeb, "waveInPrepareHeader(%04X, %p, %u);\n", 
2499                                         hWaveIn, lpWaveInHdr, uSize);
2500         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2501         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2502         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
2503         lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
2504         lp32WaveInHdr->lpNext = NULL;
2505     lp32WaveInHdr->dwBytesRecorded = 0;
2506         dprintf_mmsys(stddeb, "waveInPrepareHeader // lpData=%p size=%lu \n", 
2507                 lp32WaveInHdr->lpData, lp32WaveInHdr->dwBufferLength);
2508         return widMessage(0, WIDM_PREPARE, lpDesc->dwInstance, 
2509                                                         (DWORD)lpWaveInHdr, uSize);
2510 }
2511
2512
2513 /**************************************************************************
2514 *                               waveInUnprepareHeader   [MMSYSTEM.507]
2515 */
2516 UINT waveInUnprepareHeader(HWAVEIN hWaveIn,
2517     WAVEHDR FAR* lpWaveInHdr, UINT uSize)
2518 {
2519         LPWAVEOPENDESC  lpDesc;
2520         LPWAVEHDR               lp32WaveInHdr;
2521         dprintf_mmsys(stddeb, "waveInUnprepareHeader(%04X, %p, %u);\n", 
2522                                                 hWaveIn, lpWaveInHdr, uSize);
2523         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2524         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2525         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
2526         lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
2527         USER_HEAP_FREE(HIWORD((DWORD)lp32WaveInHdr->lpData));
2528         lp32WaveInHdr->lpData = NULL;
2529         lp32WaveInHdr->lpNext = NULL;
2530         return widMessage(0, WIDM_UNPREPARE, lpDesc->dwInstance, 
2531                                                         (DWORD)lpWaveInHdr, uSize);
2532 }
2533
2534
2535 /**************************************************************************
2536 *                               waveInAddBuffer         [MMSYSTEM.508]
2537 */
2538 UINT waveInAddBuffer(HWAVEIN hWaveIn,
2539     WAVEHDR FAR* lpWaveInHdr, UINT uSize)
2540 {
2541         LPWAVEOPENDESC  lpDesc;
2542         LPWAVEHDR               lp32WaveInHdr;
2543         dprintf_mmsys(stddeb, "waveInAddBuffer(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
2544         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2545         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2546         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
2547         lp32WaveInHdr = PTR_SEG_TO_LIN(lpWaveInHdr);
2548         lp32WaveInHdr->lpNext = NULL;
2549     lp32WaveInHdr->dwBytesRecorded = 0;
2550         dprintf_mmsys(stddeb, "waveInAddBuffer // lpData=%p size=%lu \n", 
2551                 lp32WaveInHdr->lpData, lp32WaveInHdr->dwBufferLength);
2552         return widMessage(0, WIDM_ADDBUFFER, lpDesc->dwInstance,
2553                                                                 (DWORD)lpWaveInHdr, uSize);
2554 }
2555
2556
2557 /**************************************************************************
2558 *                               waveInStart                     [MMSYSTEM.509]
2559 */
2560 UINT waveInStart(HWAVEIN hWaveIn)
2561 {
2562         LPWAVEOPENDESC  lpDesc;
2563         dprintf_mmsys(stddeb, "waveInStart(%04X)\n", hWaveIn);
2564         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2565         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2566         return widMessage(0, WIDM_START, lpDesc->dwInstance, 0L, 0L);
2567 }
2568
2569
2570 /**************************************************************************
2571 *                               waveInStop                      [MMSYSTEM.510]
2572 */
2573 UINT waveInStop(HWAVEIN hWaveIn)
2574 {
2575         LPWAVEOPENDESC  lpDesc;
2576         dprintf_mmsys(stddeb, "waveInStop(%04X)\n", hWaveIn);
2577         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2578         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2579         return widMessage(0, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
2580 }
2581
2582
2583 /**************************************************************************
2584 *                               waveInReset                     [MMSYSTEM.511]
2585 */
2586 UINT waveInReset(HWAVEIN hWaveIn)
2587 {
2588         LPWAVEOPENDESC  lpDesc;
2589         dprintf_mmsys(stddeb, "waveInReset(%04X)\n", hWaveIn);
2590         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2591         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2592         return widMessage(0, WIDM_RESET, lpDesc->dwInstance, 0L, 0L);
2593 }
2594
2595
2596 /**************************************************************************
2597 *                               waveInGetPosition       [MMSYSTEM.512]
2598 */
2599 UINT waveInGetPosition(HWAVEIN hWaveIn, MMTIME FAR* lpTime, UINT uSize)
2600 {
2601         LPWAVEOPENDESC  lpDesc;
2602         dprintf_mmsys(stddeb, "waveInGetPosition(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
2603         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2604         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2605         return widMessage(0, WIDM_GETPOS, lpDesc->dwInstance,
2606                           (DWORD)lpTime, (DWORD)uSize);
2607 }
2608
2609
2610 /**************************************************************************
2611 *                               waveInGetID                     [MMSYSTEM.513]
2612 */
2613 UINT waveInGetID(HWAVEIN hWaveIn, UINT FAR* lpuDeviceID)
2614 {
2615         dprintf_mmsys(stddeb, "waveInGetID\n");
2616         if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
2617         return 0;
2618 }
2619
2620
2621 /**************************************************************************
2622 *                               waveInMessage           [MMSYSTEM.514]
2623 */
2624 DWORD waveInMessage(HWAVEIN hWaveIn, UINT uMessage,
2625                     DWORD dwParam1, DWORD dwParam2)
2626 {
2627         LPWAVEOPENDESC  lpDesc;
2628         dprintf_mmsys(stddeb, "waveInMessage(%04X, %04X, %08lX, %08lX)\n", 
2629                         hWaveIn, uMessage, dwParam1, dwParam2);
2630         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
2631         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2632         return widMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2633 }
2634
2635
2636 /**************************************************************************
2637 *                               mmioOpen                [MMSYSTEM.1210]
2638 */
2639 HMMIO mmioOpen(LPSTR szFileName, MMIOINFO FAR* lpmmioinfo, DWORD dwOpenFlags)
2640 {
2641         int             hFile;
2642         HANDLE          hmmio;
2643         OFSTRUCT        ofs;
2644         LPMMIOINFO      lpmminfo;
2645         dprintf_mmsys(stddeb, "mmioOpen('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
2646         hFile = OpenFile(szFileName, &ofs, dwOpenFlags);
2647         if (hFile == -1) return 0;
2648         hmmio = GlobalAlloc(GMEM_MOVEABLE, sizeof(MMIOINFO));
2649         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2650         if (lpmminfo == NULL) return 0;
2651         memset(lpmminfo, 0, sizeof(MMIOINFO));
2652         lpmminfo->hmmio = hmmio;
2653         lpmminfo->dwReserved2 = MAKELONG(hFile, 0);
2654         GlobalUnlock(hmmio);
2655         dprintf_mmsys(stddeb, "mmioOpen // return hmmio=%04X\n", hmmio);
2656         return hmmio;
2657 }
2658
2659     
2660 /**************************************************************************
2661 *                               mmioClose               [MMSYSTEM.1211]
2662 */
2663 UINT mmioClose(HMMIO hmmio, UINT uFlags)
2664 {
2665         LPMMIOINFO      lpmminfo;
2666         dprintf_mmsys(stddeb, "mmioClose(%04X, %04X);\n", hmmio, uFlags);
2667         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2668         if (lpmminfo == NULL) return 0;
2669         _lclose(LOWORD(lpmminfo->dwReserved2));
2670         GlobalUnlock(hmmio);
2671         GlobalFree(hmmio);
2672         return 0;
2673 }
2674
2675
2676
2677 /**************************************************************************
2678 *                               mmioRead                [MMSYSTEM.1212]
2679 */
2680 LONG mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
2681 {
2682         LONG            count;
2683         LPMMIOINFO      lpmminfo;
2684         dprintf_mmio(stddeb, "mmioRead(%04X, %p, %ld);\n", hmmio, pch, cch);
2685         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2686         if (lpmminfo == NULL) return 0;
2687         count = read(LOWORD(lpmminfo->dwReserved2), pch, cch);
2688         GlobalUnlock(hmmio);
2689         dprintf_mmio(stddeb, "mmioRead // count=%ld\n", count);
2690         return count;
2691 }
2692
2693
2694
2695 /**************************************************************************
2696 *                               mmioWrite               [MMSYSTEM.1213]
2697 */
2698 LONG mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
2699 {
2700         LONG            count;
2701         LPMMIOINFO      lpmminfo;
2702         dprintf_mmsys(stddeb, "mmioWrite(%04X, %p, %ld);\n", hmmio, pch, cch);
2703         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2704         if (lpmminfo == NULL) return 0;
2705         count = _lwrite(LOWORD(lpmminfo->dwReserved2), (LPSTR)pch, cch);
2706         GlobalUnlock(hmmio);
2707         return count;
2708 }
2709
2710 /**************************************************************************
2711 *                               mmioSeek                [MMSYSTEM.1214]
2712 */
2713 LONG mmioSeek(HMMIO hmmio, LONG lOffset, int iOrigin)
2714 {
2715         int             count;
2716         LPMMIOINFO      lpmminfo;
2717         dprintf_mmsys(stddeb, "mmioSeek(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
2718         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2719         if (lpmminfo == NULL) {
2720                 dprintf_mmsys(stddeb, "mmioSeek // can't lock hmmio=%04X !\n", hmmio);
2721                 return 0;
2722                 }
2723         count = _llseek(LOWORD(lpmminfo->dwReserved2), lOffset, iOrigin);
2724         GlobalUnlock(hmmio);
2725         return count;
2726 }
2727
2728 /**************************************************************************
2729 *                               mmioGetInfo             [MMSYSTEM.1215]
2730 */
2731 UINT mmioGetInfo(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags)
2732 {
2733         LPMMIOINFO      lpmminfo;
2734         dprintf_mmsys(stddeb, "mmioGetInfo\n");
2735         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2736         if (lpmminfo == NULL) return 0;
2737         memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO));
2738         GlobalUnlock(hmmio);
2739         return 0;
2740 }
2741
2742 /**************************************************************************
2743 *                               mmioSetInfo             [MMSYSTEM.1216]
2744 */
2745 UINT mmioSetInfo(HMMIO hmmio, const MMIOINFO FAR* lpmmioinfo, UINT uFlags)
2746 {
2747         LPMMIOINFO      lpmminfo;
2748         dprintf_mmsys(stddeb, "mmioSetInfo\n");
2749         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2750         if (lpmminfo == NULL) return 0;
2751         GlobalUnlock(hmmio);
2752         return 0;
2753 }
2754
2755 /**************************************************************************
2756 *                               mmioSetBuffer           [MMSYSTEM.1217]
2757 */
2758 UINT mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, 
2759                                                 LONG cchBuffer, UINT uFlags)
2760 {
2761         dprintf_mmsys(stddeb, "mmioSetBuffer // empty stub \n");
2762         return 0;
2763 }
2764
2765 /**************************************************************************
2766 *                               mmioFlush               [MMSYSTEM.1218]
2767 */
2768 UINT mmioFlush(HMMIO hmmio, UINT uFlags)
2769 {
2770         LPMMIOINFO      lpmminfo;
2771         dprintf_mmsys(stddeb, "mmioFlush(%04X, %04X)\n", hmmio, uFlags);
2772         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2773         if (lpmminfo == NULL) return 0;
2774         GlobalUnlock(hmmio);
2775         return 0;
2776 }
2777
2778 /**************************************************************************
2779 *                               mmioAdvance             [MMSYSTEM.1219]
2780 */
2781 UINT mmioAdvance(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags)
2782 {
2783         int             count = 0;
2784         LPMMIOINFO      lpmminfo;
2785         dprintf_mmsys(stddeb, "mmioAdvance\n");
2786         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2787         if (lpmminfo == NULL) return 0;
2788         if (uFlags == MMIO_READ) {
2789                 count = read(LOWORD(lpmminfo->dwReserved2), 
2790                         lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
2791                 }
2792         if (uFlags == MMIO_WRITE) {
2793                 count = _lwrite(LOWORD(lpmminfo->dwReserved2),
2794                         lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
2795                 }
2796         lpmmioinfo->pchNext     += count;
2797         GlobalUnlock(hmmio);
2798         lpmminfo->lDiskOffset = _llseek(LOWORD(lpmminfo->dwReserved2), 0, SEEK_CUR);
2799         return 0;
2800 }
2801
2802 /**************************************************************************
2803 *                               mmioStringToFOURCC      [MMSYSTEM.1220]
2804 */
2805 FOURCC mmioStringToFOURCC(LPCSTR sz, UINT uFlags)
2806 {
2807         dprintf_mmsys(stddeb, "mmioStringToFOURCC // empty stub \n");
2808         return 0;
2809 }
2810
2811 /**************************************************************************
2812 *                               mmioInstallIOProc       [MMSYSTEM.1221]
2813 */
2814 LPMMIOPROC mmioInstallIOProc(FOURCC fccIOProc, 
2815                                 LPMMIOPROC pIOProc, DWORD dwFlags)
2816 {
2817         dprintf_mmsys(stddeb, "mmioInstallIOProc // empty stub \n");
2818         return 0;
2819 }
2820
2821 /**************************************************************************
2822 *                               mmioSendMessage         [MMSYSTEM.1222]
2823 */
2824 LRESULT mmioSendMessage(HMMIO hmmio, UINT uMessage,
2825                                             LPARAM lParam1, LPARAM lParam2)
2826 {
2827         dprintf_mmsys(stddeb, "mmioSendMessage // empty stub \n");
2828         return 0;
2829 }
2830
2831 /**************************************************************************
2832 *                               mmioDescend             [MMSYSTEM.1223]
2833 */
2834 UINT mmioDescend(HMMIO hmmio, MMCKINFO FAR* lpck,
2835                     const MMCKINFO FAR* lpckParent, UINT uFlags)
2836 {
2837         DWORD   dwfcc, dwOldPos;
2838         LPMMIOINFO      lpmminfo;
2839         dprintf_mmio(stddeb, "mmioDescend(%04X, %p, %p, %04X);\n", 
2840                                 hmmio, lpck, lpckParent, uFlags);
2841         if (lpck == NULL) return 0;
2842         lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
2843         if (lpmminfo == NULL) return 0;
2844         dwfcc = lpck->ckid;
2845         dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX\n", dwfcc);
2846         dwOldPos = _llseek(LOWORD(lpmminfo->dwReserved2), 0, SEEK_CUR);
2847         dprintf_mmio(stddeb, "mmioDescend // dwOldPos=%ld\n", dwOldPos);
2848         if (lpckParent != NULL) {
2849                 dprintf_mmio(stddeb, "mmioDescend // seek inside parent at %ld !\n", lpckParent->dwDataOffset);
2850                 dwOldPos = _llseek(LOWORD(lpmminfo->dwReserved2), 
2851                                         lpckParent->dwDataOffset, SEEK_SET);
2852                 }
2853         if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDRIFF) || 
2854                 (uFlags & MMIO_FINDLIST)) {
2855                 dprintf_mmio(stddeb, "mmioDescend // MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc);
2856                 while (TRUE) {
2857                         if (read(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
2858                                         sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
2859                                 _llseek(LOWORD(lpmminfo->dwReserved2), dwOldPos, SEEK_SET);
2860                                 GlobalUnlock(hmmio);
2861                                 return MMIOERR_CHUNKNOTFOUND;
2862                                 }
2863                         dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX ckid=%08lX cksize=%08lX !\n", 
2864                                                                         dwfcc, lpck->ckid, lpck->cksize);
2865                         if (dwfcc == lpck->ckid) break;
2866                         dwOldPos += lpck->cksize + 2 * sizeof(DWORD);
2867                         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
2868                                 dwOldPos += sizeof(DWORD);
2869                         _llseek(LOWORD(lpmminfo->dwReserved2), dwOldPos, SEEK_SET);
2870                         }
2871                 }
2872         else {
2873                 if (read(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
2874                                 sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
2875                         _llseek(LOWORD(lpmminfo->dwReserved2), dwOldPos, SEEK_SET);
2876                         GlobalUnlock(hmmio);
2877                         return MMIOERR_CHUNKNOTFOUND;
2878                         }
2879                 }
2880         lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
2881         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
2882                 lpck->dwDataOffset += sizeof(DWORD);
2883         lpmminfo->lDiskOffset = _llseek(LOWORD(lpmminfo->dwReserved2), 
2884                                                                         lpck->dwDataOffset, SEEK_SET);
2885         GlobalUnlock(hmmio);
2886         dprintf_mmio(stddeb, "mmioDescend // lpck->ckid=%08lX lpck->cksize=%ld !\n", 
2887                                                                 lpck->ckid, lpck->cksize);
2888         dprintf_mmsys(stddeb, "mmioDescend // lpck->fccType=%08lX !\n", lpck->fccType);
2889         return 0;
2890 }
2891
2892 /**************************************************************************
2893 *                               mmioAscend              [MMSYSTEM.1224]
2894 */
2895 UINT mmioAscend(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags)
2896 {
2897         dprintf_mmsys(stddeb, "mmioAscend // empty stub !\n");
2898         return 0;
2899 }
2900
2901 /**************************************************************************
2902 *                               mmioCreateChunk         [MMSYSTEM.1225]
2903 */
2904 UINT mmioCreateChunk(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags)
2905 {
2906         dprintf_mmsys(stddeb, "mmioCreateChunk // empty stub \n");
2907         return 0;
2908 }
2909
2910
2911 /**************************************************************************
2912 *                               mmioRename              [MMSYSTEM.1226]
2913 */
2914 UINT mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
2915      MMIOINFO FAR* lpmmioinfo, DWORD dwRenameFlags)
2916 {
2917         dprintf_mmsys(stddeb, "mmioRename('%s', '%s', %p, %08lX); // empty stub \n",
2918                         szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
2919         return 0;
2920 }
2921
2922 /**************************************************************************
2923 *                               DrvOpen                 [MMSYSTEM.1100]
2924 */
2925 HDRVR DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
2926 {
2927         dprintf_mmsys(stddeb, "DrvOpen('%s', '%s', %08lX);\n",
2928                 lpDriverName, lpSectionName, lParam);
2929         return OpenDriver(lpDriverName, lpSectionName, lParam);
2930 }
2931
2932
2933 /**************************************************************************
2934 *                               DrvClose                [MMSYSTEM.1101]
2935 */
2936 LRESULT DrvClose(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
2937 {
2938         dprintf_mmsys(stddeb, "DrvClose(%04X, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
2939         return CloseDriver(hDrvr, lParam1, lParam2);
2940 }
2941
2942
2943 /**************************************************************************
2944 *                               DrvSendMessage          [MMSYSTEM.1102]
2945 */
2946 LRESULT DrvSendMessage(HDRVR hDriver, WORD msg, LPARAM lParam1, LPARAM lParam2)
2947 {
2948         DWORD   dwDevID = 0;
2949         dprintf_mmsys(stddeb, "DrvSendMessage(%04X, %04X, %08lX, %08lX);\n",
2950                                         hDriver, msg, lParam1, lParam2);
2951 #ifndef WINELIB
2952         return CDAUDIO_DriverProc(dwDevID, hDriver, msg, lParam1, lParam2);
2953 #endif
2954 }
2955
2956 /**************************************************************************
2957 *                               DrvGetModuleHandle      [MMSYSTEM.1103]
2958 */
2959 HANDLE DrvGetModuleHandle(HDRVR hDrvr)
2960 {
2961         dprintf_mmsys(stddeb, "DrvGetModuleHandle(%04X);\n", hDrvr);
2962         return 0;
2963 }
2964
2965
2966 /**************************************************************************
2967 *                               DrvDefDriverProc        [MMSYSTEM.1104]
2968 */
2969 LRESULT DrvDefDriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
2970                                                 DWORD dwParam1, DWORD dwParam2)
2971 {
2972         return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
2973 }
2974
2975
2976 #endif /* #ifdef WINELIB */
2977