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