Release 971101
[wine] / multimedia / mmsystem.c
1 /*
2  * MMSYTEM functions
3  *
4  * Copyright 1993 Martin Ayotte
5  */
6 /* FIXME: I think there are some segmented vs. linear pointer weirdnesses 
7  *        and long term pointers to 16 bit space in here
8  */
9
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <fcntl.h>
15 #include <errno.h>
16 #include <sys/ioctl.h>
17 #include "windows.h"
18 #include "win.h"
19 #include "heap.h"
20 #include "ldt.h"
21 #include "user.h"
22 #include "driver.h"
23 #include "file.h"
24 #include "mmsystem.h"
25 #include "stddebug.h"
26 #include "debug.h"
27 #include "xmalloc.h"
28 #include "callback.h"
29
30 static int      InstalledCount;
31 static int      InstalledListLen;
32 static LPSTR    lpInstallNames = NULL;
33
34 MCI_OPEN_DRIVER_PARMS   mciDrv[MAXMCIDRIVERS];
35 /* struct below is to remember alias/devicenames for mcistring.c 
36  * FIXME: should use some internal struct ... 
37  */
38 MCI_OPEN_PARMS16 mciOpenDrv[MAXMCIDRIVERS];
39
40 UINT16 midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
41 static UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
42 LONG WINAPI DrvDefDriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
43                              DWORD dwParam1, DWORD dwParam2);
44
45 LONG WAVE_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
46                      DWORD dwParam1, DWORD dwParam2);
47 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
48                      DWORD dwParam1, DWORD dwParam2);
49 LONG CDAUDIO_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
50                         DWORD dwParam1, DWORD dwParam2);
51 LONG ANIM_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
52                      DWORD dwParam1, DWORD dwParam2);
53
54
55 #define GetDrv(wDevID) (&mciDrv[MMSYSTEM_DevIDToIndex(wDevID)])
56 #define GetOpenDrv(wDevID) (&mciOpenDrv[MMSYSTEM_DevIDToIndex(wDevID)])
57
58 /* The wDevID's returned by wine were originally in the range 
59  * 0 - (MAXMCIDRIVERS - 1) and used directly as array indices.
60  * Unfortunately, ms-windows uses wDevID of zero to indicate
61  * errors.  Now, multimedia drivers must pass the wDevID through
62  * MMSYSTEM_DevIDToIndex to get an index in that range.  An
63  * aribtrary value, MMSYSTEM_MAGIC is added to the wDevID seen
64  * by the windows programs.
65  */
66
67 #define MMSYSTEM_MAGIC 0x0F00
68
69 /**************************************************************************
70  *                              MMSYSTEM_DevIDToIndex   [internal]
71  */
72 int MMSYSTEM_DevIDToIndex(UINT16 wDevID) {
73         return wDevID - MMSYSTEM_MAGIC;
74 }
75
76 /**************************************************************************
77  *                              MMSYSTEM_FirstDevId     [internal]
78  */
79 UINT16 MMSYSTEM_FirstDevID(void)
80 {
81         return MMSYSTEM_MAGIC;
82 }
83
84 /**************************************************************************
85  *                              MMSYSTEM_NextDevId      [internal]
86  */
87 UINT16 MMSYSTEM_NextDevID(UINT16 wDevID) {
88         return wDevID + 1;
89 }
90
91 /**************************************************************************
92  *                              MMSYSTEM_DevIdValid     [internal]
93  */
94 BOOL32 MMSYSTEM_DevIDValid(UINT16 wDevID) {
95         return wDevID >= 0x0F00 && wDevID < (0x0F00 + MAXMCIDRIVERS);
96 }
97
98 /**************************************************************************
99  *                              MMSYSTEM_WEP            [MMSYSTEM.1]
100  */
101 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
102                         WORD cbHeapSize, LPSTR lpCmdLine)
103 {
104         fprintf(stderr, "STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
105         return(TRUE);
106 }
107
108 void
109 MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16,LPMMTIME32 mmt32) {
110         mmt16->wType = mmt32->wType;
111         /* layout of rest is the same for 32/16 */
112         memcpy(&(mmt32->u),&(mmt16->u),sizeof(mmt16->u));
113 }
114
115 void
116 MMSYSTEM_MMTIME16to32(LPMMTIME32 mmt32,LPMMTIME16 mmt16) {
117         mmt32->wType = mmt16->wType;
118         /* layout of rest is the same for 32/16,
119          * Note: mmt16->u is 2 bytes smaller than mmt32->u
120          */
121         memcpy(&(mmt16->u),&(mmt32->u),sizeof(mmt16->u));
122 }
123
124 /**************************************************************************
125 *                               PlaySoundA              [WINMM.1]
126 */
127 BOOL32 WINAPI PlaySound32A(LPCSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
128 {
129   dprintf_mmsys(stddeb, "PlaySoundA: pszSound='%s' hmod=%04X fdwSound=%08lX\n",
130                 pszSound, hmod, fdwSound);
131   if(hmod != 0 || !(fdwSound & SND_FILENAME)) {
132     fprintf(stderr, "PlaySoundA: only disk sound files are supported\n");
133     return FALSE;
134   } else {
135     BOOL16 bSound;
136     bSound = sndPlaySound(pszSound, (UINT16) fdwSound);
137     return (BOOL32) bSound;
138   }
139 }
140
141 /**************************************************************************
142 *                               PlaySoundW              [WINMM.18]
143 */
144 BOOL32 WINAPI PlaySound32W(LPCWSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
145 {
146   LPSTR pszSoundA = HEAP_strdupWtoA(GetProcessHeap(),0,pszSound);
147   BOOL32 bSound;
148
149   bSound = PlaySound32A(pszSoundA, hmod, fdwSound);
150   HeapFree(GetProcessHeap(),0,pszSoundA);
151   return bSound;
152 }
153
154 /**************************************************************************
155 *                               sndPlaySound            [MMSYSTEM.2]
156 */
157 BOOL16 WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags)
158 {
159         BOOL16                  bRet = FALSE;
160         HMMIO16                 hmmio;
161         MMCKINFO                ckMainRIFF;
162         char                    str[128];
163         LPSTR                   ptr;
164
165         dprintf_mmsys(stddeb, "sndPlaySound // SoundName='%s' uFlags=%04X !\n", 
166                                                                         lpszSoundName, uFlags);
167         if (lpszSoundName == NULL) {
168                 dprintf_mmsys(stddeb, "sndPlaySound // Stop !\n");
169                 return FALSE;
170                 }
171         hmmio = mmioOpen16((LPSTR)lpszSoundName, NULL, 
172                 MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
173
174         if (uFlags & SND_MEMORY) {
175                 dprintf_mmsys(stddeb, "sndPlaySound // SND_MEMORY flag not implemented!\n");
176                 return FALSE;
177         }
178
179         if (hmmio == 0) 
180         {
181                 dprintf_mmsys(stddeb, "sndPlaySound // searching in SystemSound List !\n");
182                 GetProfileString32A("Sounds", (LPSTR)lpszSoundName, "", str, sizeof(str));
183                 if (strlen(str) == 0) return FALSE;
184                 if ( (ptr = (LPSTR)strchr(str, ',')) != NULL) *ptr = '\0';
185                 hmmio = mmioOpen16(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
186                 if (hmmio == 0) 
187                 {
188                         dprintf_mmsys(stddeb, "sndPlaySound // can't find SystemSound='%s' !\n", str);
189                         return FALSE;
190                 }
191         }
192
193         if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0) == 0) 
194         {
195             dprintf_mmsys(stddeb, "sndPlaySound // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
196                                 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
197
198             if ((ckMainRIFF.ckid == FOURCC_RIFF) &&
199                 (ckMainRIFF.fccType == mmioFOURCC('W', 'A', 'V', 'E')))
200             {
201                 MMCKINFO        mmckInfo;
202
203                 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
204
205                 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0)
206                 {
207                     PCMWAVEFORMAT           pcmWaveFormat;
208
209                     dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
210                                 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
211
212                     if (mmioRead(hmmio, (HPSTR) &pcmWaveFormat,
213                                 (long) sizeof(PCMWAVEFORMAT)) == (long) sizeof(PCMWAVEFORMAT))
214                     {
215
216                         dprintf_mmsys(stddeb, "sndPlaySound // wFormatTag=%04X !\n", pcmWaveFormat.wf.wFormatTag);
217                         dprintf_mmsys(stddeb, "sndPlaySound // nChannels=%d \n", pcmWaveFormat.wf.nChannels);
218                         dprintf_mmsys(stddeb, "sndPlaySound // nSamplesPerSec=%ld\n", pcmWaveFormat.wf.nSamplesPerSec);
219                         dprintf_mmsys(stddeb, "sndPlaySound // nAvgBytesPerSec=%ld\n", pcmWaveFormat.wf.nAvgBytesPerSec);
220                         dprintf_mmsys(stddeb, "sndPlaySound // nBlockAlign=%d \n", pcmWaveFormat.wf.nBlockAlign);
221                         dprintf_mmsys(stddeb, "sndPlaySound // wBitsPerSample=%u !\n", pcmWaveFormat.wBitsPerSample);
222
223                         mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
224                         if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0)
225                         {
226                             WAVEOPENDESC        waveDesc;
227                             DWORD               dwRet;
228
229                             dprintf_mmsys(stddeb, "sndPlaySound // Chunk Found \
230  ckid=%.4s fccType=%.4s cksize=%08lX \n", (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
231
232                             pcmWaveFormat.wf.nAvgBytesPerSec = pcmWaveFormat.wf.nSamplesPerSec * 
233                                                            pcmWaveFormat.wf.nBlockAlign;
234                             waveDesc.hWave    = 0;
235                             waveDesc.lpFormat = (LPWAVEFORMAT)&pcmWaveFormat;
236
237                             dwRet = wodMessage( 0, WODM_OPEN, 0, (DWORD)&waveDesc, CALLBACK_NULL);
238                             if (dwRet == MMSYSERR_NOERROR) 
239                             {
240                                 WAVEHDR         waveHdr;
241                                 HGLOBAL16       hData;
242                                 INT32           count, bufsize;
243
244                                 bufsize = 64000;
245                                 hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
246                                 waveHdr.lpData = (LPSTR)GlobalLock16(hData);
247                                 waveHdr.dwBufferLength = bufsize;
248                                 waveHdr.dwUser = 0L;
249                                 waveHdr.dwFlags = 0L;
250                                 waveHdr.dwLoops = 0L;
251
252                                 dwRet = wodMessage(0,WODM_PREPARE,0,(DWORD)&waveHdr,sizeof(WAVEHDR));
253                                 if (dwRet == MMSYSERR_NOERROR) 
254                                 {
255                                     while( TRUE )
256                                     {
257                                         count = mmioRead(hmmio, waveHdr.lpData, bufsize);
258                                         if (count < 1) break;
259                                         waveHdr.dwBufferLength = count;
260                                 /*      waveHdr.dwBytesRecorded = count; */
261                                         /* FIXME: doesn't expect async ops */ 
262                                         wodMessage( 0, WODM_WRITE, 0, (DWORD)&waveHdr, sizeof(WAVEHDR));
263                                     }
264                                     wodMessage( 0, WODM_UNPREPARE, 0, (DWORD)&waveHdr, sizeof(WAVEHDR));
265                                     wodMessage( 0, WODM_CLOSE, 0, 0L, 0L);
266
267                                     bRet = TRUE;
268                                 }
269                                 else dprintf_mmsys(stddeb, "sndPlaySound // can't prepare WaveOut device !\n");
270
271                                 GlobalUnlock16(hData);
272                                 GlobalFree16(hData);
273                             }
274                         }
275                     }
276                 }
277             }
278         }
279
280         if (hmmio != 0) mmioClose(hmmio, 0);
281         return bRet;
282 }
283
284 /**************************************************************************
285  *                              mmsystemGetVersion      [WINMM.134]
286  */
287 UINT32 WINAPI mmsystemGetVersion32()
288 {
289         return mmsystemGetVersion16();
290 }
291
292 /**************************************************************************
293  *                              mmsystemGetVersion      [MMSYSTEM.5]
294  * return value borrowed from Win95 winmm.dll ;)
295  */
296 UINT16 WINAPI mmsystemGetVersion16()
297 {
298         dprintf_mmsys(stddeb, "mmsystemGetVersion // 3.10 (Win95?)\n");
299         return 0x030a;
300 }
301
302 /**************************************************************************
303 *                               DriverProc      [MMSYSTEM.6]
304 */
305 LRESULT WINAPI DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
306                           DWORD dwParam1, DWORD dwParam2)
307 {
308         return DrvDefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
309 }
310
311 /**************************************************************************
312 *                               DriverCallback  [MMSYSTEM.31]
313 */
314 BOOL16 WINAPI DriverCallback(DWORD dwCallBack, UINT16 uFlags, HANDLE16 hDev, 
315                              WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
316 {
317         LPWAVEOPENDESC  lpDesc;
318
319         dprintf_mmsys(stddeb, "DriverCallback(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
320                 dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
321         switch(uFlags & DCB_TYPEMASK) {
322                 case DCB_NULL:
323                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_NULL !\n");
324                         break;
325                 case DCB_WINDOW:
326                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_WINDOW = %04lX handle = %04X!\n",dwCallBack,hDev);
327                         if (!IsWindow32(dwCallBack)) return FALSE;
328                         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDev);
329                         if (lpDesc == NULL) return FALSE;
330
331                         PostMessage16((HWND16)dwCallBack, wMsg, hDev, dwParam1);
332                         break;
333                 case DCB_TASK:
334                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_TASK !\n");
335                         return FALSE;
336                 case DCB_FUNCTION:
337                         dprintf_mmsys(stddeb, "DriverCallback() // CALLBACK_FUNCTION !\n");
338                         Callbacks->CallDriverCallback( (FARPROC16)dwCallBack,
339                                                        hDev, wMsg, dwUser,
340                                                        dwParam1, dwParam2 );
341                         break;
342                 }
343         return TRUE;
344 }
345
346 /**************************************************************************
347  *      Mixer devices. New to Win95
348  */
349 /**************************************************************************
350  * find out the real mixer ID depending on hmix (depends on dwFlags)
351  * FIXME: also fix dwInstance passing to mixMessage 
352  */
353 static UINT32 _get_mixerID_from_handle(HMIXEROBJ32 hmix,DWORD dwFlags) {
354         /* FIXME: Check dwFlags for MIXER_OBJECTF_xxxx entries and modify hmix 
355          * accordingly. For now we always use mixerdevice 0. 
356          */
357         return 0;
358 }
359 /**************************************************************************
360  *                              mixerGetNumDevs         [WINMM.108]
361  */
362 UINT32 WINAPI mixerGetNumDevs32() 
363 {
364         return mixerGetNumDevs16();
365 }
366
367 /**************************************************************************
368  *                              mixerGetNumDevs 
369  */
370 UINT16 WINAPI mixerGetNumDevs16() 
371 {
372         UINT16  count;
373
374         count = mixMessage(0,MXDM_GETNUMDEVS,0L,0L,0L);
375         dprintf_mmaux(stddeb,"mixerGetNumDevs returns %d\n",count);
376         return count;
377 }
378
379 /**************************************************************************
380  *                              mixerGetDevCapsW                [WINMM.102]
381  */
382 UINT32 WINAPI mixerGetDevCaps32W(UINT32 devid,LPMIXERCAPS32W mixcaps,UINT32 size) 
383 {
384         MIXERCAPS16     mic16;
385         UINT32  ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
386
387         mixcaps->wMid = mic16.wMid;
388         mixcaps->wPid = mic16.wPid;
389         mixcaps->vDriverVersion = mic16.vDriverVersion;
390         lstrcpyAtoW(mixcaps->szPname,mic16.szPname);
391         mixcaps->fdwSupport = mic16.fdwSupport;
392         mixcaps->cDestinations = mic16.cDestinations;
393         return ret;
394 }
395 /**************************************************************************
396  *                              mixerGetDevCaps         [WINMM.101]
397  */
398 UINT32 WINAPI mixerGetDevCaps32A(UINT32 devid,LPMIXERCAPS32A mixcaps,UINT32 size) 
399 {
400         MIXERCAPS16     mic16;
401         UINT32  ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
402
403         mixcaps->wMid = mic16.wMid;
404         mixcaps->wPid = mic16.wPid;
405         mixcaps->vDriverVersion = mic16.vDriverVersion;
406         strcpy(mixcaps->szPname,mic16.szPname);
407         mixcaps->fdwSupport = mic16.fdwSupport;
408         mixcaps->cDestinations = mic16.cDestinations;
409         return ret;
410 }
411
412 /**************************************************************************
413  *                              mixerGetDevCaps 
414  */
415 UINT16 WINAPI mixerGetDevCaps16(UINT16 devid,LPMIXERCAPS16 mixcaps,UINT16 size) 
416 {
417         fprintf(stderr,"mixerGetDevCaps!\n");
418         return mixMessage(devid,MXDM_GETDEVCAPS,0L,(DWORD)mixcaps,(DWORD)size);
419 }
420
421 /**************************************************************************
422  *                              mixerOpen               [WINMM.110]
423  */
424 UINT32 WINAPI mixerOpen32(LPHMIXER32 lphmix,UINT32 uDeviceID,DWORD dwCallback,
425 DWORD dwInstance,DWORD fdwOpen) 
426 {
427         HMIXER16        hmix16;
428         UINT32          ret;
429
430         fprintf(stderr,"mixerOpen32(%p,%d,%08lx,%08lx,%08lx)\n",
431                 lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen
432         );
433         ret = mixerOpen16(&hmix16,uDeviceID,dwCallback,dwInstance,fdwOpen);
434         if (lphmix) *lphmix = hmix16;
435         return ret;
436 }
437
438 /**************************************************************************
439  *                              mixerOpen
440  */
441 UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix,UINT16 uDeviceID,DWORD dwCallback,
442 DWORD dwInstance,DWORD fdwOpen) 
443 {
444         HMIXER16        hmix;
445         LPMIXEROPENDESC lpmod;
446         BOOL32          mapperflag = (uDeviceID==0);
447         DWORD           dwRet;
448
449         fprintf(stderr,"mixerOpen(%p,%d,%08lx,%08lx,%08lx)\n",
450                 lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen
451         );
452         hmix = USER_HEAP_ALLOC(sizeof(MIXEROPENDESC));
453         if (lphmix) *lphmix = hmix;
454         lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
455         lpmod->hmx = hmix;
456         lpmod->dwCallback = dwCallback;
457         lpmod->dwInstance = dwInstance;
458         if (uDeviceID >= MAXMIXERDRIVERS)
459                 uDeviceID = 0;
460         while(uDeviceID < MAXMIXERDRIVERS) {
461                 dwRet=mixMessage(uDeviceID,MXDM_OPEN,dwInstance,(DWORD)lpmod,fdwOpen);
462                 if (dwRet == MMSYSERR_NOERROR) break;
463                 if (!mapperflag) break;
464                 uDeviceID++;
465         }
466         lpmod->uDeviceID = uDeviceID;
467         return dwRet;
468 }
469
470 /**************************************************************************
471  *                              mixerClose              [WINMM.98]
472  */
473 UINT32 WINAPI mixerClose32(HMIXER32 hmix) {
474         return mixerClose16(hmix);
475 }
476
477 /**************************************************************************
478  *                              mixerClose
479  */
480 UINT16 WINAPI mixerClose16(HMIXER16 hmix) {
481         LPMIXEROPENDESC lpmod;
482
483         fprintf(stderr,"mixerClose(%04x)\n",hmix);
484         lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
485         return mixMessage(lpmod->uDeviceID,MXDM_CLOSE,lpmod->dwInstance,0L,0L);
486 }
487
488 /**************************************************************************
489  *                              mixerGetID              [WINMM.103]
490  */
491 UINT32 WINAPI mixerGetID32(HMIXEROBJ32 hmix,LPUINT32 lpid,DWORD fdwID) {
492         UINT16  xid;
493
494         UINT32  ret = mixerGetID16(hmix,&xid,fdwID);
495         if (*lpid) *lpid = xid;
496         return ret;
497 }
498
499 /**************************************************************************
500  *                              mixerGetID
501  */
502 UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix,LPUINT16 lpid,DWORD fdwID) {
503         fprintf(stderr,"mixerGetID(%04x)\n",hmix);
504         return _get_mixerID_from_handle(hmix,fdwID);
505 }
506
507 /**************************************************************************
508  *                              mixerGetControlDetailsA [WINMM.99]
509  */
510 UINT32 mixerGetControlDetails32A(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
511         fprintf(stderr,"mixerGetControlDetails(%04x,%p,%08lx),stub!\n",
512                 hmix,lpmcd,fdwDetails
513         );
514         return MMSYSERR_NOTENABLED;
515 }
516
517 /**************************************************************************
518  *                              mixerGetControlDetailsW [WINMM.100]
519  */
520 UINT32 mixerGetControlDetails32W(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
521         fprintf(stderr,"mixerGetControlDetails(%04x,%p,%08lx),stub!\n",
522                 hmix,lpmcd,fdwDetails
523         );
524         return MMSYSERR_NOTENABLED;
525 }
526
527 /**************************************************************************
528  *                              mixerGetControlDetails  [MMSYSTEM.808]
529  */
530 UINT16 mixerGetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) {
531         fprintf(stderr,"mixerGetControlDetails(%04x,%p,%08lx),stub!\n",
532                 hmix,lpmcd,fdwDetails
533         );
534         return MMSYSERR_NOTENABLED;
535 }
536
537 /**************************************************************************
538  *                              mixerGetLineControlsA   [WINMM.104]
539  */
540 UINT32 mixerGetLineControls32A(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32A lpmlc,DWORD fdwControls) {
541         fprintf(stderr,"mixerGetLineControlsA(%04x,%p,%08lx),stub!\n",
542                 hmix,lpmlc,fdwControls
543         );
544         return MMSYSERR_NOTENABLED;
545 }
546
547 /**************************************************************************
548  *                              mixerGetLineControlsW   [WINMM.105]
549  */
550 UINT32 mixerGetLineControls32W(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32W lpmlc,DWORD fdwControls) {
551         fprintf(stderr,"mixerGetLineControlsA(%04x,%p,%08lx),stub!\n",
552                 hmix,lpmlc,fdwControls
553         );
554         return MMSYSERR_NOTENABLED;
555 }
556
557 /**************************************************************************
558  *                              mixerGetLineControls    [MMSYSTEM.807]
559  */
560 UINT16 mixerGetLineControls16(HMIXEROBJ16 hmix,LPMIXERLINECONTROLS16 lpmlc,DWORD fdwControls) {
561         fprintf(stderr,"mixerGetLineControls(%04x,%p,%08lx),stub!\n",
562                 hmix,lpmlc,fdwControls
563         );
564         return MMSYSERR_NOTENABLED;
565 }
566
567 /**************************************************************************
568  *                              mixerGetLineInfoA       [WINMM.106]
569  */
570 UINT32 mixerGetLineInfo32A(HMIXEROBJ32 hmix,LPMIXERLINE32A lpml,DWORD fdwInfo) {
571         MIXERLINE16     ml16;
572         UINT32          ret;
573
574         ml16.dwDestination = lpml->dwDestination;
575         fprintf(stderr,"mixerGetLineInfoA(%04x,%p,%08lx),stub!\n",
576                 hmix,lpml,fdwInfo
577         );
578         ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
579         lpml->cbStruct = sizeof(*lpml);
580         lpml->dwSource = ml16.dwSource;
581         lpml->dwLineID = ml16.dwLineID;
582         lpml->fdwLine = ml16.fdwLine;
583         lpml->dwUser = ml16.dwUser;
584         lpml->dwComponentType = ml16.dwComponentType;
585         lpml->cChannels = ml16.cChannels;
586         lpml->cConnections = ml16.cConnections;
587         lpml->cControls = ml16.cControls;
588         strcpy(lpml->szShortName,ml16.szShortName);
589         strcpy(lpml->szName,ml16.szName);
590         lpml->Target.dwType = ml16.Target.dwType;
591         lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
592         lpml->Target.wMid = ml16.Target.wMid;
593         lpml->Target.wPid = ml16.Target.wPid;
594         lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
595         strcpy(lpml->Target.szPname,ml16.Target.szPname);
596         return ret;
597 }
598
599 /**************************************************************************
600  *                              mixerGetLineInfoW       [WINMM.107]
601  */
602 UINT32 mixerGetLineInfo32W(HMIXEROBJ32 hmix,LPMIXERLINE32W lpml,DWORD fdwInfo) {
603         MIXERLINE16     ml16;
604         UINT32          ret;
605
606         ml16.dwDestination = lpml->dwDestination;
607         fprintf(stderr,"mixerGetLineInfoW(%04x,%p,%08lx),stub!\n",
608                 hmix,lpml,fdwInfo
609         );
610         ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
611         lpml->cbStruct = sizeof(*lpml);
612         lpml->dwSource = ml16.dwSource;
613         lpml->dwLineID = ml16.dwLineID;
614         lpml->fdwLine = ml16.fdwLine;
615         lpml->dwUser = ml16.dwUser;
616         lpml->dwComponentType = ml16.dwComponentType;
617         lpml->cChannels = ml16.cChannels;
618         lpml->cConnections = ml16.cConnections;
619         lpml->cControls = ml16.cControls;
620         lstrcpyAtoW(lpml->szShortName,ml16.szShortName);
621         lstrcpyAtoW(lpml->szName,ml16.szName);
622         lpml->Target.dwType = ml16.Target.dwType;
623         lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
624         lpml->Target.wMid = ml16.Target.wMid;
625         lpml->Target.wPid = ml16.Target.wPid;
626         lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
627         /*lstrcpyAtoW(lpml->Target.szPname,ml16.Target.szPname);*/
628         return ret;
629 }
630
631 /**************************************************************************
632  *                              mixerGetLineInfo        [MMSYSTEM.805]
633  */
634 UINT16 mixerGetLineInfo16(HMIXEROBJ16 hmix,LPMIXERLINE16 lpml,DWORD fdwInfo) {
635         UINT16 devid =  _get_mixerID_from_handle(hmix,fdwInfo);
636
637         fprintf(stderr,"mixerGetLineInfo16(%04x,%p[line %08lx],%08lx)\n",
638                 hmix,lpml,lpml->dwDestination,fdwInfo
639         );
640         return mixMessage(devid,MXDM_GETLINEINFO,0,(DWORD)lpml,fdwInfo);
641 }
642
643 /**************************************************************************
644  *                              mixerSetControlDetails  [WINMM.111]
645  */
646 UINT32 mixerSetControlDetails32(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
647         fprintf(stderr,"mixerSetControlDetails32(%04x,%p,%08lx),stub!\n",
648                 hmix,lpmcd,fdwDetails
649         );
650         return MMSYSERR_NOTENABLED;
651 }
652
653 /**************************************************************************
654  *                              mixerSetControlDetails  [MMSYSTEM.809]
655  */
656 UINT16 mixerSetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) {
657         fprintf(stderr,"mixerSetControlDetails16(%04x,%p,%08lx),stub!\n",
658                 hmix,lpmcd,fdwDetails
659         );
660         return MMSYSERR_NOTENABLED;
661 }
662
663 /**************************************************************************
664  *                              mixerMessage            [WINMM.109]
665  */
666 UINT32 mixerMessage32(HMIXER32 hmix,UINT32 uMsg,DWORD dwParam1,DWORD dwParam2) {
667         LPMIXEROPENDESC lpmod;
668         UINT16  uDeviceID;
669
670         lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
671         if (lpmod)
672                 uDeviceID = lpmod->uDeviceID;
673         else
674                 uDeviceID = 0;
675         fprintf(stderr,"mixerMessage(%04lx,%d,%08lx,%08lx)\n",(DWORD)hmix,uMsg,dwParam1,dwParam2);
676         return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
677 }
678
679 /**************************************************************************
680  *                              mixerMessage            [MMSYSTEM.804]
681  */
682 UINT16 mixerMessage16(HMIXER16 hmix,UINT16 uMsg,DWORD dwParam1,DWORD dwParam2) {
683         LPMIXEROPENDESC lpmod;
684         UINT16  uDeviceID;
685
686         lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
687         if (lpmod)
688                 uDeviceID = lpmod->uDeviceID;
689         else
690                 uDeviceID = 0;
691         fprintf(stderr,"mixerMessage(%04x,%d,%08lx,%08lx)\n",hmix,uMsg,dwParam1,dwParam2);
692         return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
693 }
694
695 /**************************************************************************
696  *                              auxGetNumDevs           [WINMM.22]
697  */
698 UINT32 WINAPI auxGetNumDevs32()
699 {
700         return auxGetNumDevs16();
701 }
702
703 /**************************************************************************
704  *                              auxGetNumDevs           [MMSYSTEM.350]
705  */
706 UINT16 WINAPI auxGetNumDevs16()
707 {
708         UINT16  count = 0;
709         dprintf_mmsys(stddeb, "auxGetNumDevs !\n");
710         count += auxMessage(0, AUXDM_GETNUMDEVS, 0L, 0L, 0L);
711         dprintf_mmsys(stddeb, "auxGetNumDevs return %u \n", count);
712         return count;
713 }
714
715 /**************************************************************************
716  *                              auxGetDevCaps           [WINMM.20]
717  */
718 UINT32 WINAPI auxGetDevCaps32W(UINT32 uDeviceID,LPAUXCAPS32W lpCaps,UINT32 uSize)
719 {
720         AUXCAPS16       ac16;
721         UINT32  ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
722
723         lpCaps->wMid = ac16.wMid;
724         lpCaps->wPid = ac16.wPid;
725         lpCaps->vDriverVersion = ac16.vDriverVersion;
726         lstrcpyAtoW(lpCaps->szPname,ac16.szPname);
727         lpCaps->wTechnology = ac16.wTechnology;
728         lpCaps->dwSupport = ac16.dwSupport;
729         return ret;
730 }
731
732 /**************************************************************************
733  *                              auxGetDevCaps           [WINMM.21]
734  */
735 UINT32 WINAPI auxGetDevCaps32A(UINT32 uDeviceID,LPAUXCAPS32A lpCaps,UINT32 uSize)
736 {
737         AUXCAPS16       ac16;
738         UINT32  ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
739
740         lpCaps->wMid = ac16.wMid;
741         lpCaps->wPid = ac16.wPid;
742         lpCaps->vDriverVersion = ac16.vDriverVersion;
743         strcpy(lpCaps->szPname,ac16.szPname);
744         lpCaps->wTechnology = ac16.wTechnology;
745         lpCaps->dwSupport = ac16.dwSupport;
746         return ret;
747 }
748
749 /**************************************************************************
750  *                              auxGetDevCaps           [MMSYSTEM.351]
751  */
752 UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID,LPAUXCAPS16 lpCaps, UINT16 uSize)
753 {
754         dprintf_mmsys(stddeb, "auxGetDevCaps(%04X, %p, %d) !\n", 
755                                         uDeviceID, lpCaps, uSize);
756         return auxMessage(uDeviceID, AUXDM_GETDEVCAPS,
757                                 0L, (DWORD)lpCaps, (DWORD)uSize);
758 }
759
760 /**************************************************************************
761  *                              auxGetVolume            [WINM.23]
762  */
763 UINT32 WINAPI auxGetVolume32(UINT32 uDeviceID, DWORD * lpdwVolume)
764 {
765         return auxGetVolume16(uDeviceID,lpdwVolume);
766 }
767
768 /**************************************************************************
769  *                              auxGetVolume            [MMSYSTEM.352]
770  */
771 UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, DWORD * lpdwVolume)
772 {
773         dprintf_mmsys(stddeb, "auxGetVolume(%04X, %p) !\n", uDeviceID, lpdwVolume);
774         return auxMessage(uDeviceID, AUXDM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
775 }
776
777 /**************************************************************************
778  *                              auxSetVolume            [WINMM.25]
779  */
780 UINT32 WINAPI auxSetVolume32(UINT32 uDeviceID, DWORD dwVolume)
781 {
782         return auxSetVolume16(uDeviceID,dwVolume);
783 }
784
785 /**************************************************************************
786  *                              auxSetVolume            [MMSYSTEM.353]
787  */
788 UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
789 {
790         dprintf_mmsys(stddeb, "auxSetVolume(%04X, %08lX) !\n", uDeviceID, dwVolume);
791         return auxMessage(uDeviceID, AUXDM_SETVOLUME, 0L, dwVolume, 0L);
792 }
793
794 /**************************************************************************
795  *                              auxOutMessage           [MMSYSTEM.354]
796  */
797 DWORD WINAPI auxOutMessage32(UINT32 uDeviceID,UINT32 uMessage,DWORD dw1,DWORD dw2)
798 {
799         switch (uMessage) {
800         case AUXDM_GETNUMDEVS:
801         case AUXDM_GETVOLUME:
802         case AUXDM_SETVOLUME:
803                 /* no argument conversion needed */
804                 break;
805         case AUXDM_GETDEVCAPS:
806                 return auxGetDevCaps32A(uDeviceID,(LPAUXCAPS32A)dw1,dw2);
807         default:
808                 fprintf(stderr,"unhandled auxMessage32(%04x,%04x,%08lx,%08lx)\n",
809                         uDeviceID,uMessage,dw1,dw2
810                 );
811                 break;
812         }
813         return auxMessage(uDeviceID,uMessage,0L,dw1,dw2);
814 }
815
816 /**************************************************************************
817  *                              auxOutMessage           [MMSYSTEM.354]
818  */
819 DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
820 {
821         dprintf_mmsys(stddeb, "auxOutMessage(%04X, %04X, %08lX, %08lX)\n", 
822                                 uDeviceID, uMessage, dw1, dw2);
823         switch (uMessage) {
824         case AUXDM_GETNUMDEVS:
825         case AUXDM_SETVOLUME:
826                 /* no argument conversion needed */
827                 break;
828         case AUXDM_GETVOLUME:
829                 return auxGetVolume16(uDeviceID,(LPDWORD)PTR_SEG_TO_LIN(dw1));
830         case AUXDM_GETDEVCAPS:
831                 return auxGetDevCaps16(uDeviceID,(LPAUXCAPS16)PTR_SEG_TO_LIN(dw1),dw2);
832         default:
833                 fprintf(stderr,"unhandled auxMessage32(%04x,%04x,%08lx,%08lx)\n",
834                         uDeviceID,uMessage,dw1,dw2
835                 );
836                 break;
837         }
838         return auxMessage(uDeviceID, uMessage, 0L, dw1, dw2);
839 }
840
841 /**************************************************************************
842  *                              mciGetErrorStringW              [WINMM.46]
843  */
844 BOOL32 WINAPI mciGetErrorString32W(DWORD wError,LPWSTR lpstrBuffer,UINT32 uLength)
845 {
846         LPSTR   bufstr = HeapAlloc(GetProcessHeap(),0,uLength);
847         BOOL32  ret = mciGetErrorString32A(wError,bufstr,uLength);
848
849         lstrcpyAtoW(lpstrBuffer,bufstr);
850         HeapFree(GetProcessHeap(),0,bufstr);
851         return ret;
852 }
853
854 /**************************************************************************
855  *                              mciGetErrorStringA              [WINMM.45]
856  */
857 BOOL32 WINAPI mciGetErrorString32A(DWORD wError,LPSTR lpstrBuffer,UINT32 uLength)
858 {
859         return mciGetErrorString16(wError,lpstrBuffer,uLength);
860 }
861
862 /**************************************************************************
863  *                              mciGetErrorString               [MMSYSTEM.706]
864  */
865 BOOL16 WINAPI mciGetErrorString16(DWORD wError,LPSTR lpstrBuffer,UINT16 uLength)
866 {
867         LPSTR   msgptr;
868         dprintf_mmsys(stddeb, "mciGetErrorString(%08lX, %p, %d);\n", wError, lpstrBuffer, uLength);
869         if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE);
870         lpstrBuffer[0] = '\0';
871         switch(wError) {
872                 case MCIERR_INVALID_DEVICE_ID:
873                         msgptr = "Invalid MCI device ID. Use the ID returned when opening the MCI device.";
874                         break;
875                 case MCIERR_UNRECOGNIZED_KEYWORD:
876                         msgptr = "The driver cannot recognize the specified command parameter.";
877                         break;
878                 case MCIERR_UNRECOGNIZED_COMMAND:
879                         msgptr = "The driver cannot recognize the specified command.";
880                         break;
881                 case MCIERR_HARDWARE:
882                         msgptr = "There is a problem with your media device. Make sure it is working correctly or contact the device manufacturer.";
883                         break;
884                 case MCIERR_INVALID_DEVICE_NAME:
885                         msgptr = "The specified device is not open or is not recognized by MCI.";
886                         break;
887                 case MCIERR_OUT_OF_MEMORY:
888                         msgptr = "Not enough memory available for this task. \nQuit one or more applications to increase available memory, and then try again.";
889                         break;
890                 case MCIERR_DEVICE_OPEN:
891                         msgptr = "The device name is already being used as an alias by this application. Use a unique alias.";
892                         break;
893                 case MCIERR_CANNOT_LOAD_DRIVER:
894                         msgptr = "There is an undetectable problem in loading the specified device driver.";
895                         break;
896                 case MCIERR_MISSING_COMMAND_STRING:
897                         msgptr = "No command was specified.";
898                         break;
899                 case MCIERR_PARAM_OVERFLOW:
900                         msgptr = "The output string was to large to fit in the return buffer. Increase the size of the buffer.";
901                         break;
902                 case MCIERR_MISSING_STRING_ARGUMENT:
903                         msgptr = "The specified command requires a character-string parameter. Please provide one.";
904                         break;
905                 case MCIERR_BAD_INTEGER:
906                         msgptr = "The specified integer is invalid for this command.";
907                         break;
908                 case MCIERR_PARSER_INTERNAL:
909                         msgptr = "The device driver returned an invalid return type. Check with the device manufacturer about obtaining a new driver.";
910                         break;
911                 case MCIERR_DRIVER_INTERNAL:
912                         msgptr = "There is a problem with the device driver. Check with the device manufacturer about obtaining a new driver.";
913                         break;
914                 case MCIERR_MISSING_PARAMETER:
915                         msgptr = "The specified command requires a parameter. Please supply one.";
916                         break;
917                 case MCIERR_UNSUPPORTED_FUNCTION:
918                         msgptr = "The MCI device you are using does not support the specified command.";
919                         break;
920                 case MCIERR_FILE_NOT_FOUND:
921                         msgptr = "Cannot find the specified file. Make sure the path and filename are correct.";
922                         break;
923                 case MCIERR_DEVICE_NOT_READY:
924                         msgptr = "The device driver is not ready.";
925                         break;
926                 case MCIERR_INTERNAL:
927                         msgptr = "A problem occurred in initializing MCI. Try restarting Windows.";
928                         break;
929                 case MCIERR_DRIVER:
930                         msgptr = "There is a problem with the device driver. The driver has closed. Cannot access error.";
931                         break;
932                 case MCIERR_CANNOT_USE_ALL:
933                         msgptr = "Cannot use 'all' as the device name with the specified command.";
934                         break;
935                 case MCIERR_MULTIPLE:
936                         msgptr = "Errors occurred in more than one device. Specify each command and device separately to determine which devices caused the error";
937                         break;
938                 case MCIERR_EXTENSION_NOT_FOUND:
939                         msgptr = "Cannot determine the device type from the given filename extension.";
940                         break;
941                 case MCIERR_OUTOFRANGE:
942                         msgptr = "The specified parameter is out of range for the specified command.";
943                         break;
944                 case MCIERR_FLAGS_NOT_COMPATIBLE:
945                         msgptr = "The specified parameters cannot be used together.";
946                         break;
947                 case MCIERR_FILE_NOT_SAVED:
948                         msgptr = "Cannot save the specified file. Make sure you have enough disk space or are still connected to the network.";
949                         break;
950                 case MCIERR_DEVICE_TYPE_REQUIRED:
951                         msgptr = "Cannot find the specified device. Make sure it is installed or that the device name is spelled correctly.";
952                         break;
953                 case MCIERR_DEVICE_LOCKED:
954                         msgptr = "The specified device is now being closed. Wait a few seconds, and then try again.";
955                         break;
956                 case MCIERR_DUPLICATE_ALIAS:
957                         msgptr = "The specified alias is already being used in this application. Use a unique alias.";
958                         break;
959                 case MCIERR_BAD_CONSTANT:
960                         msgptr = "The specified parameter is invalid for this command.";
961                         break;
962                 case MCIERR_MUST_USE_SHAREABLE:
963                         msgptr = "The device driver is already in use. To share it, use the 'shareable' parameter with each 'open' command.";
964                         break;
965                 case MCIERR_MISSING_DEVICE_NAME:
966                         msgptr = "The specified command requires an alias, file, driver, or device name. Please supply one.";
967                         break;
968                 case MCIERR_BAD_TIME_FORMAT:
969                         msgptr = "The specified value for the time format is invalid. Refer to the MCI documentation for valid formats.";
970                         break;
971                 case MCIERR_NO_CLOSING_QUOTE:
972                         msgptr = "A closing double-quotation mark is missing from the parameter value. Please supply one.";
973                         break;
974                 case MCIERR_DUPLICATE_FLAGS:
975                         msgptr = "A parameter or value was specified twice. Only specify it once.";
976                         break;
977                 case MCIERR_INVALID_FILE:
978                         msgptr = "The specified file cannot be played on the specified MCI device. The file may be corrupt, or not in the correct format.";
979                         break;
980                 case MCIERR_NULL_PARAMETER_BLOCK:
981                         msgptr = "A null parameter block was passed to MCI.";
982                         break;
983                 case MCIERR_UNNAMED_RESOURCE:
984                         msgptr = "Cannot save an unnamed file. Supply a filename.";
985                         break;
986                 case MCIERR_NEW_REQUIRES_ALIAS:
987                         msgptr = "You must specify an alias when using the 'new' parameter.";
988                         break;
989                 case MCIERR_NOTIFY_ON_AUTO_OPEN:
990                         msgptr = "Cannot use the 'notify' flag with auto-opened devices.";
991                         break;
992                 case MCIERR_NO_ELEMENT_ALLOWED:
993                         msgptr = "Cannot use a filename with the specified device.";
994                         break;
995                 case MCIERR_NONAPPLICABLE_FUNCTION:
996                         msgptr = "Cannot carry out the commands in the order specified. Correct the command sequence, and then try again.";
997                         break;
998                 case MCIERR_ILLEGAL_FOR_AUTO_OPEN:
999                         msgptr = "Cannot carry out the specified command on an auto-opened device. Wait until the device is closed, and then try again.";
1000                         break;
1001                 case MCIERR_FILENAME_REQUIRED:
1002                         msgptr = "The filename is invalid. Make sure the filename is not longer than 8 characters, followed by a period and an extension.";
1003                         break;
1004                 case MCIERR_EXTRA_CHARACTERS:
1005                         msgptr = "Cannot specify extra characters after a string enclosed in quotation marks.";
1006                         break;
1007                 case MCIERR_DEVICE_NOT_INSTALLED:
1008                         msgptr = "The specified device is not installed on the system. Use the Drivers option in Control Panel to install the device.";
1009                         break;
1010                 case MCIERR_GET_CD:
1011                         msgptr = "Cannot access the specified file or MCI device. Try changing directories or restarting your computer.";
1012                         break;
1013                 case MCIERR_SET_CD:
1014                         msgptr = "Cannot access the specified file or MCI device because the application cannot change directories.";
1015                         break;
1016                 case MCIERR_SET_DRIVE:
1017                         msgptr = "Cannot access specified file or MCI device because the application cannot change drives.";
1018                         break;
1019                 case MCIERR_DEVICE_LENGTH:
1020                         msgptr = "Specify a device or driver name that is less than 79 characters.";
1021                         break;
1022                 case MCIERR_DEVICE_ORD_LENGTH:
1023                         msgptr = "Specify a device or driver name that is less than 69 characters.";
1024                         break;
1025                 case MCIERR_NO_INTEGER:
1026                         msgptr = "The specified command requires an integer parameter. Please provide one.";
1027                         break;
1028                 case MCIERR_WAVE_OUTPUTSINUSE:
1029                         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.";
1030                         break;
1031                 case MCIERR_WAVE_SETOUTPUTINUSE:
1032                         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.";
1033                         break;
1034                 case MCIERR_WAVE_INPUTSINUSE:
1035                         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.";
1036                         break;
1037                 case MCIERR_WAVE_SETINPUTINUSE:
1038                         msgptr = "Cannot set the current wave device for recording because it is in use. Wait until the device is free, and then try again.";
1039                         break;
1040                 case MCIERR_WAVE_OUTPUTUNSPECIFIED:
1041                         msgptr = "Any compatible waveform playback device may be used.";
1042                         break;
1043                 case MCIERR_WAVE_INPUTUNSPECIFIED:
1044                         msgptr = "Any compatible waveform recording device may be used.";
1045                         break;
1046                 case MCIERR_WAVE_OUTPUTSUNSUITABLE:
1047                         msgptr = "No wave device that can play files in the current format is installed. Use the Drivers option to install the wave device.";
1048                         break;
1049                 case MCIERR_WAVE_SETOUTPUTUNSUITABLE:
1050                         msgptr = "The device you are trying to play to cannot recognize the current file format.";
1051                         break;
1052                 case MCIERR_WAVE_INPUTSUNSUITABLE:
1053                         msgptr = "No wave device that can record files in the current format is installed. Use the Drivers option to install the wave device.";
1054                         break;
1055                 case MCIERR_WAVE_SETINPUTUNSUITABLE:
1056                         msgptr = "The device you are trying to record from cannot recognize the current file format.";
1057                         break;
1058                 case MCIERR_NO_WINDOW:
1059                         msgptr = "There is no display window.";
1060                         break;
1061                 case MCIERR_CREATEWINDOW:
1062                         msgptr = "Could not create or use window.";
1063                         break;
1064                 case MCIERR_FILE_READ:
1065                         msgptr = "Cannot read the specified file. Make sure the file is still present, or check your disk or network connection.";
1066                         break;
1067                 case MCIERR_FILE_WRITE:
1068                         msgptr = "Cannot write to the specified file. Make sure you have enough disk space or are still connected to the network.";
1069                         break;
1070                 case MCIERR_SEQ_DIV_INCOMPATIBLE:
1071                         msgptr = "The time formats of the \"song pointer\" and SMPTE are mutually exclusive. You can't use them together.";
1072                         break;
1073                 case MCIERR_SEQ_NOMIDIPRESENT:
1074                         msgptr = "The system has no installed MIDI devices. Use the Drivers option from the Control Panel to install a MIDI driver.";
1075                         break;
1076                 case MCIERR_SEQ_PORT_INUSE:
1077                         msgptr = "The specified MIDI port is already in use. Wait until it is free; the try again.";
1078                         break;
1079                 case MCIERR_SEQ_PORT_MAPNODEVICE:
1080                         msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use the MIDI Mapper option from the Control Panel to edit the setup.";
1081                         break;
1082                 case MCIERR_SEQ_PORT_MISCERROR:
1083                         msgptr = "An error occurred with the specified port.";
1084                         break;
1085                 case MCIERR_SEQ_PORT_NONEXISTENT:
1086                         msgptr = "The specified MIDI device is not installed on the system. Use the Drivers option from the Control Panel to install a MIDI device.";
1087                         break;
1088                 case MCIERR_SEQ_PORTUNSPECIFIED:
1089                         msgptr = "The system doesnot have a current MIDI port specified.";
1090                         break;
1091                 case MCIERR_SEQ_TIMER:
1092                         msgptr = "All multimedia timers are being used by other applications. Quit one of these applications; then, try again.";
1093                         break;
1094
1095 /* 
1096 msg# 513 : vcr
1097 msg# 514 : videodisc
1098 msg# 515 : overlay
1099 msg# 516 : cdaudio
1100 msg# 517 : dat
1101 msg# 518 : scanner
1102 msg# 519 : animation
1103 msg# 520 : digitalvideo
1104 msg# 521 : other
1105 msg# 522 : waveaudio
1106 msg# 523 : sequencer
1107 msg# 524 : not ready
1108 msg# 525 : stopped
1109 msg# 526 : playing
1110 msg# 527 : recording
1111 msg# 528 : seeking
1112 msg# 529 : paused
1113 msg# 530 : open
1114 msg# 531 : false
1115 msg# 532 : true
1116 msg# 533 : milliseconds
1117 msg# 534 : hms
1118 msg# 535 : msf
1119 msg# 536 : frames
1120 msg# 537 : smpte 24
1121 msg# 538 : smpte 25
1122 msg# 539 : smpte 30
1123 msg# 540 : smpte 30 drop
1124 msg# 541 : bytes
1125 msg# 542 : samples
1126 msg# 543 : tmsf
1127 */
1128                 default:
1129                         msgptr = "Unknown MCI Error !\n";
1130                         break;
1131         }
1132         lstrcpyn32A(lpstrBuffer, msgptr, uLength);
1133         dprintf_mmsys(stddeb, "mciGetErrorString // msg = %s;\n", msgptr);
1134         return TRUE;
1135 }
1136
1137
1138 /**************************************************************************
1139  *                              mciDriverNotify                 [MMSYSTEM.711]
1140  */
1141 BOOL16 WINAPI mciDriverNotify(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
1142 {
1143         dprintf_mmsys(stddeb, "mciDriverNotify(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
1144         if (!IsWindow32(hWndCallBack)) return FALSE;
1145         dprintf_mmsys(stddeb, "mciDriverNotify // before PostMessage\n");
1146         PostMessage16( hWndCallBack, MM_MCINOTIFY, wStatus, 
1147                        MAKELONG(wDevID, 0));
1148         return TRUE;
1149 }
1150
1151 /**************************************************************************
1152  *                      mciOpen                                 [internal]
1153  */
1154
1155 DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms)
1156 {
1157         char    str[128];
1158         LPMCI_OPEN_PARMS16 lpParms;
1159         UINT16  uDevTyp = 0;
1160         UINT16  wDevID = MMSYSTEM_FirstDevID();
1161         DWORD dwret;
1162
1163         lpParms = PTR_SEG_TO_LIN(lp16Parms);
1164         dprintf_mmsys(stddeb, "mciOpen(%08lX, %p (%p))\n", dwParam, lp16Parms, lpParms);
1165         if (lp16Parms == NULL) return MCIERR_INTERNAL;
1166
1167         while(GetDrv(wDevID)->wType != 0) {
1168                 wDevID = MMSYSTEM_NextDevID(wDevID);
1169                 if (!MMSYSTEM_DevIDValid(wDevID)) {
1170                         dprintf_mmsys(stddeb, "MCI_OPEN // MAXMCIDRIVERS reached !\n");
1171                         return MCIERR_INTERNAL;
1172                 }
1173         }
1174         dprintf_mmsys(stddeb, "mciOpen // wDevID=%04X \n", wDevID);
1175         memcpy(GetOpenDrv(wDevID),lpParms,sizeof(*lpParms));
1176
1177         if (dwParam & MCI_OPEN_ELEMENT) {
1178                 char    *s,*t;
1179
1180                 dprintf_mmsys(stddeb,"mciOpen // lpstrElementName='%s'\n",
1181                         (char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName)
1182                 );
1183                 s=(char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
1184                 t=strrchr(s,'.');
1185                 if (t) {
1186                         GetProfileString32A("mci extensions",t+1,"*",str,sizeof(str));
1187                         CharUpper32A(str);
1188                         dprintf_mmsys(stddeb, "mciOpen // str = %s \n", str);
1189                         if (strcmp(str, "CDAUDIO") == 0) {
1190                                 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
1191                         } else
1192                         if (strcmp(str, "WAVEAUDIO") == 0) {
1193                                 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
1194                         } else
1195                         if (strcmp(str, "SEQUENCER") == 0)      {
1196                                 uDevTyp = MCI_DEVTYPE_SEQUENCER;
1197                         } else
1198                         if (strcmp(str, "ANIMATION1") == 0) {
1199                                 uDevTyp = MCI_DEVTYPE_ANIMATION;
1200                         } else
1201                         if (strcmp(str, "AVIVIDEO") == 0) {
1202                                 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
1203                         } else 
1204                         if (strcmp(str,"*") == 0) {
1205                                 dprintf_mmsys(stddeb,"No [mci extensions] entry for %s found.\n",t);
1206                                 return MCIERR_EXTENSION_NOT_FOUND;
1207                         } else  {
1208                                 dprintf_mmsys(stddeb,"[mci extensions] entry %s for %s not supported.\n",str,t);
1209                         }
1210                 } else
1211                         return MCIERR_EXTENSION_NOT_FOUND;
1212         }
1213
1214         if (dwParam & MCI_OPEN_ALIAS) {
1215                 dprintf_mmsys(stddeb, "MCI_OPEN // Alias='%s' !\n",
1216                         (char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
1217                 GetOpenDrv(wDevID)->lpstrAlias = (LPSTR)SEGPTR_GET(
1218                     SEGPTR_STRDUP((char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias)));
1219                 /* mplayer does allocate alias to CDAUDIO */
1220         }
1221         if (dwParam & MCI_OPEN_TYPE) {
1222                 if (dwParam & MCI_OPEN_TYPE_ID) {
1223                         dprintf_mmsys(stddeb, "MCI_OPEN // Dev=%08lx!\n", (DWORD)lpParms->lpstrDeviceType);
1224                         uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
1225                         GetOpenDrv(wDevID)->lpstrDeviceType=(LPSTR)lpParms->lpstrDeviceType;
1226                 } else {
1227                         if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
1228                         dprintf_mmsys(stddeb, "MCI_OPEN // Dev='%s' !\n",
1229                               (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
1230                         GetOpenDrv(wDevID)->lpstrDeviceType=(LPSTR)SEGPTR_GET(
1231               SEGPTR_STRDUP((char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType)));
1232                         strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
1233                         CharUpper32A(str);
1234                         if (strcmp(str, "CDAUDIO") == 0) {
1235                                 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
1236                         } else
1237                         if (strcmp(str, "WAVEAUDIO") == 0) {
1238                                 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
1239                         } else
1240                         if (strcmp(str, "SEQUENCER") == 0)      {
1241                                 uDevTyp = MCI_DEVTYPE_SEQUENCER;
1242                         } else
1243                         if (strcmp(str, "ANIMATION1") == 0) {
1244                                 uDevTyp = MCI_DEVTYPE_ANIMATION;
1245                         } else
1246                         if (strcmp(str, "AVIVIDEO") == 0) {
1247                                 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
1248                         }
1249                 }
1250         }
1251         GetDrv(wDevID)->wType = uDevTyp;
1252         GetDrv(wDevID)->wDeviceID = 0;  /* FIXME? for multiple devices */
1253         lpParms->wDeviceID = wDevID;
1254         dprintf_mmsys(stddeb, "MCI_OPEN // mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n", 
1255                                 wDevID, uDevTyp, lpParms->wDeviceID);
1256         switch(uDevTyp)
1257         {
1258         case MCI_DEVTYPE_CD_AUDIO:
1259           dwret = CDAUDIO_DriverProc( 0, 0, MCI_OPEN_DRIVER,
1260                                      dwParam, (DWORD)lp16Parms);
1261           break;
1262         case MCI_DEVTYPE_WAVEFORM_AUDIO:
1263           dwret =  WAVE_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
1264                                    dwParam, (DWORD)lp16Parms);
1265           break;
1266         case MCI_DEVTYPE_SEQUENCER:
1267           dwret = MIDI_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
1268                                   dwParam, (DWORD)lp16Parms);
1269           break;
1270         case MCI_DEVTYPE_ANIMATION:
1271           dwret = ANIM_DriverProc( 0, 0, MCI_OPEN_DRIVER, 
1272                                   dwParam, (DWORD)lp16Parms);
1273           break;
1274         case MCI_DEVTYPE_DIGITAL_VIDEO:
1275           dprintf_mmsys(stddeb, "MCI_OPEN // No DIGITAL_VIDEO yet !\n");
1276           return MCIERR_DEVICE_NOT_INSTALLED;
1277         default:
1278           dprintf_mmsys(stddeb, "MCI_OPEN // Invalid Device Name '%08lx' !\n", (DWORD)lpParms->lpstrDeviceType);
1279           return MCIERR_INVALID_DEVICE_NAME;
1280         }
1281
1282
1283         if (dwParam&MCI_NOTIFY)
1284           mciDriverNotify(lpParms->dwCallback,wDevID,
1285                           (dwret==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
1286
1287         /* only handled devices fall through */
1288         dprintf_mmsys(stddeb, "MCI_OPEN // wDevID = %04X wDeviceID = %d dwret = %ld\n",wDevID, lpParms->wDeviceID, dwret);
1289         return dwret;
1290 }
1291
1292
1293 /**************************************************************************
1294 *                               mciClose                                [internal]
1295 */
1296 DWORD mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
1297 {
1298         DWORD   dwRet = MCIERR_INTERNAL;
1299
1300         dprintf_mmsys(stddeb, "mciClose(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
1301         switch(GetDrv(wDevID)->wType) {
1302                 case MCI_DEVTYPE_CD_AUDIO:
1303                         dwRet = CDAUDIO_DriverProc(GetDrv(wDevID)->wDeviceID,0,
1304                                            MCI_CLOSE, dwParam, (DWORD)lpParms);
1305                         break;
1306                 case MCI_DEVTYPE_WAVEFORM_AUDIO:
1307                         dwRet = WAVE_DriverProc(GetDrv(wDevID)->wDeviceID, 0, 
1308                                                 MCI_CLOSE, dwParam,
1309                                                 (DWORD)lpParms);
1310                         break;
1311                 case MCI_DEVTYPE_SEQUENCER:
1312                         dwRet = MIDI_DriverProc(GetDrv(wDevID)->wDeviceID, 0, 
1313                                                 MCI_CLOSE, dwParam,
1314                                                 (DWORD)lpParms);
1315                         break;
1316                 case MCI_DEVTYPE_ANIMATION:
1317                         dwRet = ANIM_DriverProc(GetDrv(wDevID)->wDeviceID, 0, 
1318                                                 MCI_CLOSE, dwParam,
1319                                                 (DWORD)lpParms);
1320                         break;
1321                 default:
1322                         dprintf_mmsys(stddeb, "mciClose() // unknown device type=%04X !\n", GetDrv(wDevID)->wType);
1323                         dwRet = MCIERR_DEVICE_NOT_INSTALLED;
1324                 }
1325         GetDrv(wDevID)->wType = 0;
1326
1327         if (dwParam&MCI_NOTIFY)
1328           mciDriverNotify(lpParms->dwCallback,wDevID,
1329                           (dwRet==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
1330
1331         dprintf_mmsys(stddeb, "mciClose() // returns %ld\n",dwRet);
1332         return dwRet;
1333 }
1334
1335
1336 /**************************************************************************
1337 *                       mciSysinfo                              [internal]
1338 */
1339 DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS16 lpParms)
1340 {
1341         int     len;
1342         LPSTR   ptr;
1343         LPSTR   lpstrReturn;
1344         DWORD   *lpdwRet;
1345         LPSTR   SysFile = "SYSTEM.INI";
1346         dprintf_mci(stddeb, "mciSysInfo(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
1347         lpstrReturn = PTR_SEG_TO_LIN(lpParms->lpstrReturn);
1348         switch(dwFlags) {
1349         case MCI_SYSINFO_QUANTITY:
1350                 dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_QUANTITY \n");
1351                 lpdwRet = (DWORD *)lpstrReturn;
1352                 *(lpdwRet) = InstalledCount;
1353                 return 0;
1354         case MCI_SYSINFO_INSTALLNAME:
1355                 dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_INSTALLNAME \n");
1356                 if (lpInstallNames == NULL) {
1357                         InstalledCount = 0;
1358                         InstalledListLen = 0;
1359                         ptr = lpInstallNames = xmalloc(2048);
1360                         GetPrivateProfileString32A("mci", NULL, "", lpInstallNames, 2000, SysFile);
1361                         while(strlen(ptr) > 0) {
1362                                 dprintf_mci(stddeb, "---> '%s' \n", ptr);
1363                                 len = strlen(ptr) + 1;
1364                                 ptr += len;
1365                                 InstalledListLen += len;
1366                                 InstalledCount++;
1367                         }
1368                 }
1369                 if (lpParms->dwRetSize < InstalledListLen)
1370                         lstrcpyn32A(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 1);
1371                 else
1372                         strcpy(lpstrReturn, lpInstallNames);
1373                 return 0;
1374         case MCI_SYSINFO_NAME:
1375                 dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_NAME \n");
1376                 return 0;
1377         case MCI_SYSINFO_OPEN:
1378                 dprintf_mci(stddeb, "mciSysInfo // MCI_SYSINFO_OPEN \n");
1379                 return 0;
1380         }
1381         return MMSYSERR_INVALPARAM;
1382 }
1383
1384 /**************************************************************************
1385  *                      mciSound                                [internal]
1386  *  not used anymore ??
1387
1388 DWORD mciSound(UINT16 wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
1389 {
1390         if (lpParms == NULL) return MCIERR_INTERNAL;
1391         if (dwParam & MCI_SOUND_NAME)
1392                 dprintf_mci(stddeb, "MCI_SOUND // file='%s' !\n", lpParms->lpstrSoundName);
1393         return MCIERR_INVALID_DEVICE_ID;
1394 }
1395  *
1396  */
1397
1398 static const char *_mciCommandToString(UINT16 wMsg)
1399 {
1400         static char buffer[100];
1401
1402 #define CASE(s) case (s): return #s
1403
1404         switch (wMsg) {
1405                 CASE(MCI_OPEN);
1406                 CASE(MCI_CLOSE);
1407                 CASE(MCI_ESCAPE);
1408                 CASE(MCI_PLAY);
1409                 CASE(MCI_SEEK);
1410                 CASE(MCI_STOP);
1411                 CASE(MCI_PAUSE);
1412                 CASE(MCI_INFO);
1413                 CASE(MCI_GETDEVCAPS);
1414                 CASE(MCI_SPIN);
1415                 CASE(MCI_SET);
1416                 CASE(MCI_STEP);
1417                 CASE(MCI_RECORD);
1418                 CASE(MCI_SYSINFO);
1419                 CASE(MCI_BREAK);
1420                 CASE(MCI_SAVE);
1421                 CASE(MCI_STATUS);
1422                 CASE(MCI_CUE);
1423                 CASE(MCI_REALIZE);
1424                 CASE(MCI_WINDOW);
1425                 CASE(MCI_PUT);
1426                 CASE(MCI_WHERE);
1427                 CASE(MCI_FREEZE);
1428                 CASE(MCI_UNFREEZE);
1429                 CASE(MCI_LOAD);
1430                 CASE(MCI_CUT);
1431                 CASE(MCI_COPY);
1432                 CASE(MCI_PASTE);
1433                 CASE(MCI_UPDATE);
1434                 CASE(MCI_RESUME);
1435                 CASE(MCI_DELETE);
1436                 default:
1437                         sprintf(buffer, "%04X", wMsg);
1438                         return buffer;
1439
1440         }
1441 }
1442
1443 /**************************************************************************
1444 *                               mciSendCommand                  [MMSYSTEM.701]
1445 */
1446 DWORD WINAPI mciSendCommand(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1,
1447                             DWORD dwParam2)
1448 {
1449     HDRVR16 hDrv = 0;
1450     dprintf_mci(stddeb, "mciSendCommand(%04X, %s, %08lX, %08lX)\n", 
1451                 wDevID, _mciCommandToString(wMsg), dwParam1, dwParam2);
1452     switch(wMsg)
1453     {
1454     case MCI_OPEN:
1455         return mciOpen(dwParam1, (LPMCI_OPEN_PARMS16)dwParam2);
1456     case MCI_CLOSE:
1457         return mciClose( wDevID, dwParam1,
1458                          (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1459     case MCI_SYSINFO:
1460         return mciSysInfo( dwParam1,
1461                            (LPMCI_SYSINFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
1462     default:
1463         switch(GetDrv(wDevID)->wType)
1464         {
1465         case MCI_DEVTYPE_CD_AUDIO:
1466             return CDAUDIO_DriverProc(GetDrv(wDevID)->wDeviceID, hDrv, 
1467                                       wMsg, dwParam1, dwParam2);
1468         case MCI_DEVTYPE_WAVEFORM_AUDIO:
1469             return WAVE_DriverProc(GetDrv(wDevID)->wDeviceID, hDrv, 
1470                                    wMsg, dwParam1, dwParam2);
1471         case MCI_DEVTYPE_SEQUENCER:
1472             return MIDI_DriverProc(GetDrv(wDevID)->wDeviceID, hDrv, 
1473                                    wMsg, dwParam1, dwParam2);
1474         case MCI_DEVTYPE_ANIMATION:
1475             return ANIM_DriverProc(GetDrv(wDevID)->wDeviceID, hDrv, 
1476                                    wMsg, dwParam1, dwParam2);
1477         default:
1478             dprintf_mci(stddeb,
1479                         "mciSendCommand() // unknown device type=%04X !\n", 
1480                         GetDrv(wDevID)->wType);
1481         }
1482     }
1483     return MMSYSERR_INVALPARAM;
1484 }
1485
1486 /**************************************************************************
1487 *                               mciGetDeviceID          [MMSYSTEM.703]
1488 */
1489 UINT16 WINAPI mciGetDeviceID (LPCSTR lpstrName)
1490 {
1491     UINT16 wDevID;
1492
1493     dprintf_mci(stddeb, "mciGetDeviceID(\"%s\")\n", lpstrName);
1494     if (lpstrName && !lstrcmpi32A(lpstrName, "ALL"))
1495         return MCI_ALL_DEVICE_ID;
1496
1497     if (!lpstrName)
1498         return 0;
1499
1500     wDevID = MMSYSTEM_FirstDevID();
1501     while(MMSYSTEM_DevIDValid(wDevID) && GetDrv(wDevID)->wType) {
1502         if (GetOpenDrv(wDevID)->lpstrDeviceType && 
1503             strcmp(PTR_SEG_TO_LIN(GetOpenDrv(wDevID)->lpstrDeviceType), lpstrName) == 0)
1504             return wDevID;
1505
1506         if (GetOpenDrv(wDevID)->lpstrAlias && 
1507             strcmp(PTR_SEG_TO_LIN(GetOpenDrv(wDevID)->lpstrAlias), lpstrName) == 0)
1508             return wDevID;
1509
1510         wDevID = MMSYSTEM_NextDevID(wDevID);
1511     }
1512
1513     return 0;
1514 }
1515
1516 /**************************************************************************
1517 *                               mciSetYieldProc         [MMSYSTEM.714]
1518 */
1519 BOOL16 WINAPI mciSetYieldProc (UINT16 uDeviceID, 
1520                                YIELDPROC fpYieldProc, DWORD dwYieldData)
1521 {
1522     return FALSE;
1523 }
1524
1525 /**************************************************************************
1526 *                               mciGetDeviceIDFromElementID     [MMSYSTEM.715]
1527 */
1528 UINT16 WINAPI mciGetDeviceIDFromElementID(DWORD dwElementID, LPCSTR lpstrType)
1529 {
1530     return 0;
1531 }
1532
1533 /**************************************************************************
1534 *                               mciGetYieldProc         [MMSYSTEM.716]
1535 */
1536 YIELDPROC WINAPI mciGetYieldProc(UINT16 uDeviceID, DWORD * lpdwYieldData)
1537 {
1538     return NULL;
1539 }
1540
1541 /**************************************************************************
1542 *                               mciGetCreatorTask       [MMSYSTEM.717]
1543 */
1544 HTASK16 WINAPI mciGetCreatorTask(UINT16 uDeviceID)
1545 {
1546     return 0;
1547 }
1548
1549 /**************************************************************************
1550  *                              midiOutGetNumDevs       [WINMM.80]
1551  */
1552 UINT32 WINAPI midiOutGetNumDevs32(void)
1553 {
1554         return midiOutGetNumDevs16();
1555 }
1556 /**************************************************************************
1557  *                              midiOutGetNumDevs       [MMSYSTEM.201]
1558  */
1559 UINT16 WINAPI midiOutGetNumDevs16(void)
1560 {
1561         UINT16  count = 0;
1562         dprintf_mmsys(stddeb, "midiOutGetNumDevs\n");
1563         count += modMessage(0, MODM_GETNUMDEVS, 0L, 0L, 0L);
1564         dprintf_mmsys(stddeb, "midiOutGetNumDevs return %u \n", count);
1565         return count;
1566 }
1567
1568 /**************************************************************************
1569  *                              midiOutGetDevCapsW      [WINMM.76]
1570  */
1571 UINT32 WINAPI midiOutGetDevCaps32W(UINT32 uDeviceID,LPMIDIOUTCAPS32W lpCaps, UINT32 uSize)
1572 {
1573         MIDIOUTCAPS16   moc16;
1574         UINT32          ret;
1575
1576         ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
1577         lpCaps->wMid            = moc16.wMid;
1578         lpCaps->wPid            = moc16.wPid;
1579         lpCaps->vDriverVersion  = moc16.vDriverVersion;
1580         lstrcpyAtoW(lpCaps->szPname,moc16.szPname);
1581         lpCaps->wTechnology     = moc16.wTechnology;
1582         lpCaps->wVoices         = moc16.wVoices;
1583         lpCaps->wNotes          = moc16.wNotes;
1584         lpCaps->wChannelMask    = moc16.wChannelMask;
1585         lpCaps->dwSupport       = moc16.dwSupport;
1586         return ret;
1587 }
1588 /**************************************************************************
1589  *                              midiOutGetDevCapsA      [WINMM.75]
1590  */
1591 UINT32 WINAPI midiOutGetDevCaps32A(UINT32 uDeviceID,LPMIDIOUTCAPS32A lpCaps, UINT32 uSize)
1592 {
1593         MIDIOUTCAPS16   moc16;
1594         UINT32          ret;
1595
1596         ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
1597         lpCaps->wMid            = moc16.wMid;
1598         lpCaps->wPid            = moc16.wPid;
1599         lpCaps->vDriverVersion  = moc16.vDriverVersion;
1600         strcpy(lpCaps->szPname,moc16.szPname);
1601         lpCaps->wTechnology     = moc16.wTechnology;
1602         lpCaps->wVoices         = moc16.wVoices;
1603         lpCaps->wNotes          = moc16.wNotes;
1604         lpCaps->wChannelMask    = moc16.wChannelMask;
1605         lpCaps->dwSupport       = moc16.dwSupport;
1606         return ret;
1607 }
1608
1609 /**************************************************************************
1610  *                              midiOutGetDevCaps       [MMSYSTEM.202]
1611  */
1612 UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID,LPMIDIOUTCAPS16 lpCaps, UINT16 uSize)
1613 {
1614         dprintf_mmsys(stddeb, "midiOutGetDevCaps\n");
1615         return modMessage(uDeviceID,MODM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);
1616 }
1617
1618 /**************************************************************************
1619  *                              midiOutGetErrorTextA    [WINMM.77]
1620  */
1621 UINT32 WINAPI midiOutGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
1622 {
1623         dprintf_mmsys(stddeb, "midiOutGetErrorText\n");
1624         return midiGetErrorText(uError, lpText, uSize);
1625 }
1626
1627 /**************************************************************************
1628  *                              midiOutGetErrorTextW    [WINMM.78]
1629  */
1630 UINT32 WINAPI midiOutGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
1631 {
1632         LPSTR   xstr = HeapAlloc(GetProcessHeap(),0,uSize);
1633         UINT32  ret;
1634         dprintf_mmsys(stddeb, "midiOutGetErrorText\n");
1635         ret = midiGetErrorText(uError, xstr, uSize);
1636         lstrcpyAtoW(lpText,xstr);
1637         HeapFree(GetProcessHeap(),0,xstr);
1638         return ret;
1639 }
1640 /**************************************************************************
1641  *                              midiOutGetErrorText     [MMSYSTEM.203]
1642  */
1643 UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
1644 {
1645         dprintf_mmsys(stddeb, "midiOutGetErrorText\n");
1646         return midiGetErrorText(uError, lpText, uSize);
1647 }
1648
1649 /**************************************************************************
1650  *                              midiGetErrorText        [internal]
1651  */
1652 UINT16 WINAPI midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
1653 {
1654         LPSTR   msgptr;
1655         if ((lpText == NULL) || (uSize < 1)) return(FALSE);
1656         lpText[0] = '\0';
1657         switch(uError) {
1658                 case MIDIERR_UNPREPARED:
1659                         msgptr = "The MIDI header was not prepared. Use the Prepare function to prepare the header, and then try again.";
1660                         break;
1661                 case MIDIERR_STILLPLAYING:
1662                         msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
1663                         break;
1664                 case MIDIERR_NOMAP:
1665                         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.";
1666                         break;
1667                 case MIDIERR_NOTREADY:
1668                         msgptr = "The port is transmitting data to the device. Wait until the data has been transmitted, and then try again.";
1669                         break;
1670                 case MIDIERR_NODEVICE:
1671                         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.";
1672                         break;
1673                 case MIDIERR_INVALIDSETUP:
1674                         msgptr = "The current MIDI setup is damaged. Copy the original MIDIMAP.CFG file to the Windows SYSTEM directory, and then try again.";
1675                         break;
1676 /*
1677 msg# 336 : Cannot use the song-pointer time format and the SMPTE time-format together.
1678 msg# 337 : The specified MIDI device is already in use. Wait until it is free, and then try again.
1679 msg# 338 : The specified MIDI device is not installed on the system. Use the Drivers option in Control Panel to install the driver.
1680 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.
1681 msg# 340 : An error occurred using the specified port.
1682 msg# 341 : All multimedia timers are being used by other applications. Quit one of these applications, and then try again.
1683 msg# 342 : There is no current MIDI port.
1684 msg# 343 : There are no MIDI devices installed on the system. Use the Drivers option in Control Panel to install the driver.
1685 */
1686                 default:
1687                         msgptr = "Unknown MIDI Error !\n";
1688                         break;
1689                 }
1690         lstrcpyn32A(lpText, msgptr, uSize);
1691         return TRUE;
1692 }
1693
1694 /**************************************************************************
1695  *                              midiOutOpen             [WINM.84]
1696  */
1697 UINT32 WINAPI midiOutOpen32(HMIDIOUT32 * lphMidiOut, UINT32 uDeviceID,
1698                             DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
1699 {
1700         HMIDIOUT16      hmo16;
1701         UINT32          ret;
1702
1703         ret = midiOutOpen16(&hmo16,uDeviceID,dwCallback,dwInstance,dwFlags);
1704         if (lphMidiOut) *lphMidiOut = hmo16;
1705         return ret;
1706 }
1707 /**************************************************************************
1708  *                              midiOutOpen             [MMSYSTEM.204]
1709  */
1710 UINT16 WINAPI midiOutOpen16(HMIDIOUT16 * lphMidiOut, UINT16 uDeviceID,
1711                             DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
1712 {
1713         HMIDI16 hMidiOut;
1714         LPMIDIOPENDESC  lpDesc;
1715         DWORD   dwRet = 0;
1716         BOOL32  bMapperFlg = FALSE;
1717         if (lphMidiOut != NULL) *lphMidiOut = 0;
1718         dprintf_mmsys(stddeb, "midiOutOpen(%p, %d, %08lX, %08lX, %08lX);\n", 
1719                 lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
1720         if (uDeviceID == (UINT16)MIDI_MAPPER) {
1721                 dprintf_mmsys(stddeb, "midiOutOpen      // MIDI_MAPPER mode requested !\n");
1722                 bMapperFlg = TRUE;
1723                 uDeviceID = 0;
1724         }
1725         hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
1726         if (lphMidiOut != NULL) *lphMidiOut = hMidiOut;
1727         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1728         if (lpDesc == NULL)
1729                 return MMSYSERR_NOMEM;
1730         lpDesc->hMidi = hMidiOut;
1731         lpDesc->dwCallback = dwCallback;
1732         lpDesc->dwInstance = dwInstance;
1733         while(uDeviceID < MAXMIDIDRIVERS) {
1734                 dwRet = modMessage(uDeviceID, MODM_OPEN, 
1735                         lpDesc->dwInstance, (DWORD)lpDesc, 0L);
1736                 if (dwRet == MMSYSERR_NOERROR) break;
1737                 if (!bMapperFlg) break;
1738                 uDeviceID++;
1739                 dprintf_mmsys(stddeb, "midiOutOpen      // MIDI_MAPPER mode ! try next driver...\n");
1740         }
1741         return dwRet;
1742 }
1743
1744 /**************************************************************************
1745  *                              midiOutClose            [WINMM.74]
1746  */
1747 UINT32 WINAPI midiOutClose32(HMIDIOUT32 hMidiOut)
1748 {
1749         return midiOutClose16(hMidiOut);
1750 }
1751
1752 /**************************************************************************
1753  *                              midiOutClose            [MMSYSTEM.205]
1754  */
1755 UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
1756 {
1757         LPMIDIOPENDESC  lpDesc;
1758         dprintf_mmsys(stddeb, "midiOutClose(%04X)\n", hMidiOut);
1759         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1760         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1761         return modMessage(0, MODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
1762 }
1763
1764 /**************************************************************************
1765  *                              midiOutPrepareHeader    [WINMM.85]
1766  */
1767 UINT32 WINAPI midiOutPrepareHeader32(HMIDIOUT32 hMidiOut,
1768                                      MIDIHDR * lpMidiOutHdr, UINT32 uSize)
1769 {
1770         return midiOutPrepareHeader16(hMidiOut,lpMidiOutHdr,uSize);
1771 }
1772
1773 /**************************************************************************
1774  *                              midiOutPrepareHeader    [MMSYSTEM.206]
1775  */
1776 UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut,
1777                                      MIDIHDR * lpMidiOutHdr, UINT16 uSize)
1778 {
1779         LPMIDIOPENDESC  lpDesc;
1780         dprintf_mmsys(stddeb, "midiOutPrepareHeader(%04X, %p, %d)\n", 
1781                                         hMidiOut, lpMidiOutHdr, uSize);
1782         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1783         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1784         return modMessage(0, MODM_PREPARE, lpDesc->dwInstance, 
1785                           (DWORD)lpMidiOutHdr, (DWORD)uSize);
1786 }
1787
1788 /**************************************************************************
1789  *                              midiOutUnprepareHeader  [WINMM.89]
1790  */
1791 UINT32 WINAPI midiOutUnprepareHeader32(HMIDIOUT32 hMidiOut,
1792                                        MIDIHDR * lpMidiOutHdr, UINT32 uSize)
1793 {
1794         return midiOutUnprepareHeader16(hMidiOut,lpMidiOutHdr,uSize);
1795 }
1796 /**************************************************************************
1797  *                              midiOutUnprepareHeader  [MMSYSTEM.207]
1798  */
1799 UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut,
1800                                      MIDIHDR * lpMidiOutHdr, UINT16 uSize)
1801 {
1802         LPMIDIOPENDESC  lpDesc;
1803         dprintf_mmsys(stddeb, "midiOutUnprepareHeader(%04X, %p, %d)\n", 
1804                                         hMidiOut, lpMidiOutHdr, uSize);
1805         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1806         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1807         return modMessage(0, MODM_UNPREPARE, lpDesc->dwInstance, 
1808                                                 (DWORD)lpMidiOutHdr, (DWORD)uSize);
1809 }
1810
1811 /**************************************************************************
1812  *                              midiOutShortMsg         [WINMM.88]
1813  */
1814 UINT32 WINAPI midiOutShortMsg32(HMIDIOUT32 hMidiOut, DWORD dwMsg)
1815 {
1816         return midiOutShortMsg16(hMidiOut,dwMsg);
1817 }
1818 /**************************************************************************
1819  *                              midiOutShortMsg         [MMSYSTEM.208]
1820  */
1821 UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
1822 {
1823         LPMIDIOPENDESC  lpDesc;
1824         dprintf_mmsys(stddeb, "midiOutShortMsg(%04X, %08lX)\n", hMidiOut, dwMsg);
1825         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1826         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1827         return modMessage(0, MODM_DATA, lpDesc->dwInstance, dwMsg, 0L);
1828 }
1829
1830 /**************************************************************************
1831  *                              midiOutLongMsg          [WINMM.82]
1832  */
1833 UINT32 WINAPI midiOutLongMsg32(HMIDIOUT32 hMidiOut,
1834                                MIDIHDR * lpMidiOutHdr, UINT32 uSize)
1835 {
1836         return midiOutLongMsg16(hMidiOut,lpMidiOutHdr,uSize);
1837 }
1838
1839 /**************************************************************************
1840  *                              midiOutLongMsg          [MMSYSTEM.209]
1841  */
1842 UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut,
1843                                MIDIHDR * lpMidiOutHdr, UINT16 uSize)
1844 {
1845         LPMIDIOPENDESC  lpDesc;
1846         dprintf_mmsys(stddeb, "midiOutLongMsg(%04X, %p, %d)\n", 
1847                                 hMidiOut, lpMidiOutHdr, uSize);
1848         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1849         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1850         return modMessage(0, MODM_LONGDATA, lpDesc->dwInstance, 
1851                                                 (DWORD)lpMidiOutHdr, (DWORD)uSize);
1852 }
1853
1854 /**************************************************************************
1855  *                              midiOutReset            [WINMM.86]
1856  */
1857 UINT32 WINAPI midiOutReset32(HMIDIOUT32 hMidiOut)
1858 {
1859         return midiOutReset16(hMidiOut);
1860 }
1861
1862 /**************************************************************************
1863  *                              midiOutReset            [MMSYSTEM.210]
1864  */
1865 UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
1866 {
1867         LPMIDIOPENDESC  lpDesc;
1868         dprintf_mmsys(stddeb, "midiOutReset(%04X)\n", hMidiOut);
1869         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1870         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1871         return modMessage(0, MODM_RESET, lpDesc->dwInstance, 0L, 0L);
1872 }
1873
1874 /**************************************************************************
1875  *                              midiOutGetVolume        [WINM.81]
1876  */
1877 UINT32 WINAPI midiOutGetVolume32(UINT32 uDeviceID, DWORD * lpdwVolume)
1878 {
1879         return midiOutGetVolume16(uDeviceID,lpdwVolume);
1880 }
1881 /**************************************************************************
1882  *                              midiOutGetVolume        [MMSYSTEM.211]
1883  */
1884 UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD * lpdwVolume)
1885 {
1886         dprintf_mmsys(stddeb, "midiOutGetVolume(%04X, %p);\n", uDeviceID, lpdwVolume);
1887         return modMessage(uDeviceID, MODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
1888 }
1889
1890 /**************************************************************************
1891  *                              midiOutSetVolume        [WINMM.87]
1892  */
1893 UINT32 WINAPI midiOutSetVolume32(UINT32 uDeviceID, DWORD dwVolume)
1894 {
1895         return midiOutSetVolume16(uDeviceID,dwVolume);
1896 }
1897
1898 /**************************************************************************
1899  *                              midiOutSetVolume        [MMSYSTEM.212]
1900  */
1901 UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
1902 {
1903         dprintf_mmsys(stddeb, "midiOutSetVolume(%04X, %08lX);\n", uDeviceID, dwVolume);
1904         return modMessage(uDeviceID, MODM_SETVOLUME, 0L, dwVolume, 0L);
1905 }
1906
1907 /**************************************************************************
1908  *                              midiOutCachePatches             [WINMM.73]
1909  */
1910 UINT32 WINAPI midiOutCachePatches32(HMIDIOUT32 hMidiOut, UINT32 uBank,
1911                                     WORD * lpwPatchArray, UINT32 uFlags)
1912 {
1913         return midiOutCachePatches16(hMidiOut,uBank,lpwPatchArray,uFlags);
1914 }
1915
1916 /**************************************************************************
1917  *                              midiOutCachePatches             [MMSYSTEM.213]
1918  */
1919 UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
1920                                     WORD * lpwPatchArray, UINT16 uFlags)
1921 {
1922         /* not really necessary to support this */
1923         fprintf(stdnimp, "midiOutCachePatches: not supported yet\n");
1924         return MMSYSERR_NOTSUPPORTED;
1925 }
1926
1927 /**************************************************************************
1928  *                              midiOutCacheDrumPatches [WINMM.72]
1929  */
1930 UINT32 WINAPI midiOutCacheDrumPatches32(HMIDIOUT32 hMidiOut, UINT32 uPatch,
1931                                         WORD * lpwKeyArray, UINT32 uFlags)
1932 {
1933         return midiOutCacheDrumPatches16(hMidiOut,uPatch,lpwKeyArray,uFlags);
1934 }
1935
1936 /**************************************************************************
1937  *                              midiOutCacheDrumPatches [MMSYSTEM.214]
1938  */
1939 UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
1940                                         WORD * lpwKeyArray, UINT16 uFlags)
1941 {
1942         fprintf(stdnimp, "midiOutCacheDrumPatchesi: not supported yet\n");
1943         return MMSYSERR_NOTSUPPORTED;
1944 }
1945
1946 /**************************************************************************
1947  *                              midiOutGetID            [WINMM.79]
1948  */
1949 UINT32 WINAPI midiOutGetID32(HMIDIOUT32 hMidiOut, UINT32 * lpuDeviceID)
1950 {
1951         UINT16  xid;
1952         UINT32  ret;
1953
1954         ret = midiOutGetID16(hMidiOut,&xid);
1955         *lpuDeviceID = xid;
1956         return ret;
1957 }
1958
1959 /**************************************************************************
1960  *                              midiOutGetID            [MMSYSTEM.215]
1961  */
1962 UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16 * lpuDeviceID)
1963 {
1964         dprintf_mmsys(stddeb, "midiOutGetID\n");
1965         return 0;
1966 }
1967
1968 /**************************************************************************
1969  *                              midiOutMessage          [WINMM.83]
1970  */
1971 DWORD WINAPI midiOutMessage32(HMIDIOUT32 hMidiOut, UINT32 uMessage, 
1972                               DWORD dwParam1, DWORD dwParam2)
1973 {
1974         LPMIDIOPENDESC  lpDesc;
1975
1976         dprintf_mmsys(stddeb, "midiOutMessage(%04X, %04X, %08lX, %08lX)\n", 
1977                         hMidiOut, uMessage, dwParam1, dwParam2);
1978         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
1979         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
1980         switch (uMessage) {
1981         case MODM_OPEN:
1982                 fprintf(stderr,"midiOutMessage32: can't handle MODM_OPEN!\n");
1983                 return 0;
1984         case MODM_GETDEVCAPS:
1985                 return midiOutGetDevCaps32A(hMidiOut,(LPMIDIOUTCAPS32A)dwParam1,dwParam2);
1986         case MODM_GETNUMDEVS:
1987         case MODM_RESET:
1988         case MODM_CLOSE:
1989         case MODM_GETVOLUME:
1990         case MODM_SETVOLUME:
1991         case MODM_LONGDATA:
1992         case MODM_PREPARE:
1993         case MODM_UNPREPARE:
1994                 /* no argument conversion needed */
1995                 break;
1996         default:
1997                 fprintf(stderr,"unhandled midiOutMessage32(%04x,%04x,%08lx,%08lx)\n",
1998                         hMidiOut,uMessage,dwParam1,dwParam2
1999                 );
2000                 break;
2001         }
2002         return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2003 }
2004
2005 /**************************************************************************
2006  *                              midiOutMessage          [MMSYSTEM.216]
2007  */
2008 DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage, 
2009                               DWORD dwParam1, DWORD dwParam2)
2010 {
2011         LPMIDIOPENDESC  lpDesc;
2012
2013         dprintf_mmsys(stddeb, "midiOutMessage(%04X, %04X, %08lX, %08lX)\n", 
2014                         hMidiOut, uMessage, dwParam1, dwParam2);
2015         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2016         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2017         switch (uMessage) {
2018         case MODM_OPEN:
2019                 fprintf(stderr,"midiOutMessage16: can't handle MODM_OPEN!\n");
2020                 return 0;
2021         case MODM_GETNUMDEVS:
2022         case MODM_RESET:
2023         case MODM_CLOSE:
2024         case MODM_SETVOLUME:
2025                 /* no argument conversion needed */
2026                 break;
2027         case MODM_GETVOLUME:
2028                 return midiOutGetVolume16(hMidiOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
2029         case MODM_LONGDATA:
2030                 return midiOutLongMsg16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2031         case MODM_PREPARE:
2032                 return midiOutPrepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2033         case MODM_UNPREPARE:
2034                 return midiOutUnprepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2035         default:
2036                 fprintf(stderr,"unhandled midiOutMessage16(%04x,%04x,%08lx,%08lx)\n",
2037                         hMidiOut,uMessage,dwParam1,dwParam2
2038                 );
2039                 break;
2040         }
2041         return modMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2042 }
2043
2044 /**************************************************************************
2045  *                              midiInGetNumDevs        [WINMM.64]
2046  */
2047 UINT32 WINAPI midiInGetNumDevs32(void)
2048 {
2049         return midiInGetNumDevs16();
2050 }
2051
2052 /**************************************************************************
2053  *                              midiInGetNumDevs        [MMSYSTEM.301]
2054  */
2055 UINT16 WINAPI midiInGetNumDevs16(void)
2056 {
2057         UINT16  count = 0;
2058         dprintf_mmsys(stddeb, "midiInGetNumDevs\n");
2059         count += midMessage(0, MIDM_GETNUMDEVS, 0L, 0L, 0L);
2060         dprintf_mmsys(stddeb, "midiInGetNumDevs return %u \n", count);
2061         return count;
2062 }
2063
2064 /**************************************************************************
2065  *                              midiInGetDevCaps        [WINMM.60]
2066  */
2067 UINT32 WINAPI midiInGetDevCaps32W(UINT32 uDeviceID,
2068                                   LPMIDIINCAPS32W lpCaps, UINT32 uSize)
2069 {
2070         MIDIINCAPS16    mic16;
2071         UINT32          ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
2072
2073         lpCaps->wMid = mic16.wMid;
2074         lpCaps->wPid = mic16.wPid;
2075         lpCaps->vDriverVersion = mic16.vDriverVersion;
2076         lstrcpyAtoW(lpCaps->szPname,mic16.szPname);
2077         lpCaps->dwSupport = mic16.dwSupport;
2078         return ret;
2079 }
2080
2081 /**************************************************************************
2082  *                              midiInGetDevCaps        [WINMM.59]
2083  */
2084 UINT32 WINAPI midiInGetDevCaps32A(UINT32 uDeviceID,
2085                                   LPMIDIINCAPS32A lpCaps, UINT32 uSize)
2086 {
2087         MIDIINCAPS16    mic16;
2088         UINT32          ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
2089
2090         lpCaps->wMid = mic16.wMid;
2091         lpCaps->wPid = mic16.wPid;
2092         lpCaps->vDriverVersion = mic16.vDriverVersion;
2093         strcpy(lpCaps->szPname,mic16.szPname);
2094         lpCaps->dwSupport = mic16.dwSupport;
2095         return ret;
2096 }
2097
2098 /**************************************************************************
2099  *                              midiInGetDevCaps        [MMSYSTEM.302]
2100  */
2101 UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID,
2102                                LPMIDIINCAPS16 lpCaps, UINT16 uSize)
2103 {
2104         dprintf_mmsys(stddeb, "midiInGetDevCaps\n");
2105         return midMessage(uDeviceID,MIDM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);;
2106 }
2107
2108 /**************************************************************************
2109  *                              midiInGetErrorText              [WINMM.62]
2110  */
2111 UINT32 WINAPI midiInGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
2112 {
2113         LPSTR   xstr = HeapAlloc(GetProcessHeap(),0,uSize);
2114         UINT32  ret = midiInGetErrorText16(uError,xstr,uSize);
2115         lstrcpyAtoW(lpText,xstr);
2116         HeapFree(GetProcessHeap(),0,xstr);
2117         return ret;
2118 }
2119 /**************************************************************************
2120  *                              midiInGetErrorText              [WINMM.61]
2121  */
2122 UINT32 WINAPI midiInGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
2123 {
2124         return midiInGetErrorText16(uError,lpText,uSize);
2125 }
2126
2127 /**************************************************************************
2128  *                              midiInGetErrorText              [MMSYSTEM.303]
2129  */
2130 UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
2131 {
2132         dprintf_mmsys(stddeb, "midiInGetErrorText\n");
2133         return (midiGetErrorText(uError, lpText, uSize));
2134 }
2135
2136 /**************************************************************************
2137  *                              midiInOpen              [WINMM.66]
2138  */
2139 UINT32 WINAPI midiInOpen32(HMIDIIN32 * lphMidiIn, UINT32 uDeviceID,
2140                            DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
2141 {
2142         HMIDIIN16       xhmid16;
2143         UINT32 ret = midiInOpen16(&xhmid16,uDeviceID,dwCallback,dwInstance,dwFlags);
2144         if (lphMidiIn) *lphMidiIn = xhmid16;
2145         return ret;
2146 }
2147
2148 /**************************************************************************
2149  *                              midiInOpen              [MMSYSTEM.304]
2150  */
2151 UINT16 WINAPI midiInOpen16(HMIDIIN16 * lphMidiIn, UINT16 uDeviceID,
2152                            DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
2153 {
2154         HMIDI16 hMidiIn;
2155         LPMIDIOPENDESC  lpDesc;
2156         DWORD   dwRet = 0;
2157         BOOL32  bMapperFlg = FALSE;
2158
2159         if (lphMidiIn != NULL) *lphMidiIn = 0;
2160         dprintf_mmsys(stddeb, "midiInOpen(%p, %d, %08lX, %08lX, %08lX);\n", 
2161                 lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
2162         if (uDeviceID == (UINT16)MIDI_MAPPER) {
2163                 dprintf_mmsys(stddeb, "midiInOpen       // MIDI_MAPPER mode requested !\n");
2164                 bMapperFlg = TRUE;
2165                 uDeviceID = 0;
2166         }
2167         hMidiIn = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
2168         if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
2169         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2170         if (lpDesc == NULL) return MMSYSERR_NOMEM;
2171         lpDesc->hMidi = hMidiIn;
2172         lpDesc->dwCallback = dwCallback;
2173         lpDesc->dwInstance = dwInstance;
2174         while(uDeviceID < MAXMIDIDRIVERS) {
2175                 dwRet = midMessage(uDeviceID, MIDM_OPEN, 
2176                         lpDesc->dwInstance, (DWORD)lpDesc, 0L);
2177                 if (dwRet == MMSYSERR_NOERROR) break;
2178                 if (!bMapperFlg) break;
2179                 uDeviceID++;
2180                 dprintf_mmsys(stddeb, "midiInOpen       // MIDI_MAPPER mode ! try next driver...\n");
2181         }
2182         return dwRet;
2183 }
2184
2185 /**************************************************************************
2186  *                              midiInClose             [WINMM.58]
2187  */
2188 UINT32 WINAPI midiInClose32(HMIDIIN32 hMidiIn)
2189 {
2190         return midiInClose16(hMidiIn);
2191 }
2192
2193 /**************************************************************************
2194  *                              midiInClose             [MMSYSTEM.305]
2195  */
2196 UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
2197 {
2198         LPMIDIOPENDESC  lpDesc;
2199         dprintf_mmsys(stddeb, "midiInClose(%04X)\n", hMidiIn);
2200         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2201         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2202         return midMessage(0, MIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
2203 }
2204
2205 /**************************************************************************
2206  *                              midiInPrepareHeader     [WINMM.67]
2207  */
2208 UINT32 WINAPI midiInPrepareHeader32(HMIDIIN32 hMidiIn,
2209                                     MIDIHDR * lpMidiInHdr, UINT32 uSize)
2210 {
2211         return midiInPrepareHeader16(hMidiIn,lpMidiInHdr,uSize);
2212 }
2213
2214 /**************************************************************************
2215  *                              midiInPrepareHeader     [MMSYSTEM.306]
2216  */
2217 UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn,
2218                                     MIDIHDR * lpMidiInHdr, UINT16 uSize)
2219 {
2220         LPMIDIOPENDESC  lpDesc;
2221         dprintf_mmsys(stddeb, "midiInPrepareHeader(%04X, %p, %d)\n", 
2222                                         hMidiIn, lpMidiInHdr, uSize);
2223         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2224         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2225         return midMessage(0, MIDM_PREPARE, lpDesc->dwInstance, 
2226                                                 (DWORD)lpMidiInHdr, (DWORD)uSize);
2227 }
2228
2229 /**************************************************************************
2230  *                              midiInUnprepareHeader   [WINMM.71]
2231  */
2232 UINT32 WINAPI midiInUnprepareHeader32(HMIDIIN32 hMidiIn,
2233                                       MIDIHDR * lpMidiInHdr, UINT32 uSize)
2234 {
2235         return midiInUnprepareHeader16(hMidiIn,lpMidiInHdr,uSize);
2236 }
2237
2238 /**************************************************************************
2239  *                              midiInUnprepareHeader   [MMSYSTEM.307]
2240  */
2241 UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn,
2242                                       MIDIHDR * lpMidiInHdr, UINT16 uSize)
2243 {
2244         LPMIDIOPENDESC  lpDesc;
2245         dprintf_mmsys(stddeb, "midiInUnprepareHeader(%04X, %p, %d)\n", 
2246                                         hMidiIn, lpMidiInHdr, uSize);
2247         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2248         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2249         return midMessage(0, MIDM_UNPREPARE, lpDesc->dwInstance, 
2250                                                 (DWORD)lpMidiInHdr, (DWORD)uSize);
2251 }
2252
2253 /**************************************************************************
2254  *                              midiInAddBuffer         [WINMM.57]
2255  */
2256 UINT32 WINAPI midiInAddBuffer32(HMIDIIN32 hMidiIn,
2257                                 MIDIHDR * lpMidiInHdr, UINT32 uSize)
2258 {
2259         return midiInAddBuffer16(hMidiIn,lpMidiInHdr,uSize);
2260 }
2261
2262 /**************************************************************************
2263  *                              midiInAddBuffer         [MMSYSTEM.308]
2264  */
2265 UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn,
2266                                 MIDIHDR * lpMidiInHdr, UINT16 uSize)
2267 {
2268         dprintf_mmsys(stddeb, "midiInAddBuffer\n");
2269         return 0;
2270 }
2271
2272 /**************************************************************************
2273  *                              midiInStart                     [WINMM.69]
2274  */
2275 UINT32 WINAPI midiInStart32(HMIDIIN32 hMidiIn)
2276 {
2277         return midiInStart16(hMidiIn);
2278 }
2279
2280 /**************************************************************************
2281  *                              midiInStart                     [MMSYSTEM.309]
2282  */
2283 UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
2284 {
2285         dprintf_mmsys(stddeb, "midiInStart\n");
2286         return 0;
2287 }
2288
2289 /**************************************************************************
2290  *                              midiInStop                      [WINMM.70]
2291  */
2292 UINT32 WINAPI midiInStop32(HMIDIIN32 hMidiIn)
2293 {
2294         return midiInStop16(hMidiIn);
2295 }
2296
2297 /**************************************************************************
2298  *                              midiInStop                      [MMSYSTEM.310]
2299  */
2300 UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
2301 {
2302         dprintf_mmsys(stddeb, "midiInStop\n");
2303         return 0;
2304 }
2305
2306 /**************************************************************************
2307  *                              midiInReset                     [WINMM.68]
2308  */
2309 UINT32 WINAPI midiInReset32(HMIDIIN32 hMidiIn)
2310 {
2311         return midiInReset16(hMidiIn);
2312 }
2313
2314 /**************************************************************************
2315  *                              midiInReset                     [MMSYSTEM.311]
2316  */
2317 UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
2318 {
2319         dprintf_mmsys(stddeb, "midiInReset\n");
2320         return 0;
2321 }
2322
2323 /**************************************************************************
2324  *                              midiInGetID                     [WINMM.63]
2325  */
2326 UINT32 WINAPI midiInGetID32(HMIDIIN32 hMidiIn, UINT32 * lpuDeviceID)
2327 {
2328         dprintf_mmsys(stddeb, "midiInGetID\n");
2329         return 0;
2330 }
2331
2332 /**************************************************************************
2333  *                              midiInGetID                     [MMSYSTEM.312]
2334  */
2335 UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16 * lpuDeviceID)
2336 {
2337         dprintf_mmsys(stddeb, "midiInGetID\n");
2338         return 0;
2339 }
2340
2341 /**************************************************************************
2342  *                              midiInMessage           [WINMM.65]
2343  */
2344 DWORD WINAPI midiInMessage32(HMIDIIN32 hMidiIn, UINT32 uMessage, 
2345                              DWORD dwParam1, DWORD dwParam2)
2346 {
2347         LPMIDIOPENDESC  lpDesc;
2348         dprintf_mmsys(stddeb, "midiInMessage(%04X, %04X, %08lX, %08lX)\n", 
2349                         hMidiIn, uMessage, dwParam1, dwParam2);
2350         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2351         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2352         switch (uMessage) {
2353         case MIDM_OPEN:
2354                 fprintf(stderr,"midiInMessage32: can't handle MIDM_OPEN!\n");
2355                 return 0;
2356         case MIDM_GETDEVCAPS:
2357                 return midiInGetDevCaps32A(hMidiIn,(LPMIDIINCAPS32A)dwParam1,dwParam2);
2358         case MIDM_GETNUMDEVS:
2359         case MIDM_RESET:
2360         case MIDM_STOP:
2361         case MIDM_START:
2362         case MIDM_CLOSE:
2363                 /* no argument conversion needed */
2364                 break;
2365         case MIDM_PREPARE:
2366                 return midiInPrepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
2367         case MIDM_UNPREPARE:
2368                 return midiInUnprepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
2369         case MIDM_ADDBUFFER:
2370                 return midiInAddBuffer32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
2371         default:
2372                 fprintf(stderr,"unhandled midiInMessage32(%04x,%04x,%08lx,%08lx)\n",
2373                         hMidiIn,uMessage,dwParam1,dwParam2
2374                 );
2375                 break;
2376         }
2377         return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2378 }
2379
2380 /**************************************************************************
2381  *                              midiInMessage           [MMSYSTEM.313]
2382  */
2383 DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage, 
2384                              DWORD dwParam1, DWORD dwParam2)
2385 {
2386         LPMIDIOPENDESC  lpDesc;
2387         dprintf_mmsys(stddeb, "midiInMessage(%04X, %04X, %08lX, %08lX)\n", 
2388                         hMidiIn, uMessage, dwParam1, dwParam2);
2389         lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2390         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2391         switch (uMessage) {
2392         case MIDM_OPEN:
2393                 fprintf(stderr,"midiInMessage16: can't handle MIDM_OPEN!\n");
2394                 return 0;
2395         case MIDM_GETDEVCAPS:
2396                 return midiInGetDevCaps16(hMidiIn,(LPMIDIINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2397         case MIDM_GETNUMDEVS:
2398         case MIDM_RESET:
2399         case MIDM_STOP:
2400         case MIDM_START:
2401         case MIDM_CLOSE:
2402                 /* no argument conversion needed */
2403                 break;
2404         case MIDM_PREPARE:
2405                 return midiInPrepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2406         case MIDM_UNPREPARE:
2407                 return midiInUnprepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2408         case MIDM_ADDBUFFER:
2409                 return midiInAddBuffer16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2410         default:
2411                 fprintf(stderr,"unhandled midiInMessage16(%04x,%04x,%08lx,%08lx)\n",
2412                         hMidiIn,uMessage,dwParam1,dwParam2
2413                 );
2414                 break;
2415         }
2416         return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2417 }
2418
2419
2420 /**************************************************************************
2421  *                              waveOutGetNumDevs               [MMSYSTEM.401]
2422  */
2423 UINT32 WINAPI waveOutGetNumDevs32() {
2424         return waveOutGetNumDevs16();
2425 }
2426
2427 /**************************************************************************
2428  *                              waveOutGetNumDevs               [WINMM.167]
2429  */
2430 UINT16 WINAPI waveOutGetNumDevs16()
2431 {
2432         UINT16  count = 0;
2433         dprintf_mmsys(stddeb, "waveOutGetNumDevs\n");
2434         count += wodMessage( MMSYSTEM_FirstDevID(), WODM_GETNUMDEVS, 0L, 0L, 0L);
2435         dprintf_mmsys(stddeb, "waveOutGetNumDevs return %u \n", count);
2436         return count;
2437 }
2438
2439 /**************************************************************************
2440  *                              waveOutGetDevCaps               [MMSYSTEM.402]
2441  */
2442 UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID, WAVEOUTCAPS16 * lpCaps,
2443                                 UINT16 uSize)
2444 {
2445         if (uDeviceID > waveOutGetNumDevs16() - 1) return MMSYSERR_BADDEVICEID;
2446         if (uDeviceID == (UINT16)WAVE_MAPPER) return MMSYSERR_BADDEVICEID; /* FIXME: do we have a wave mapper ? */
2447         dprintf_mmsys(stddeb, "waveOutGetDevCaps\n");
2448         return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
2449 }
2450
2451 /**************************************************************************
2452  *                              waveOutGetDevCapsA              [WINMM.162]
2453  */
2454 UINT32 WINAPI waveOutGetDevCaps32A(UINT32 uDeviceID, LPWAVEOUTCAPS32A lpCaps,
2455                                 UINT32 uSize)
2456 {
2457         WAVEOUTCAPS16   woc16;
2458         UINT16 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
2459         
2460         lpCaps->wMid = woc16.wMid;
2461         lpCaps->wPid = woc16.wPid;
2462         lpCaps->vDriverVersion = woc16.vDriverVersion;
2463         strcpy(lpCaps->szPname,woc16.szPname);
2464         lpCaps->dwFormats = woc16.dwFormats;
2465         lpCaps->wChannels = woc16.wChannels;
2466         lpCaps->dwSupport = woc16.dwSupport;
2467         return ret;
2468 }
2469
2470 /**************************************************************************
2471  *                              waveOutGetDevCapsW              [WINMM.163]
2472  */
2473 UINT32 WINAPI waveOutGetDevCaps32W(UINT32 uDeviceID, LPWAVEOUTCAPS32W lpCaps,
2474                                 UINT32 uSize)
2475 {
2476         WAVEOUTCAPS16   woc16;
2477         UINT32 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
2478
2479         lpCaps->wMid = woc16.wMid;
2480         lpCaps->wPid = woc16.wPid;
2481         lpCaps->vDriverVersion = woc16.vDriverVersion;
2482         lstrcpyAtoW(lpCaps->szPname,woc16.szPname);
2483         lpCaps->dwFormats = woc16.dwFormats;
2484         lpCaps->wChannels = woc16.wChannels;
2485         lpCaps->dwSupport = woc16.dwSupport;
2486         return ret;
2487 }
2488
2489 /**************************************************************************
2490  *                              waveOutGetErrorText     [MMSYSTEM.403]
2491  */
2492 UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
2493 {
2494         dprintf_mmsys(stddeb, "waveOutGetErrorText\n");
2495         return(waveGetErrorText(uError, lpText, uSize));
2496 }
2497
2498 /**************************************************************************
2499  *                              waveOutGetErrorTextA    [WINMM.164]
2500  */
2501 UINT32 WINAPI waveOutGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
2502 {
2503         return(waveOutGetErrorText16(uError, lpText, uSize));
2504 }
2505
2506 /**************************************************************************
2507  *                              waveOutGetErrorTextW    [WINMM.165]
2508  */
2509 UINT32 WINAPI waveOutGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
2510 {
2511         LPSTR   xstr = HeapAlloc(GetProcessHeap(),0,uSize);
2512         UINT32  ret = waveOutGetErrorText32A(uError, xstr, uSize);
2513         
2514         lstrcpyAtoW(lpText,xstr);
2515         HeapFree(GetProcessHeap(),0,xstr);
2516         return ret;
2517 }
2518
2519
2520 /**************************************************************************
2521  *                              waveGetErrorText                [internal]
2522  */
2523 static UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
2524 {
2525         LPSTR   msgptr;
2526         dprintf_mmsys(stddeb, "waveGetErrorText(%04X, %p, %d);\n", uError, lpText, uSize);
2527         if ((lpText == NULL) || (uSize < 1)) return(FALSE);
2528         lpText[0] = '\0';
2529         switch(uError) {
2530                 case MMSYSERR_NOERROR:
2531                         msgptr = "The specified command was carried out.";
2532                         break;
2533                 case MMSYSERR_ERROR:
2534                         msgptr = "Undefined external error.";
2535                         break;
2536                 case MMSYSERR_BADDEVICEID:
2537                         msgptr = "A device ID has been used that is out of range for your system.";
2538                         break;
2539                 case MMSYSERR_NOTENABLED:
2540                         msgptr = "The driver was not enabled.";
2541                         break;
2542                 case MMSYSERR_ALLOCATED:
2543                         msgptr = "The specified device is already in use. Wait until it is free, and then try again.";
2544                         break;
2545                 case MMSYSERR_INVALHANDLE:
2546                         msgptr = "The specified device handle is invalid.";
2547                         break;
2548                 case MMSYSERR_NODRIVER:
2549                         msgptr = "There is no driver installed on your system !\n";
2550                         break;
2551                 case MMSYSERR_NOMEM:
2552                         msgptr = "Not enough memory available for this task. Quit one or more applications to increase available memory, and then try again.";
2553                         break;
2554                 case MMSYSERR_NOTSUPPORTED:
2555                         msgptr = "This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports.";
2556                         break;
2557                 case MMSYSERR_BADERRNUM:
2558                         msgptr = "An error number was specified that is not defined in the system.";
2559                         break;
2560                 case MMSYSERR_INVALFLAG:
2561                         msgptr = "An invalid flag was passed to a system function.";
2562                         break;
2563                 case MMSYSERR_INVALPARAM:
2564                         msgptr = "An invalid parameter was passed to a system function.";
2565                         break;
2566                 case WAVERR_BADFORMAT:
2567                         msgptr = "The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats";
2568                         break;
2569                 case WAVERR_STILLPLAYING:
2570                         msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
2571                         break;
2572                 case WAVERR_UNPREPARED:
2573                         msgptr = "The wave header was not prepared. Use the Prepare function to prepare the header, and then try again.";
2574                         break;
2575                 case WAVERR_SYNC:
2576                         msgptr = "Cannot open the device without using the WAVE_ALLOWSYNC flag. Use the flag, and then try again.";
2577                         break;
2578                 default:
2579                         msgptr = "Unknown MMSYSTEM Error !\n";
2580                         break;
2581                 }
2582         lstrcpyn32A(lpText, msgptr, uSize);
2583         return TRUE;
2584 }
2585
2586 /**************************************************************************
2587  *                      waveOutOpen                     [WINMM.173]
2588  * All the args/structs have the same layout as the win16 equivalents
2589  */
2590 UINT32 WINAPI waveOutOpen32(HWAVEOUT32 * lphWaveOut, UINT32 uDeviceID,
2591                             const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
2592                             DWORD dwInstance, DWORD dwFlags)
2593 {
2594         HWAVEOUT16      hwo16;
2595         UINT32  ret=waveOutOpen16(&hwo16,uDeviceID,lpFormat,dwCallback,dwInstance,dwFlags);
2596         if (lphWaveOut) *lphWaveOut=hwo16;
2597         return ret;
2598 }
2599 /**************************************************************************
2600  *                      waveOutOpen                     [MMSYSTEM.404]
2601  */
2602 UINT16 WINAPI waveOutOpen16(HWAVEOUT16 * lphWaveOut, UINT16 uDeviceID,
2603                             const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
2604                             DWORD dwInstance, DWORD dwFlags)
2605 {
2606         HWAVEOUT16      hWaveOut;
2607         LPWAVEOPENDESC  lpDesc;
2608         DWORD           dwRet = 0;
2609         BOOL32          bMapperFlg = FALSE;
2610
2611         dprintf_mmsys(stddeb, "waveOutOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
2612                 lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
2613         if (dwFlags & WAVE_FORMAT_QUERY)
2614                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_FORMAT_QUERY requested !\n");
2615         if (uDeviceID == (UINT16)WAVE_MAPPER) {
2616                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_MAPPER mode requested !\n");
2617                 bMapperFlg = TRUE;
2618                 uDeviceID = 0;
2619         }
2620         if (lpFormat == NULL) return WAVERR_BADFORMAT;
2621
2622         hWaveOut = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
2623         if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
2624         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2625         if (lpDesc == NULL) return MMSYSERR_NOMEM;
2626         lpDesc->hWave = hWaveOut;
2627         lpDesc->lpFormat = (LPWAVEFORMAT)lpFormat;  /* should the struct be copied iso pointer? */
2628         lpDesc->dwCallBack = dwCallback;
2629         lpDesc->dwInstance = dwInstance;
2630         if (uDeviceID >= MAXWAVEDRIVERS)
2631                 uDeviceID = 0;
2632         while(uDeviceID < MAXWAVEDRIVERS) {
2633                 dwRet = wodMessage(uDeviceID, WODM_OPEN, 
2634                         lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
2635                 if (dwRet == MMSYSERR_NOERROR) break;
2636                 if (!bMapperFlg) break;
2637                 uDeviceID++;
2638                 dprintf_mmsys(stddeb, "waveOutOpen      // WAVE_MAPPER mode ! try next driver...\n");
2639         }
2640         lpDesc->uDeviceID = uDeviceID;  /* save physical Device ID */
2641         if (dwFlags & WAVE_FORMAT_QUERY) {
2642                 dprintf_mmsys(stddeb, "waveOutOpen      // End of WAVE_FORMAT_QUERY !\n");
2643                 dwRet = waveOutClose32(hWaveOut);
2644         }
2645         return dwRet;
2646 }
2647
2648 /**************************************************************************
2649  *                              waveOutClose            [WINMM.161]
2650  */
2651 UINT32 WINAPI waveOutClose32(HWAVEOUT32 hWaveOut)
2652 {
2653         return waveOutClose16(hWaveOut);
2654 }
2655 /**************************************************************************
2656  *                              waveOutClose            [MMSYSTEM.405]
2657  */
2658 UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
2659 {
2660         LPWAVEOPENDESC  lpDesc;
2661
2662         dprintf_mmsys(stddeb, "waveOutClose(%04X)\n", hWaveOut);
2663         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2664         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2665         return wodMessage( lpDesc->uDeviceID, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
2666 }
2667
2668 /**************************************************************************
2669  *                              waveOutPrepareHeader    [WINMM.175]
2670  */
2671 UINT32 WINAPI waveOutPrepareHeader32(HWAVEOUT32 hWaveOut,
2672                                    WAVEHDR * lpWaveOutHdr, UINT32 uSize)
2673 {
2674         LPWAVEOPENDESC  lpDesc;
2675
2676         dprintf_mmsys(stddeb, "waveOutPrepareHeader(%04X, %p, %u);\n", 
2677                                         hWaveOut, lpWaveOutHdr, uSize);
2678         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2679         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2680         return wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance, 
2681                            (DWORD)lpWaveOutHdr,uSize);
2682 }
2683 /**************************************************************************
2684  *                              waveOutPrepareHeader    [MMSYSTEM.406]
2685  */
2686 UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut,
2687                                      WAVEHDR * lpWaveOutHdr, UINT16 uSize)
2688 {
2689         LPWAVEOPENDESC  lpDesc;
2690         LPBYTE          saveddata = lpWaveOutHdr->lpData;
2691         UINT16          ret;
2692
2693         dprintf_mmsys(stddeb, "waveOutPrepareHeader(%04X, %p, %u);\n", 
2694                                         hWaveOut, lpWaveOutHdr, uSize);
2695         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2696         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2697         lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
2698         ret = wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance, 
2699                            (DWORD)lpWaveOutHdr,uSize);
2700         lpWaveOutHdr->lpData = saveddata;
2701         return ret;
2702 }
2703
2704 /**************************************************************************
2705  *                              waveOutUnprepareHeader  [WINMM.181]
2706  */
2707 UINT32 WINAPI waveOutUnprepareHeader32(HWAVEOUT32 hWaveOut,
2708                                        WAVEHDR * lpWaveOutHdr, UINT32 uSize)
2709 {
2710         LPWAVEOPENDESC  lpDesc;
2711
2712         dprintf_mmsys(stddeb, "waveOutUnprepareHeader(%04X, %p, %u);\n", 
2713                                                 hWaveOut, lpWaveOutHdr, uSize);
2714         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2715         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2716         return wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance, 
2717                                         (DWORD)lpWaveOutHdr, uSize);
2718 }
2719 /**************************************************************************
2720  *                              waveOutUnprepareHeader  [MMSYSTEM.407]
2721  */
2722 UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut,
2723                                      WAVEHDR * lpWaveOutHdr, UINT16 uSize)
2724 {
2725         LPWAVEOPENDESC  lpDesc;
2726         LPBYTE          saveddata = lpWaveOutHdr->lpData;
2727         UINT16          ret;
2728
2729         dprintf_mmsys(stddeb, "waveOutUnprepareHeader(%04X, %p, %u);\n", 
2730                                                 hWaveOut, lpWaveOutHdr, uSize);
2731         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2732         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2733         lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
2734         ret = wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance, 
2735                           (DWORD)lpWaveOutHdr, uSize);
2736         lpWaveOutHdr->lpData = saveddata;
2737         return ret;
2738 }
2739
2740 /**************************************************************************
2741  *                              waveOutWrite            [MMSYSTEM.408]
2742  */
2743 UINT32 WINAPI waveOutWrite32(HWAVEOUT32 hWaveOut, WAVEHDR * lpWaveOutHdr,
2744                              UINT32 uSize)
2745 {
2746         LPWAVEOPENDESC  lpDesc;
2747         dprintf_mmsys(stddeb, "waveOutWrite(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2748         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2749         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2750         lpWaveOutHdr->reserved = (DWORD)lpWaveOutHdr->lpData;
2751         return wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
2752 }
2753 /**************************************************************************
2754  *                              waveOutWrite            [MMSYSTEM.408]
2755  */
2756 UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, WAVEHDR * lpWaveOutHdr,
2757                            UINT16 uSize)
2758 {
2759         LPWAVEOPENDESC  lpDesc;
2760         UINT16          ret;
2761
2762         dprintf_mmsys(stddeb, "waveOutWrite(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2763         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2764         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2765         lpWaveOutHdr->reserved=(DWORD)lpWaveOutHdr->lpData;/*save original ptr*/
2766         lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
2767         ret = wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
2768         lpWaveOutHdr->lpData = (LPBYTE)lpWaveOutHdr->reserved;
2769         return ret;
2770 }
2771
2772 /**************************************************************************
2773  *                              waveOutPause            [WINMM.174]
2774  */
2775 UINT32 WINAPI waveOutPause32(HWAVEOUT32 hWaveOut)
2776 {
2777         return waveOutPause16(hWaveOut);
2778 }
2779
2780 /**************************************************************************
2781  *                              waveOutPause            [MMSYSTEM.409]
2782  */
2783 UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut)
2784 {
2785         LPWAVEOPENDESC  lpDesc;
2786
2787         dprintf_mmsys(stddeb, "waveOutPause(%04X)\n", hWaveOut);
2788         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2789         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2790         return wodMessage( lpDesc->uDeviceID, WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
2791 }
2792
2793 /**************************************************************************
2794  *                              waveOutRestart          [WINMM.177]
2795  */
2796 UINT32 WINAPI waveOutRestart32(HWAVEOUT32 hWaveOut)
2797 {
2798         return waveOutRestart16(hWaveOut);
2799 }
2800 /**************************************************************************
2801  *                              waveOutRestart          [MMSYSTEM.410]
2802  */
2803 UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut)
2804 {
2805         LPWAVEOPENDESC  lpDesc;
2806
2807         dprintf_mmsys(stddeb, "waveOutRestart(%04X)\n", hWaveOut);
2808         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2809         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2810         return wodMessage( lpDesc->uDeviceID, WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
2811 }
2812
2813 /**************************************************************************
2814  *                              waveOutReset            [WINMM.176]
2815  */
2816 UINT32 WINAPI waveOutReset32(HWAVEOUT32 hWaveOut)
2817 {
2818         return waveOutReset16(hWaveOut);
2819 }
2820
2821 /**************************************************************************
2822  *                              waveOutReset            [MMSYSTEM.411]
2823  */
2824 UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut)
2825 {
2826         LPWAVEOPENDESC  lpDesc;
2827         dprintf_mmsys(stddeb, "waveOutReset(%04X)\n", hWaveOut);
2828         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2829         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2830         return wodMessage( lpDesc->uDeviceID, WODM_RESET, lpDesc->dwInstance, 0L, 0L);
2831 }
2832
2833 /**************************************************************************
2834  *                              waveOutGetPosition      [WINMM.170]
2835  */
2836 UINT32 WINAPI waveOutGetPosition32(HWAVEOUT32 hWaveOut, LPMMTIME32 lpTime,
2837                                    UINT32 uSize)
2838 {
2839         MMTIME16        mmt16;
2840         UINT32 ret = waveOutGetPosition16(hWaveOut,&mmt16,sizeof(mmt16));
2841         MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
2842         return ret;
2843 }
2844 /**************************************************************************
2845  *                              waveOutGetPosition      [MMSYSTEM.412]
2846  */
2847 UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut,LPMMTIME16 lpTime,
2848                                    UINT16 uSize)
2849 {
2850         LPWAVEOPENDESC  lpDesc;
2851         dprintf_mmsys(stddeb, "waveOutGetPosition(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
2852         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2853         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2854         return wodMessage( lpDesc->uDeviceID, WODM_GETPOS, lpDesc->dwInstance, 
2855                                                         (DWORD)lpTime, (DWORD)uSize);
2856 }
2857
2858 #define WAVEOUT_SHORTCUT_1(xx,XX,atype) \
2859         UINT32 WINAPI waveOut##xx##32(HWAVEOUT32 hWaveOut, atype x)     \
2860 {                                                                       \
2861         return waveOut##xx##16(hWaveOut,x);                             \
2862 }                                                                       \
2863 UINT16 WINAPI waveOut##xx##16(HWAVEOUT16 hWaveOut, atype x)             \
2864 {                                                                       \
2865         LPWAVEOPENDESC  lpDesc;                                         \
2866         dprintf_mmsys(stddeb, "waveOut"#xx"(%04X, %08lx);\n", hWaveOut,(DWORD)x);\
2867         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);         \
2868         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;                \
2869         return wodMessage(lpDesc->uDeviceID, WODM_##XX, lpDesc->dwInstance,\
2870                           (DWORD)x, 0L);                                \
2871 }
2872
2873 WAVEOUT_SHORTCUT_1(GetPitch,GETPITCH,DWORD*)
2874 WAVEOUT_SHORTCUT_1(SetPitch,SETPITCH,DWORD)
2875 WAVEOUT_SHORTCUT_1(GetPlaybackRate,GETPLAYBACKRATE,DWORD*)
2876 WAVEOUT_SHORTCUT_1(SetPlaybackRate,SETPLAYBACKRATE,DWORD)
2877
2878 #define WAVEOUT_SHORTCUT_2(xx,XX,atype) \
2879         UINT32 WINAPI waveOut##xx##32(UINT32 devid, atype x)            \
2880 {                                                                       \
2881         return waveOut##xx##16(devid,x);                                \
2882 }                                                                       \
2883 UINT16 WINAPI waveOut##xx##16(UINT16 devid, atype x)                    \
2884 {                                                                       \
2885         dprintf_mmsys(stddeb, "waveOut"#xx"(%04X, %08lx);\n", devid,(DWORD)x);  \
2886         return wodMessage(devid, WODM_##XX, 0L, (DWORD)x, 0L);          \
2887 }
2888         
2889
2890 WAVEOUT_SHORTCUT_2(GetVolume,GETVOLUME,DWORD*)
2891 WAVEOUT_SHORTCUT_2(SetVolume,SETVOLUME,DWORD)
2892
2893
2894 /**************************************************************************
2895  *                              waveOutBreakLoop        [MMSYSTEM.419]
2896  */
2897 UINT32 WINAPI waveOutBreakLoop32(HWAVEOUT32 hWaveOut)
2898 {
2899         return waveOutBreakLoop16(hWaveOut);
2900 }
2901 /**************************************************************************
2902  *                              waveOutBreakLoop        [MMSYSTEM.419]
2903  */
2904 UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut)
2905 {
2906         dprintf_mmsys(stddeb, "waveOutBreakLoop(%04X)\n", hWaveOut);
2907         return MMSYSERR_INVALHANDLE;
2908 }
2909
2910 /**************************************************************************
2911  *                              waveOutGetID            [MMSYSTEM.420]
2912  */
2913 UINT32 WINAPI waveOutGetID32(HWAVEOUT32 hWaveOut, UINT32 * lpuDeviceID)
2914 {
2915         LPWAVEOPENDESC  lpDesc;
2916         dprintf_mmsys(stddeb, "waveOutGetID(%04X, %p);\n", hWaveOut, lpuDeviceID);
2917         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2918         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2919         if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
2920         *lpuDeviceID = lpDesc->uDeviceID;
2921         return 0;
2922 }
2923 /**************************************************************************
2924  *                              waveOutGetID            [MMSYSTEM.420]
2925  */
2926 UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16 * lpuDeviceID)
2927 {
2928         LPWAVEOPENDESC  lpDesc;
2929         dprintf_mmsys(stddeb, "waveOutGetID(%04X, %p);\n", hWaveOut, lpuDeviceID);
2930         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2931         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2932         if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
2933         *lpuDeviceID = lpDesc->uDeviceID;
2934         return 0;
2935 }
2936
2937 /**************************************************************************
2938  *                              waveOutMessage          [MMSYSTEM.421]
2939  */
2940 DWORD WINAPI waveOutMessage32(HWAVEOUT32 hWaveOut, UINT32 uMessage, 
2941                               DWORD dwParam1, DWORD dwParam2)
2942 {
2943         LPWAVEOPENDESC  lpDesc;
2944
2945         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2946         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2947         switch (uMessage) {
2948         case WODM_GETNUMDEVS:
2949         case WODM_GETPOS:
2950         case WODM_GETVOLUME:
2951         case WODM_GETPITCH:
2952         case WODM_GETPLAYBACKRATE:
2953         case WODM_SETVOLUME:
2954         case WODM_SETPITCH:
2955         case WODM_SETPLAYBACKRATE:
2956         case WODM_RESET:
2957         case WODM_PAUSE:
2958         case WODM_PREPARE:
2959         case WODM_UNPREPARE:
2960         case WODM_STOP:
2961         case WODM_CLOSE:
2962                 /* no argument conversion needed */
2963                 break;
2964         case WODM_WRITE:
2965                 return waveOutWrite32(hWaveOut,(LPWAVEHDR)dwParam1,dwParam2);
2966         case WODM_GETDEVCAPS:
2967                 /* FIXME: UNICODE/ANSI? */
2968                 return waveOutGetDevCaps32A(hWaveOut,(LPWAVEOUTCAPS32A)dwParam1,dwParam2);
2969         case WODM_OPEN:
2970                 fprintf(stderr,"waveOutMessage32 can't handle WODM_OPEN, please report.\n");
2971                 break;
2972         default:
2973                 fprintf(stderr,"unhandled waveOutMessage32(0x%04x,0x%04x,%08lx,%08lx)\n",
2974                         hWaveOut,uMessage,dwParam1,dwParam2
2975                 );
2976                 break;
2977         }
2978         return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2979 }
2980
2981 /**************************************************************************
2982  *                              waveOutMessage          [MMSYSTEM.421]
2983  */
2984 DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage, 
2985                               DWORD dwParam1, DWORD dwParam2)
2986 {
2987         LPWAVEOPENDESC  lpDesc;
2988
2989         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
2990         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2991         switch (uMessage) {
2992         case WODM_GETNUMDEVS:
2993         case WODM_SETVOLUME:
2994         case WODM_SETPITCH:
2995         case WODM_SETPLAYBACKRATE:
2996         case WODM_RESET:
2997         case WODM_PAUSE:
2998         case WODM_STOP:
2999         case WODM_CLOSE:
3000                 /* no argument conversion needed */
3001                 break;
3002         case WODM_GETPOS:
3003                 return waveOutGetPosition16(hWaveOut,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3004         case WODM_GETVOLUME:
3005                 return waveOutGetVolume16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
3006         case WODM_GETPITCH:
3007                 return waveOutGetPitch16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
3008         case WODM_GETPLAYBACKRATE:
3009                 return waveOutGetPlaybackRate16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
3010         case WODM_GETDEVCAPS:
3011                 return waveOutGetDevCaps16(hWaveOut,(LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3012         case WODM_PREPARE:
3013                 return waveOutPrepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3014         case WODM_UNPREPARE:
3015                 return waveOutUnprepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3016         case WODM_WRITE:
3017                 return waveOutWrite16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3018         case WODM_OPEN:
3019                 fprintf(stderr,"waveOutMessage16 can't handle WODM_OPEN, please report.\n");
3020                 break;
3021         default:
3022                 fprintf(stderr,"unhandled waveOutMessage16(0x%04x,0x%04x,%08lx,%08lx)\n",
3023                         hWaveOut,uMessage,dwParam1,dwParam2
3024                 );
3025         }
3026         return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
3027 }
3028
3029 /**************************************************************************
3030  *                              waveInGetNumDevs                [WINMM.151]
3031  */
3032 UINT32 WINAPI waveInGetNumDevs32()
3033 {
3034         return waveInGetNumDevs16();
3035 }
3036
3037 /**************************************************************************
3038  *                              waveInGetNumDevs                [MMSYSTEM.501]
3039  */
3040 UINT16 WINAPI waveInGetNumDevs16()
3041 {
3042         UINT16  count = 0;
3043         dprintf_mmsys(stddeb, "waveInGetNumDevs\n");
3044         count += widMessage(0, WIDM_GETNUMDEVS, 0L, 0L, 0L);
3045         dprintf_mmsys(stddeb, "waveInGetNumDevs return %u \n", count);
3046         return count;
3047 }
3048
3049 /**************************************************************************
3050  *                              waveInGetDevCapsA               [WINMM.147]
3051  */
3052 UINT32 WINAPI waveInGetDevCaps32W(UINT32 uDeviceID, LPWAVEINCAPS32W lpCaps, UINT32 uSize)
3053 {
3054         WAVEINCAPS16    wic16;
3055         UINT32  ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
3056
3057         lpCaps->wMid = wic16.wMid;
3058         lpCaps->wPid = wic16.wPid;
3059         lpCaps->vDriverVersion = wic16.vDriverVersion;
3060         lstrcpyAtoW(lpCaps->szPname,wic16.szPname);
3061         lpCaps->dwFormats = wic16.dwFormats;
3062         lpCaps->wChannels = wic16.wChannels;
3063
3064         return ret;
3065 }
3066 /**************************************************************************
3067  *                              waveInGetDevCapsA               [WINMM.146]
3068  */
3069 UINT32 WINAPI waveInGetDevCaps32A(UINT32 uDeviceID, LPWAVEINCAPS32A lpCaps, UINT32 uSize)
3070 {
3071         WAVEINCAPS16    wic16;
3072         UINT32  ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
3073         
3074         lpCaps->wMid = wic16.wMid;
3075         lpCaps->wPid = wic16.wPid;
3076         lpCaps->vDriverVersion = wic16.vDriverVersion;
3077         strcpy(lpCaps->szPname,wic16.szPname);
3078         lpCaps->dwFormats = wic16.dwFormats;
3079         lpCaps->wChannels = wic16.wChannels;
3080         return ret;
3081 }
3082 /**************************************************************************
3083  *                              waveInGetDevCaps                [MMSYSTEM.502]
3084  */
3085 UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps, UINT16 uSize)
3086 {
3087         dprintf_mmsys(stddeb, "waveInGetDevCaps\n");
3088         return widMessage(uDeviceID, WIDM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
3089 }
3090
3091 /**************************************************************************
3092  *                              waveInGetErrorTextA     [WINMM.148]
3093  */
3094 UINT32 WINAPI waveInGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
3095 {
3096    dprintf_mmsys(stddeb, "waveInGetErrorText\n");
3097    return(waveGetErrorText(uError, lpText, uSize));
3098 }
3099
3100 /**************************************************************************
3101  *                              waveInGetErrorTextW     [WINMM.149]
3102  */
3103 UINT32 WINAPI waveInGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
3104 {
3105         LPSTR txt = HeapAlloc(GetProcessHeap(),0,uSize);
3106         UINT32  ret = waveGetErrorText(uError, txt, uSize);
3107
3108         lstrcpyAtoW(lpText,txt);
3109         HeapFree(GetProcessHeap(),0,txt);
3110         return ret;
3111 }
3112
3113 /**************************************************************************
3114  *                              waveInGetErrorText      [MMSYSTEM.503]
3115  */
3116 UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
3117 {
3118    dprintf_mmsys(stddeb, "waveInGetErrorText\n");
3119    return(waveGetErrorText(uError, lpText, uSize));
3120 }
3121
3122
3123 /**************************************************************************
3124  *                              waveInOpen                      [WINMM.154]
3125  */
3126 UINT32 WINAPI waveInOpen32(HWAVEIN32 * lphWaveIn, UINT32 uDeviceID,
3127                            const LPWAVEFORMAT lpFormat, DWORD dwCallback,
3128                            DWORD dwInstance, DWORD dwFlags)
3129 {
3130         HWAVEIN16       hwin16;
3131         UINT32  ret=waveInOpen16(&hwin16,uDeviceID,lpFormat,dwCallback,dwInstance,dwFlags);
3132         if (lphWaveIn) *lphWaveIn = hwin16;
3133         return ret;
3134 }
3135
3136 /**************************************************************************
3137  *                              waveInOpen                      [MMSYSTEM.504]
3138  */
3139 UINT16 WINAPI waveInOpen16(HWAVEIN16 * lphWaveIn, UINT16 uDeviceID,
3140                            const LPWAVEFORMAT lpFormat, DWORD dwCallback,
3141                            DWORD dwInstance, DWORD dwFlags)
3142 {
3143         HWAVEIN16 hWaveIn;
3144         LPWAVEOPENDESC  lpDesc;
3145         DWORD   dwRet = 0;
3146         BOOL32  bMapperFlg = FALSE;
3147         dprintf_mmsys(stddeb, "waveInOpen(%p, %d, %p, %08lX, %08lX, %08lX);\n", 
3148                 lphWaveIn, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
3149         if (dwFlags & WAVE_FORMAT_QUERY)
3150                 dprintf_mmsys(stddeb, "waveInOpen // WAVE_FORMAT_QUERY requested !\n");
3151         if (uDeviceID == (UINT16)WAVE_MAPPER) {
3152                 dprintf_mmsys(stddeb, "waveInOpen       // WAVE_MAPPER mode requested !\n");
3153                 bMapperFlg = TRUE;
3154                 uDeviceID = 0;
3155         }
3156         if (lpFormat == NULL) return WAVERR_BADFORMAT;
3157         hWaveIn = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
3158         if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
3159         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3160         if (lpDesc == NULL) return MMSYSERR_NOMEM;
3161         lpDesc->hWave = hWaveIn;
3162         lpDesc->lpFormat = lpFormat;
3163         lpDesc->dwCallBack = dwCallback;
3164         lpDesc->dwInstance = dwInstance;
3165         while(uDeviceID < MAXWAVEDRIVERS) {
3166                 dwRet = widMessage(uDeviceID, WIDM_OPEN, 
3167                         lpDesc->dwInstance, (DWORD)lpDesc, 0L);
3168                 if (dwRet == MMSYSERR_NOERROR) break;
3169                 if (!bMapperFlg) break;
3170                 uDeviceID++;
3171                 dprintf_mmsys(stddeb, "waveInOpen       // WAVE_MAPPER mode ! try next driver...\n");
3172         }
3173         lpDesc->uDeviceID = uDeviceID;
3174         if (dwFlags & WAVE_FORMAT_QUERY) {
3175                 dprintf_mmsys(stddeb, "waveInOpen       // End of WAVE_FORMAT_QUERY !\n");
3176                 dwRet = waveInClose16(hWaveIn);
3177         }
3178         return dwRet;
3179 }
3180
3181 /**************************************************************************
3182  *                              waveInClose                     [WINMM.145]
3183  */
3184 UINT32 WINAPI waveInClose32(HWAVEIN32 hWaveIn)
3185 {
3186         return waveInClose16(hWaveIn);
3187 }
3188 /**************************************************************************
3189  *                              waveInClose                     [MMSYSTEM.505]
3190  */
3191 UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
3192 {
3193         LPWAVEOPENDESC  lpDesc;
3194
3195         dprintf_mmsys(stddeb, "waveInClose(%04X)\n", hWaveIn);
3196         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3197         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3198         return widMessage(lpDesc->uDeviceID, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
3199 }
3200
3201 /**************************************************************************
3202  *                              waveInPrepareHeader             [WINMM.155]
3203  */
3204 UINT32 WINAPI waveInPrepareHeader32(HWAVEIN32 hWaveIn,
3205                                   WAVEHDR * lpWaveInHdr, UINT32 uSize)
3206 {
3207         LPWAVEOPENDESC  lpDesc;
3208
3209         dprintf_mmsys(stddeb, "waveInPrepareHeader(%04X, %p, %u);\n", 
3210                                         hWaveIn, lpWaveInHdr, uSize);
3211         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3212         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3213         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3214         lpWaveInHdr = lpWaveInHdr;
3215         lpWaveInHdr->lpNext = NULL;
3216         lpWaveInHdr->dwBytesRecorded = 0;
3217         dprintf_mmsys(stddeb, "waveInPrepareHeader // lpData=%p size=%lu \n", 
3218                 lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
3219         return widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance, 
3220                           (DWORD)lpWaveInHdr, uSize);
3221 }
3222 /**************************************************************************
3223  *                              waveInPrepareHeader             [MMSYSTEM.506]
3224  */
3225 UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn,
3226                                   WAVEHDR * lpWaveInHdr, UINT16 uSize)
3227 {
3228         LPWAVEOPENDESC  lpDesc;
3229         LPBYTE          saveddata = lpWaveInHdr->lpData;
3230         UINT16          ret;
3231
3232         dprintf_mmsys(stddeb, "waveInPrepareHeader(%04X, %p, %u);\n", 
3233                                         hWaveIn, lpWaveInHdr, uSize);
3234         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3235         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3236         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3237         lpWaveInHdr = lpWaveInHdr;
3238         lpWaveInHdr->lpNext = NULL;
3239         lpWaveInHdr->dwBytesRecorded = 0;
3240
3241         dprintf_mmsys(stddeb, "waveInPrepareHeader // lpData=%p size=%lu \n", 
3242                 lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
3243         lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
3244         ret = widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance, 
3245                           (DWORD)lpWaveInHdr,uSize);
3246         lpWaveInHdr->lpData = saveddata;
3247         return ret;
3248 }
3249
3250
3251 /**************************************************************************
3252  *                              waveInUnprepareHeader   [WINMM.159]
3253  */
3254 UINT32 WINAPI waveInUnprepareHeader32(HWAVEIN32 hWaveIn,
3255                                       WAVEHDR * lpWaveInHdr, UINT32 uSize)
3256 {
3257         LPWAVEOPENDESC  lpDesc;
3258
3259         dprintf_mmsys(stddeb, "waveInUnprepareHeader(%04X, %p, %u);\n", 
3260                                                 hWaveIn, lpWaveInHdr, uSize);
3261         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3262         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3263         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3264         /*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
3265         lpWaveInHdr->lpData = NULL;
3266         lpWaveInHdr->lpNext = NULL;
3267         return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance, 
3268                           (DWORD)lpWaveInHdr, uSize);
3269 }
3270 /**************************************************************************
3271  *                              waveInUnprepareHeader   [MMSYSTEM.507]
3272  */
3273 UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn,
3274                                       WAVEHDR * lpWaveInHdr, UINT16 uSize)
3275 {
3276         LPWAVEOPENDESC  lpDesc;
3277
3278         dprintf_mmsys(stddeb, "waveInUnprepareHeader(%04X, %p, %u);\n", 
3279                                                 hWaveIn, lpWaveInHdr, uSize);
3280         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3281         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3282         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3283         /*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
3284         lpWaveInHdr->lpData = NULL;
3285         lpWaveInHdr->lpNext = NULL;
3286         return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance, 
3287                           (DWORD)lpWaveInHdr, uSize);
3288 }
3289
3290 /**************************************************************************
3291  *                              waveInAddBuffer         [WINMM.144]
3292  */
3293 UINT32 WINAPI waveInAddBuffer32(HWAVEIN32 hWaveIn,
3294                                 WAVEHDR * lpWaveInHdr, UINT32 uSize)
3295 {
3296         LPWAVEOPENDESC  lpDesc;
3297
3298         dprintf_mmsys(stddeb, "waveInAddBuffer(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
3299         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3300         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3301         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3302         lpWaveInHdr->lpNext = NULL;
3303         lpWaveInHdr->dwBytesRecorded = 0;
3304         dprintf_mmsys(stddeb, "waveInAddBuffer // lpData=%p size=%lu \n", 
3305                 lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
3306         return widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
3307                                                                 (DWORD)lpWaveInHdr, uSize);
3308         
3309 }
3310
3311 /**************************************************************************
3312  *                              waveInAddBuffer         [MMSYSTEM.508]
3313  */
3314 UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn,
3315                                 WAVEHDR * lpWaveInHdr, UINT16 uSize)
3316 {
3317         LPWAVEOPENDESC  lpDesc;
3318         UINT16          ret;
3319
3320         dprintf_mmsys(stddeb, "waveInAddBuffer(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
3321         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3322         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3323         if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3324         lpWaveInHdr->lpNext = NULL;
3325         lpWaveInHdr->dwBytesRecorded = 0;
3326         lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
3327         dprintf_mmsys(stddeb, "waveInAddBuffer // lpData=%p size=%lu \n", 
3328                 lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
3329         ret = widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
3330                           (DWORD)lpWaveInHdr, uSize);
3331         /*lpWaveInHdr->lpData = saveddata;*/
3332         return ret;
3333 }
3334
3335 /**************************************************************************
3336  *                              waveInStart                     [WINMM.157]
3337  */
3338 UINT32 WINAPI waveInStart32(HWAVEIN32 hWaveIn)
3339 {
3340         return waveInStart16(hWaveIn);
3341 }
3342
3343 /**************************************************************************
3344  *                              waveInStart                     [MMSYSTEM.509]
3345  */
3346 UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn)
3347 {
3348         LPWAVEOPENDESC  lpDesc;
3349
3350         dprintf_mmsys(stddeb, "waveInStart(%04X)\n", hWaveIn);
3351         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3352         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3353         return widMessage(lpDesc->uDeviceID,WIDM_START,lpDesc->dwInstance,0,0);
3354 }
3355
3356 /**************************************************************************
3357  *                              waveInStop                      [WINMM.158]
3358  */
3359 UINT32 WINAPI waveInStop32(HWAVEIN32 hWaveIn)
3360 {
3361         return waveInStop16(hWaveIn);
3362 }
3363
3364 /**************************************************************************
3365  *                              waveInStop                      [MMSYSTEM.510]
3366  */
3367 UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn)
3368 {
3369         LPWAVEOPENDESC  lpDesc;
3370
3371         dprintf_mmsys(stddeb, "waveInStop(%04X)\n", hWaveIn);
3372         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3373         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3374         return widMessage(lpDesc->uDeviceID, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
3375 }
3376
3377 /**************************************************************************
3378  *                              waveInReset                     [WINMM.156]
3379  */
3380 UINT32 WINAPI waveInReset32(HWAVEIN32 hWaveIn)
3381 {
3382         return waveInReset16(hWaveIn);
3383 }
3384
3385 /**************************************************************************
3386  *                              waveInReset                     [MMSYSTEM.511]
3387  */
3388 UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn)
3389 {
3390         LPWAVEOPENDESC  lpDesc;
3391
3392         dprintf_mmsys(stddeb, "waveInReset(%04X)\n", hWaveIn);
3393         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3394         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3395         return widMessage(lpDesc->uDeviceID,WIDM_RESET,lpDesc->dwInstance,0,0);
3396 }
3397
3398 /**************************************************************************
3399  *                              waveInGetPosition       [WINMM.152]
3400  */
3401 UINT32 WINAPI waveInGetPosition32(HWAVEIN32 hWaveIn, LPMMTIME32 lpTime,
3402                                   UINT32 uSize)
3403 {
3404         MMTIME16 mmt16;
3405         UINT32  ret = waveInGetPosition16(hWaveIn,&mmt16,uSize);
3406
3407         MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
3408         return ret;
3409 }
3410
3411 /**************************************************************************
3412  *                              waveInGetPosition       [MMSYSTEM.512]
3413  */
3414 UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn,LPMMTIME16 lpTime,
3415                                   UINT16 uSize)
3416 {
3417         LPWAVEOPENDESC  lpDesc;
3418
3419         dprintf_mmsys(stddeb, "waveInGetPosition(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
3420         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3421         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3422         return widMessage(lpDesc->uDeviceID, WIDM_GETPOS, lpDesc->dwInstance,
3423                           (DWORD)lpTime, (DWORD)uSize);
3424 }
3425
3426 /**************************************************************************
3427  *                              waveInGetID                     [WINMM.150]
3428  */
3429 UINT32 WINAPI waveInGetID32(HWAVEIN32 hWaveIn, UINT32 * lpuDeviceID)
3430 {
3431         LPWAVEOPENDESC  lpDesc;
3432
3433         dprintf_mmsys(stddeb, "waveInGetID\n");
3434         if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
3435         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3436         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3437         *lpuDeviceID = lpDesc->uDeviceID;
3438         return 0;
3439 }
3440
3441
3442 /**************************************************************************
3443  *                              waveInGetID                     [MMSYSTEM.513]
3444  */
3445 UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16 * lpuDeviceID)
3446 {
3447         LPWAVEOPENDESC  lpDesc;
3448
3449         dprintf_mmsys(stddeb, "waveInGetID\n");
3450         if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
3451         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3452         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3453         *lpuDeviceID = lpDesc->uDeviceID;
3454         return 0;
3455 }
3456
3457 /**************************************************************************
3458  *                              waveInMessage           [WINMM.153]
3459  */
3460 DWORD WINAPI waveInMessage32(HWAVEIN32 hWaveIn, UINT32 uMessage,
3461                              DWORD dwParam1, DWORD dwParam2)
3462 {
3463         LPWAVEOPENDESC  lpDesc;
3464
3465         fprintf(stderr, "waveInMessage32(%04X, %04X, %08lX, %08lX),FIXME!\n", 
3466                         hWaveIn, uMessage, dwParam1, dwParam2);
3467         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3468         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3469         switch (uMessage) {
3470         case WIDM_OPEN:
3471                 fprintf(stderr,"waveInMessage32: cannot handle WIDM_OPEN, please report.\n");
3472                 break;
3473         case WIDM_GETNUMDEVS:
3474         case WIDM_GETPOS:
3475         case WIDM_CLOSE:
3476         case WIDM_STOP :
3477         case WIDM_RESET:
3478         case WIDM_START:
3479         case WIDM_PREPARE:
3480         case WIDM_UNPREPARE:
3481         case WIDM_ADDBUFFER:
3482         case WIDM_PAUSE:
3483                 /* no argument conversion needed */
3484                 break;
3485         case WIDM_GETDEVCAPS:
3486                 /*FIXME: ANSI/UNICODE */
3487                 return waveInGetDevCaps32A(hWaveIn,(LPWAVEINCAPS32A)dwParam1,dwParam2);
3488         default:
3489                 fprintf(stderr,"unhandled waveInMessage32(%04x,%04x,%08lx,%08lx)\n",hWaveIn,uMessage,dwParam1,dwParam2);
3490                 break;
3491         }
3492         return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
3493 }
3494
3495 /**************************************************************************
3496  *                              waveInMessage           [MMSYSTEM.514]
3497  */
3498 DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
3499                              DWORD dwParam1, DWORD dwParam2)
3500 {
3501         LPWAVEOPENDESC  lpDesc;
3502
3503         fprintf(stderr, "waveInMessage(%04X, %04X, %08lX, %08lX),FIXME!\n", 
3504                         hWaveIn, uMessage, dwParam1, dwParam2);
3505         lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3506         if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3507         switch (uMessage) {
3508         case WIDM_OPEN:
3509                 fprintf(stderr,"waveInMessage16: cannot handle WIDM_OPEN, please report.\n");
3510                 break;
3511         case WIDM_GETNUMDEVS:
3512         case WIDM_CLOSE:
3513         case WIDM_STOP :
3514         case WIDM_RESET:
3515         case WIDM_START:
3516         case WIDM_PAUSE:
3517                 /* no argument conversion needed */
3518                 break;
3519         case WIDM_GETDEVCAPS:
3520                 return waveInGetDevCaps16(hWaveIn,(LPWAVEINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3521         case WIDM_GETPOS:
3522                 return waveInGetPosition16(hWaveIn,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3523         case WIDM_PREPARE:
3524                 return waveInPrepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3525         case WIDM_UNPREPARE:
3526                 return waveInUnprepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3527         case WIDM_ADDBUFFER:
3528                 return waveInAddBuffer16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3529         default:
3530                 fprintf(stderr,"unhandled waveInMessage16(%04x,%04x,%08lx,%08lx)\n",hWaveIn,uMessage,dwParam1,dwParam2);
3531                 break;
3532         }
3533         return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
3534 }
3535
3536 /**************************************************************************
3537  *                              mmioOpenW                       [WINMM.123]
3538  */
3539 HMMIO32 WINAPI mmioOpen32W(LPWSTR szFileName, MMIOINFO32 * lpmmioinfo,
3540                           DWORD dwOpenFlags)
3541 {
3542         LPSTR   szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName);
3543         HMMIO32 ret = mmioOpen16(szFn,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags);
3544
3545         HeapFree(GetProcessHeap(),0,szFn);
3546         return ret;
3547 }
3548
3549 /**************************************************************************
3550  *                              mmioOpenA                       [WINMM.122]
3551  */
3552 HMMIO32 WINAPI mmioOpen32A(LPSTR szFileName, MMIOINFO32 * lpmmioinfo,
3553                           DWORD dwOpenFlags)
3554 {
3555         return mmioOpen16(szFileName,(LPMMIOINFO16)lpmmioinfo,dwOpenFlags);
3556 }
3557
3558 /**************************************************************************
3559  *                              mmioOpen                [MMSYSTEM.1210]
3560  */
3561 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16 * lpmmioinfo,
3562                           DWORD dwOpenFlags)
3563 {
3564         HFILE32 hFile;
3565         HMMIO16         hmmio;
3566         OFSTRUCT        ofs;
3567         LPMMIOINFO16    lpmminfo;
3568         dprintf_mmio(stddeb, "mmioOpen('%s', %p, %08lX);\n", szFileName, lpmmioinfo, dwOpenFlags);
3569         if (!szFileName)
3570         {
3571             /* FIXME: should load memory file if szFileName == NULL */
3572             fprintf(stderr, "WARNING: mmioOpen(): szFileName == NULL (memory file ???)\n");
3573             return 0;
3574         }
3575         hFile = OpenFile32(szFileName, &ofs, dwOpenFlags);
3576         if (hFile == -1) return 0;
3577         hmmio = GlobalAlloc16(GMEM_MOVEABLE, sizeof(MMIOINFO16));
3578         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3579         if (lpmminfo == NULL) return 0;
3580         memset(lpmminfo, 0, sizeof(MMIOINFO16));
3581         lpmminfo->hmmio = hmmio;
3582         lpmminfo->dwReserved2 = hFile;
3583         GlobalUnlock16(hmmio);
3584         dprintf_mmio(stddeb, "mmioOpen // return hmmio=%04X\n", hmmio);
3585         return hmmio;
3586 }
3587
3588     
3589 /**************************************************************************
3590 *                               mmioClose               [MMSYSTEM.1211]
3591 */
3592 UINT16 WINAPI mmioClose(HMMIO16 hmmio, UINT16 uFlags)
3593 {
3594         LPMMIOINFO16    lpmminfo;
3595         dprintf_mmio(stddeb, "mmioClose(%04X, %04X);\n", hmmio, uFlags);
3596         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3597         if (lpmminfo == NULL) return 0;
3598         _lclose32((HFILE32)lpmminfo->dwReserved2);
3599         GlobalUnlock16(hmmio);
3600         GlobalFree16(hmmio);
3601         return 0;
3602 }
3603
3604
3605
3606 /**************************************************************************
3607 *                               mmioRead                [MMSYSTEM.1212]
3608 */
3609 LONG WINAPI mmioRead(HMMIO16 hmmio, HPSTR pch, LONG cch)
3610 {
3611         LONG            count;
3612         LPMMIOINFO16    lpmminfo;
3613         dprintf_mmio(stddeb, "mmioRead(%04X, %p, %ld);\n", hmmio, pch, cch);
3614         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3615         if (lpmminfo == NULL) return 0;
3616         count = _lread32(LOWORD(lpmminfo->dwReserved2), pch, cch);
3617         GlobalUnlock16(hmmio);
3618         dprintf_mmio(stddeb, "mmioRead // count=%ld\n", count);
3619         return count;
3620 }
3621
3622
3623
3624 /**************************************************************************
3625 *                               mmioWrite               [MMSYSTEM.1213]
3626 */
3627 LONG WINAPI mmioWrite(HMMIO16 hmmio, HPCSTR pch, LONG cch)
3628 {
3629         LONG            count;
3630         LPMMIOINFO16    lpmminfo;
3631         dprintf_mmio(stddeb, "mmioWrite(%04X, %p, %ld);\n", hmmio, pch, cch);
3632         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3633         if (lpmminfo == NULL) return 0;
3634         count = _lwrite32(LOWORD(lpmminfo->dwReserved2), (LPSTR)pch, cch);
3635         GlobalUnlock16(hmmio);
3636         return count;
3637 }
3638
3639 /**************************************************************************
3640 *                               mmioSeek                [MMSYSTEM.1214]
3641 */
3642 LONG WINAPI mmioSeek(HMMIO16 hmmio, LONG lOffset, int iOrigin)
3643 {
3644         int             count;
3645         LPMMIOINFO16    lpmminfo;
3646         dprintf_mmio(stddeb, "mmioSeek(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
3647         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3648         if (lpmminfo == NULL) {
3649                 dprintf_mmio(stddeb, "mmioSeek // can't lock hmmio=%04X !\n", hmmio);
3650                 return 0;
3651                 }
3652         count = _llseek32((HFILE32)lpmminfo->dwReserved2, lOffset, iOrigin);
3653         GlobalUnlock16(hmmio);
3654         return count;
3655 }
3656
3657 /**************************************************************************
3658 *                               mmioGetInfo             [MMSYSTEM.1215]
3659 */
3660 UINT16 WINAPI mmioGetInfo(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
3661 {
3662         LPMMIOINFO16    lpmminfo;
3663         dprintf_mmio(stddeb, "mmioGetInfo\n");
3664         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3665         if (lpmminfo == NULL) return 0;
3666         memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO16));
3667         GlobalUnlock16(hmmio);
3668         return 0;
3669 }
3670
3671 /**************************************************************************
3672 *                               mmioSetInfo             [MMSYSTEM.1216]
3673 */
3674 UINT16 WINAPI mmioSetInfo(HMMIO16 hmmio, const MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
3675 {
3676         LPMMIOINFO16    lpmminfo;
3677         dprintf_mmio(stddeb, "mmioSetInfo\n");
3678         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3679         if (lpmminfo == NULL) return 0;
3680         GlobalUnlock16(hmmio);
3681         return 0;
3682 }
3683
3684 /**************************************************************************
3685 *                               mmioSetBuffer           [MMSYSTEM.1217]
3686 */
3687 UINT16 WINAPI mmioSetBuffer(HMMIO16 hmmio, LPSTR pchBuffer, 
3688                             LONG cchBuffer, UINT16 uFlags)
3689 {
3690         dprintf_mmio(stddeb, "mmioSetBuffer // empty stub \n");
3691         return 0;
3692 }
3693
3694 /**************************************************************************
3695 *                               mmioFlush               [MMSYSTEM.1218]
3696 */
3697 UINT16 WINAPI mmioFlush(HMMIO16 hmmio, UINT16 uFlags)
3698 {
3699         LPMMIOINFO16    lpmminfo;
3700         dprintf_mmio(stddeb, "mmioFlush(%04X, %04X)\n", hmmio, uFlags);
3701         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3702         if (lpmminfo == NULL) return 0;
3703         GlobalUnlock16(hmmio);
3704         return 0;
3705 }
3706
3707 /**************************************************************************
3708 *                               mmioAdvance             [MMSYSTEM.1219]
3709 */
3710 UINT16 WINAPI mmioAdvance(HMMIO16 hmmio, MMIOINFO16 * lpmmioinfo, UINT16 uFlags)
3711 {
3712         int             count = 0;
3713         LPMMIOINFO16    lpmminfo;
3714         dprintf_mmio(stddeb, "mmioAdvance\n");
3715         lpmminfo = (LPMMIOINFO16)GlobalLock16(hmmio);
3716         if (lpmminfo == NULL) return 0;
3717         if (uFlags == MMIO_READ) {
3718                 count = _lread32(LOWORD(lpmminfo->dwReserved2), 
3719                         lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
3720                 }
3721         if (uFlags == MMIO_WRITE) {
3722                 count = _lwrite32(LOWORD(lpmminfo->dwReserved2),
3723                         lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
3724                 }
3725         lpmmioinfo->pchNext     += count;
3726         GlobalUnlock16(hmmio);
3727         lpmminfo->lDiskOffset = _llseek32((HFILE32)lpmminfo->dwReserved2, 0, SEEK_CUR);
3728         return 0;
3729 }
3730
3731 /**************************************************************************
3732  *                              mmioStringToFOURCCW     [WINMM.131]
3733  */
3734 FOURCC WINAPI mmioStringToFOURCC32A(LPCSTR sz, UINT32 uFlags)
3735 {
3736         return mmioStringToFOURCC16(sz,uFlags);
3737 }
3738
3739 /**************************************************************************
3740  *                              mmioStringToFOURCCW     [WINMM.132]
3741  */
3742 FOURCC WINAPI mmioStringToFOURCC32W(LPCWSTR sz, UINT32 uFlags)
3743 {
3744         LPSTR   szA = HEAP_strdupWtoA(GetProcessHeap(),0,sz);
3745         FOURCC  ret = mmioStringToFOURCC32A(szA,uFlags);
3746
3747         HeapFree(GetProcessHeap(),0,szA);
3748         return ret;
3749 }
3750
3751 /**************************************************************************
3752  *                              mmioStringToFOURCC      [MMSYSTEM.1220]
3753  */
3754 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
3755 {
3756         dprintf_mmio(stddeb, "mmioStringToFOURCC // empty stub \n");
3757         return 0;
3758 }
3759
3760 /**************************************************************************
3761 *                               mmioInstallIOProc16     [MMSYSTEM.1221]
3762 */
3763 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, 
3764                                         LPMMIOPROC16 pIOProc, DWORD dwFlags)
3765 {
3766         dprintf_mmio(stddeb, "mmioInstallIOProc // empty stub \n");
3767         return 0;
3768 }
3769
3770 /**************************************************************************
3771  *                              mmioInstallIOProc32A   [WINMM.120]
3772  */
3773 LPMMIOPROC32 WINAPI mmioInstallIOProc32A(FOURCC fccIOProc, 
3774                                          LPMMIOPROC32 pIOProc, DWORD dwFlags)
3775 {
3776         dprintf_mmio(stddeb, "mmioInstallIOProcA (%c%c%c%c,%p,0x%08lx)// empty stub \n",
3777                      (char)((fccIOProc&0xff000000)>>24),
3778                      (char)((fccIOProc&0x00ff0000)>>16),
3779                      (char)((fccIOProc&0x0000ff00)>> 8),
3780                      (char)(fccIOProc&0x000000ff),
3781                      pIOProc, dwFlags );
3782         return 0;
3783 }
3784
3785 /**************************************************************************
3786 *                               mmioSendMessage         [MMSYSTEM.1222]
3787 */
3788 LRESULT WINAPI mmioSendMessage(HMMIO16 hmmio, UINT16 uMessage,
3789                                LPARAM lParam1, LPARAM lParam2)
3790 {
3791         dprintf_mmio(stddeb, "mmioSendMessage // empty stub \n");
3792         return 0;
3793 }
3794
3795 /**************************************************************************
3796 *                               mmioDescend             [MMSYSTEM.1223]
3797 */
3798 UINT16 WINAPI mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
3799                           const MMCKINFO * lpckParent, UINT16 uFlags)
3800 {
3801         DWORD   dwfcc, dwOldPos;
3802
3803         dprintf_mmio(stddeb, "mmioDescend(%04X, %p, %p, %04X);\n", 
3804                                 hmmio, lpck, lpckParent, uFlags);
3805
3806         if (lpck == NULL)
3807             return 0;
3808
3809         dwfcc = lpck->ckid;
3810         dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX\n", dwfcc);
3811
3812         dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
3813         dprintf_mmio(stddeb, "mmioDescend // dwOldPos=%ld\n", dwOldPos);
3814
3815         if (lpckParent != NULL) {
3816                 dprintf_mmio(stddeb, "mmioDescend // seek inside parent at %ld !\n", lpckParent->dwDataOffset);
3817                 dwOldPos = mmioSeek(hmmio, lpckParent->dwDataOffset, SEEK_SET);
3818         }
3819 /*
3820
3821    It seems to be that FINDRIFF should not be treated the same as the 
3822    other FINDxxx so I treat it as a MMIO_FINDxxx
3823
3824         if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDRIFF) || 
3825                 (uFlags & MMIO_FINDLIST)) {
3826 */
3827         if ((uFlags & MMIO_FINDCHUNK) || (uFlags & MMIO_FINDLIST)) {
3828                 dprintf_mmio(stddeb, "mmioDescend // MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc);
3829                 while (TRUE) {
3830                         LONG ix;
3831
3832                         ix = mmioRead(hmmio, (LPSTR)lpck, sizeof(MMCKINFO));
3833                         dprintf_mmio(stddeb, "mmioDescend // after _lread32 ix = %ld req = %d, errno = %d\n",ix,sizeof(MMCKINFO),errno);
3834                         if (ix < sizeof(MMCKINFO)) {
3835
3836                                 mmioSeek(hmmio, dwOldPos, SEEK_SET);
3837                                 dprintf_mmio(stddeb, "mmioDescend // return ChunkNotFound\n");
3838                                 return MMIOERR_CHUNKNOTFOUND;
3839                         }
3840                         dprintf_mmio(stddeb, "mmioDescend // dwfcc=%08lX ckid=%08lX cksize=%08lX !\n", 
3841                                                                         dwfcc, lpck->ckid, lpck->cksize);
3842                         if (dwfcc == lpck->ckid)
3843                                 break;
3844
3845                         dwOldPos += lpck->cksize + 2 * sizeof(DWORD);
3846                         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
3847                                 dwOldPos += sizeof(DWORD);
3848                         mmioSeek(hmmio, dwOldPos, SEEK_SET);
3849                 }
3850         }
3851         else {
3852                 if (mmioRead(hmmio, (LPSTR)lpck, sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
3853                         mmioSeek(hmmio, dwOldPos, SEEK_SET);
3854                         dprintf_mmio(stddeb, "mmioDescend // return ChunkNotFound 2nd\n");
3855                         return MMIOERR_CHUNKNOTFOUND;
3856                 }
3857         }
3858         lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
3859         if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST) 
3860                 lpck->dwDataOffset += sizeof(DWORD);
3861         mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
3862
3863         dprintf_mmio(stddeb, "mmioDescend // lpck->ckid=%08lX lpck->cksize=%ld !\n", 
3864                                                                 lpck->ckid, lpck->cksize);
3865         dprintf_mmio(stddeb, "mmioDescend // lpck->fccType=%08lX !\n", lpck->fccType);
3866
3867         return 0;
3868 }
3869
3870 /**************************************************************************
3871 *                               mmioAscend              [MMSYSTEM.1224]
3872 */
3873 UINT16 WINAPI mmioAscend(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
3874 {
3875         dprintf_mmio(stddeb, "mmioAscend // empty stub !\n");
3876         return 0;
3877 }
3878
3879 /**************************************************************************
3880 *                               mmioCreateChunk         [MMSYSTEM.1225]
3881 */
3882 UINT16 WINAPI mmioCreateChunk(HMMIO16 hmmio, MMCKINFO * lpck, UINT16 uFlags)
3883 {
3884         dprintf_mmio(stddeb, "mmioCreateChunk // empty stub \n");
3885         return 0;
3886 }
3887
3888
3889 /**************************************************************************
3890 *                               mmioRename              [MMSYSTEM.1226]
3891 */
3892 UINT16 WINAPI mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
3893                          MMIOINFO16 * lpmmioinfo, DWORD dwRenameFlags)
3894 {
3895         dprintf_mmio(stddeb, "mmioRename('%s', '%s', %p, %08lX); // empty stub \n",
3896                         szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
3897         return 0;
3898 }
3899
3900 /**************************************************************************
3901 *                               DrvOpen                 [MMSYSTEM.1100]
3902 */
3903 HDRVR16 WINAPI DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
3904 {
3905         dprintf_mmsys(stddeb, "DrvOpen('%s', '%s', %08lX);\n",
3906                 lpDriverName, lpSectionName, lParam);
3907         return OpenDriver(lpDriverName, lpSectionName, lParam);
3908 }
3909
3910
3911 /**************************************************************************
3912 *                               DrvClose                [MMSYSTEM.1101]
3913 */
3914 LRESULT WINAPI DrvClose(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
3915 {
3916         dprintf_mmsys(stddeb, "DrvClose(%04X, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
3917         return CloseDriver(hDrvr, lParam1, lParam2);
3918 }
3919
3920
3921 /**************************************************************************
3922 *                               DrvSendMessage          [MMSYSTEM.1102]
3923 */
3924 LRESULT WINAPI DrvSendMessage(HDRVR16 hDriver, WORD msg, LPARAM lParam1,
3925                               LPARAM lParam2)
3926 {
3927         DWORD   dwDriverID = 0;
3928         dprintf_mmsys(stddeb, "DrvSendMessage(%04X, %04X, %08lX, %08lX);\n",
3929                                         hDriver, msg, lParam1, lParam2);
3930         return CDAUDIO_DriverProc(dwDriverID, hDriver, msg, lParam1, lParam2);
3931 }
3932
3933 /**************************************************************************
3934 *                               DrvGetModuleHandle      [MMSYSTEM.1103]
3935 */
3936 HANDLE16 WINAPI DrvGetModuleHandle(HDRVR16 hDrvr)
3937 {
3938         dprintf_mmsys(stddeb, "DrvGetModuleHandle(%04X);\n", hDrvr);
3939         return 0;
3940 }
3941
3942
3943 /**************************************************************************
3944 *                               DrvDefDriverProc        [MMSYSTEM.1104]
3945 */
3946 LRESULT WINAPI DrvDefDriverProc(DWORD dwDriverID, HDRVR16 hDriv, WORD wMsg, 
3947                                 DWORD dwParam1, DWORD dwParam2)
3948 {
3949         return DefDriverProc(dwDriverID, hDriv, wMsg, dwParam1, dwParam2);
3950 }