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