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