Cleaned up a bit, removed todos for OpenThread, avoid TerminateThread
[wine] / dlls / winmm / lolvldrv.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  * MMSYTEM low level drivers handling functions
5  *
6  * Copyright 1999 Eric Pouech
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <string.h>
24 #include <stdio.h>
25 #include <assert.h>
26 #include "wine/winbase16.h"
27 #include "winreg.h"
28 #include "winver.h"
29 #include "winemm.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
33
34 typedef DWORD   (CALLBACK *WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
35 typedef DWORD   (CALLBACK *WINEMM_msgFunc32)(UINT  , UINT, DWORD, DWORD, DWORD);
36
37 /* for each loaded driver and each known type of driver, this structure contains
38  * the information needed to access it
39  */
40 typedef struct tagWINE_MM_DRIVER_PART {
41     int                         nIDMin;         /* lower bound of global indexes for this type */
42     int                         nIDMax;         /* hhigher bound of global indexes for this type */
43     union {
44         WINEMM_msgFunc32        fnMessage32;    /* pointer to fonction */
45         WINEMM_msgFunc16        fnMessage16;
46     } u;
47 } WINE_MM_DRIVER_PART;
48
49 /* each low-level .drv will be associated with an instance of this structure */
50 typedef struct tagWINE_MM_DRIVER {
51     HDRVR                       hDriver;
52     LPSTR                       drvname;        /* name of the driver */
53     BOOL                        bIs32 : 1,      /* TRUE if 32 bit driver, FALSE for 16 */
54                                 bIsMapper : 1;  /* TRUE if mapper */
55     WINE_MM_DRIVER_PART         parts[MMDRV_MAX];/* Information for all known types */
56 } WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
57
58 typedef enum {
59     MMDRV_MAP_NOMEM,    /* ko, memory problem */
60     MMDRV_MAP_MSGERROR, /* ko, unknown message */
61     MMDRV_MAP_OK,       /* ok, no memory allocated. to be sent to the proc. */
62     MMDRV_MAP_OKMEM,    /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
63     MMDRV_MAP_PASS      /* not handled (no memory allocated) to be sent to the driver */
64 } MMDRV_MapType;
65
66 typedef MMDRV_MapType   (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
67
68 /* each known type of driver has an instance of this structure */
69 typedef struct tagWINE_LLTYPE {
70     /* those attributes depend on the specification of the type */    
71     LPSTR               typestr;        /* name (for debugging) */
72     BOOL                bSupportMapper; /* if type is allowed to support mapper */
73     MMDRV_MAPFUNC       Map16To32A;     /* those are function pointers to handle */
74     MMDRV_MAPFUNC       UnMap16To32A;   /*   the parameter conversion (16 vs 32 bit) */
75     MMDRV_MAPFUNC       Map32ATo16;     /*   when hi-func (in mmsystem or winmm) and */
76     MMDRV_MAPFUNC       UnMap32ATo16;   /*   low-func (in .drv) do not match */
77     LPDRVCALLBACK       Callback;       /* handles callback for a specified type */
78     /* those attributes reflect the loaded/current situation for the type */
79     UINT                wMaxId;         /* number of loaded devices (sum across all loaded drivers */
80     LPWINE_MLD          lpMlds;         /* "static" mlds to access the part though device IDs */
81     int                 nMapper;        /* index to mapper */
82 } WINE_LLTYPE;
83
84 static int              MMDrvsHi /* = 0 */;
85 static WINE_MM_DRIVER   MMDrvs[3];
86 static LPWINE_MLD       MM_MLDrvs[40];
87 #define MAX_MM_MLDRVS   (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
88
89 /* ### start build ### */
90 extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
91 /* ### stop build ### */
92
93 /**************************************************************************
94  *                              MMDRV_GetDescription16          [internal]
95  */
96 static  BOOL    MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
97 {
98     OFSTRUCT    ofs;
99     HFILE       hFile;
100     WORD        w;
101     DWORD       dw;
102     BOOL        ret = FALSE;
103
104     if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
105         ERR("Can't open file %s (builtin driver ?)\n", fname);
106         return FALSE;
107     }
108
109 #define E(_x)   do {TRACE _x;goto theEnd;} while(0)
110
111     if (_lread(hFile, &w, 2) != 2)                      E(("Can't read sig\n"));
112     if (w != ('Z' * 256 + 'M'))                         E(("Bad sig %04x\n", w));
113     if (_llseek(hFile, 0x3C, SEEK_SET) < 0)             E(("Can't seek to ext header offset\n"));
114     if (_lread(hFile, &dw, 4) != 4)                     E(("Can't read ext header offset\n"));
115     if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0)        E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
116     if (_lread(hFile, &dw, 4) != 4)                     E(("Can't read nr table offset\n"));
117     if (_llseek(hFile, dw, SEEK_SET) < 0)               E(("Can't seek to nr table %lu\n", dw));
118     if (_lread(hFile, buf, 1) != 1)                     E(("Can't read descr length\n"));
119     buflen = min((BYTE)buf[0], buflen - 1);
120     if (_lread(hFile, buf, buflen) != buflen)           E(("Can't read descr (%d)\n", buflen));
121     buf[buflen] = '\0';
122     ret = TRUE;
123     TRACE("Got '%s' [%d]\n", buf, buflen);
124 theEnd:
125     CloseHandle(hFile);
126     return ret;
127 }
128
129 /**************************************************************************
130  *                              MMDRV_GetDescription32          [internal]
131  */
132 static  BOOL    MMDRV_GetDescription32(const char* fname, char* buf, int buflen)
133 {
134     OFSTRUCT    ofs;
135     DWORD       h;
136     LPVOID      ptr = 0;
137     LPVOID      val;
138     DWORD       dw;
139     BOOL        ret = FALSE;
140     UINT        u;
141     FARPROC pGetFileVersionInfoSizeA;
142     FARPROC pGetFileVersionInfoA;
143     FARPROC pVerQueryValueA;
144     HMODULE hmodule = 0;
145
146 #define E(_x)   do {TRACE _x;goto theEnd;} while(0)
147
148     if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR)           E(("Can't find file %s\n", fname));
149
150     if (!(hmodule = LoadLibraryA( "version.dll" ))) goto theEnd;
151     if (!(pGetFileVersionInfoSizeA = GetProcAddress( hmodule, "GetFileVersionInfoSizeA" )))
152         goto theEnd;
153     if (!(pGetFileVersionInfoA = GetProcAddress( hmodule, "GetFileVersionInfoA" )))
154         goto theEnd;
155     if (!(pVerQueryValueA = GetProcAddress( hmodule, "pVerQueryValueA" )))
156         goto theEnd;
157
158     if (!(dw = pGetFileVersionInfoSizeA(ofs.szPathName, &h)))   E(("Can't get FVIS\n"));
159     if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw)))            E(("OOM\n"));
160     if (!pGetFileVersionInfoA(ofs.szPathName, h, dw, ptr))      E(("Can't get FVI\n"));
161     
162 #define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
163                   TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
164     
165     A(CompanyName);
166     A(FileDescription);
167     A(FileVersion);
168     A(InternalName);
169     A(LegalCopyright);
170     A(OriginalFilename);
171     A(ProductName);
172     A(ProductVersion);
173     A(Comments);
174     A(LegalTrademarks);
175     A(PrivateBuild);
176     A(SpecialBuild); 
177 #undef A
178
179     if (!pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
180     lstrcpynA(buf, val, buflen);
181
182 #undef E    
183     ret = TRUE;
184 theEnd:
185     HeapFree(GetProcessHeap(), 0, ptr);
186     if (hmodule) FreeLibrary( hmodule );
187     return ret;
188 }
189
190 /**************************************************************************
191  *                              MMDRV_Callback                  [internal]
192  */
193 static void     MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
194 {
195     TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
196           mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
197
198     if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
199         /* 16 bit func, call it */
200         TRACE("Function (16 bit) !\n");
201         MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, hDev, uMsg, 
202                                   mld->dwClientInstance, dwParam1, dwParam2);
203     } else {
204         DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg, 
205                        mld->dwClientInstance, dwParam1, dwParam2);
206     }
207 }
208
209 /* =================================
210  *       A U X    M A P P E R S
211  * ================================= */
212
213 /**************************************************************************
214  *                              MMDRV_Aux_Map16To32A            [internal]
215  */
216 static  MMDRV_MapType   MMDRV_Aux_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
217 {
218     return MMDRV_MAP_MSGERROR;
219 }
220
221 /**************************************************************************
222  *                              MMDRV_Aux_UnMap16To32A          [internal]
223  */
224 static  MMDRV_MapType   MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
225 {
226     return MMDRV_MAP_MSGERROR;
227 }
228
229 /**************************************************************************
230  *                              MMDRV_Aux_Map32ATo16            [internal]
231  */
232 static  MMDRV_MapType   MMDRV_Aux_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
233 {
234     return MMDRV_MAP_MSGERROR;
235 }
236
237 /**************************************************************************
238  *                              MMDRV_Aux_UnMap32ATo16          [internal]
239  */
240 static  MMDRV_MapType   MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
241 {
242 #if 0
243  case AUXDM_GETDEVCAPS:
244     lpCaps->wMid = ac16.wMid;
245     lpCaps->wPid = ac16.wPid;
246     lpCaps->vDriverVersion = ac16.vDriverVersion;
247     strcpy(lpCaps->szPname, ac16.szPname);
248     lpCaps->wTechnology = ac16.wTechnology;
249     lpCaps->dwSupport = ac16.dwSupport;
250 #endif
251     return MMDRV_MAP_MSGERROR;
252 }
253
254 /**************************************************************************
255  *                              MMDRV_Aux_Callback              [internal]
256  */
257 static void     CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
258 {
259     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
260
261     FIXME("NIY\n");
262     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
263 }
264
265 /* =================================
266  *     M I X E R  M A P P E R S
267  * ================================= */
268
269 /**************************************************************************
270  *                              xMMDRV_Mixer_Map16To32A         [internal]
271  */
272 static  MMDRV_MapType   MMDRV_Mixer_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
273 {
274     return MMDRV_MAP_MSGERROR;
275 }
276
277 /**************************************************************************
278  *                              MMDRV_Mixer_UnMap16To32A        [internal]
279  */
280 static  MMDRV_MapType   MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
281 {
282 #if 0
283     MIXERCAPSA  micA;
284     UINT        ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
285     
286     if (ret == MMSYSERR_NOERROR) {
287         mixcaps->wMid           = micA.wMid;
288         mixcaps->wPid           = micA.wPid;
289         mixcaps->vDriverVersion = micA.vDriverVersion;
290         strcpy(mixcaps->szPname, micA.szPname);
291         mixcaps->fdwSupport     = micA.fdwSupport;
292         mixcaps->cDestinations  = micA.cDestinations;
293     }
294     return ret;
295 #endif
296     return MMDRV_MAP_MSGERROR;
297 }
298
299 /**************************************************************************
300  *                              MMDRV_Mixer_Map32ATo16          [internal]
301  */
302 static  MMDRV_MapType   MMDRV_Mixer_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
303 {
304     return MMDRV_MAP_MSGERROR;
305 }
306
307 /**************************************************************************
308  *                              MMDRV_Mixer_UnMap32ATo16        [internal]
309  */
310 static  MMDRV_MapType   MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
311 {
312     return MMDRV_MAP_MSGERROR;
313 }
314
315 /**************************************************************************
316  *                              MMDRV_Mixer_Callback            [internal]
317  */
318 static void     CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
319 {
320     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
321
322     FIXME("NIY\n");
323     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
324 }
325
326 /* =================================
327  *   M I D I  I N    M A P P E R S
328  * ================================= */
329
330 /**************************************************************************
331  *                              MMDRV_MidiIn_Map16To32A         [internal]
332  */
333 static  MMDRV_MapType   MMDRV_MidiIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
334 {
335     return MMDRV_MAP_MSGERROR;
336 }
337
338 /**************************************************************************
339  *                              MMDRV_MidiIn_UnMap16To32A       [internal]
340  */
341 static  MMDRV_MapType   MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
342 {
343     return MMDRV_MAP_MSGERROR;
344 }
345
346 /**************************************************************************
347  *                              MMDRV_MidiIn_Map32ATo16         [internal]
348  */
349 static  MMDRV_MapType   MMDRV_MidiIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
350 {
351     return MMDRV_MAP_MSGERROR;
352 }
353
354 /**************************************************************************
355  *                              MMDRV_MidiIn_UnMap32ATo16       [internal]
356  */
357 static  MMDRV_MapType   MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
358 {
359     return MMDRV_MAP_MSGERROR;
360 }
361
362 /**************************************************************************
363  *                              MMDRV_MidiIn_Callback           [internal]
364  */
365 static void     CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
366 {
367     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
368
369     switch (uMsg) {
370     case MIM_OPEN:
371     case MIM_CLOSE:
372         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
373
374     case MIM_DATA:      
375     case MIM_MOREDATA:  
376     case MIM_ERROR:     
377         /* dwParam1 & dwParam2 are are data, nothing to do */
378         break;
379     case MIM_LONGDATA:
380     case MIM_LONGERROR:
381         /* dwParam1 points to a MidiHdr, work to be done !!! */
382         if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
383             /* initial map is: 32 => 16 */
384             LPMIDIHDR           mh16 = MapSL(dwParam1);
385             LPMIDIHDR           mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
386             
387             dwParam1 = (DWORD)mh32;
388             mh32->dwFlags = mh16->dwFlags;
389             mh32->dwBytesRecorded = mh16->dwBytesRecorded;
390             if (mh32->reserved >= sizeof(MIDIHDR))
391                 mh32->dwOffset = mh16->dwOffset;
392         } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
393             /* initial map is: 16 => 32 */
394             LPMIDIHDR           mh32 = (LPMIDIHDR)(dwParam1);
395             SEGPTR              segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
396             LPMIDIHDR           mh16 = MapSL(segmh16);
397             
398             dwParam1 = (DWORD)segmh16;
399             mh16->dwFlags = mh32->dwFlags;
400             mh16->dwBytesRecorded = mh32->dwBytesRecorded;
401             if (mh16->reserved >= sizeof(MIDIHDR))
402                 mh16->dwOffset = mh32->dwOffset;
403         }       
404         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
405         break;
406     /* case MOM_POSITIONCB: */
407     default:
408         ERR("Unknown msg %u\n", uMsg);
409     }
410
411     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
412 }
413
414 /* =================================
415  *   M I D I  O U T  M A P P E R S
416  * ================================= */
417
418 /**************************************************************************
419  *                              MMDRV_MidiOut_Map16To32A        [internal]
420  */
421 static  MMDRV_MapType   MMDRV_MidiOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
422 {
423     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
424
425     switch (wMsg) {
426     case MODM_GETNUMDEVS:
427     case MODM_DATA:
428     case MODM_RESET:
429     case MODM_SETVOLUME:
430         ret = MMDRV_MAP_OK;
431         break;
432         
433     case MODM_OPEN:
434     case MODM_CLOSE:
435     case MODM_GETVOLUME:
436         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
437         break;
438
439     case MODM_GETDEVCAPS:
440         {
441             LPMIDIOUTCAPSA      moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
442             LPMIDIOUTCAPS16     moc16 = MapSL(*lpParam1);
443
444             if (moc32) {
445                 *(LPMIDIOUTCAPS16*)moc32 = moc16;
446                 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
447                 *lpParam1 = (DWORD)moc32;
448                 *lpParam2 = sizeof(MIDIOUTCAPSA);
449
450                 ret = MMDRV_MAP_OKMEM;
451             } else {
452                 ret = MMDRV_MAP_NOMEM;
453             }
454         }
455         break;
456     case MODM_PREPARE:
457         {
458             LPMIDIHDR           mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
459             LPMIDIHDR           mh16 = MapSL(*lpParam1);
460
461             if (mh32) {
462                 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
463                 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
464                 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
465                 mh32->dwBufferLength = mh16->dwBufferLength;
466                 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
467                 mh32->dwUser = mh16->dwUser;
468                 mh32->dwFlags = mh16->dwFlags;
469                 /* FIXME: nothing on mh32->lpNext */
470                 /* could link the mh32->lpNext at this level for memory house keeping */
471                 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
472                 mh16->lpNext = mh32; /* for reuse in unprepare and write */
473                 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
474                 mh16->reserved = *lpParam2;
475                 *lpParam1 = (DWORD)mh32;
476                 *lpParam2 = sizeof(MIDIHDR);
477
478                 ret = MMDRV_MAP_OKMEM;
479             } else {
480                 ret = MMDRV_MAP_NOMEM;
481             }
482         }
483         break;
484     case MODM_UNPREPARE:
485     case MODM_LONGDATA:
486         {
487             LPMIDIHDR           mh16 = MapSL(*lpParam1);
488             LPMIDIHDR           mh32 = (LPMIDIHDR)mh16->lpNext;
489
490             *lpParam1 = (DWORD)mh32;
491             *lpParam2 = sizeof(MIDIHDR);
492             /* dwBufferLength can be reduced between prepare & write */
493             if (mh32->dwBufferLength < mh16->dwBufferLength) {
494                 ERR("Size of buffer has been increased (%ld, %ld)\n",
495                     mh32->dwBufferLength, mh16->dwBufferLength);
496                 return MMDRV_MAP_MSGERROR;
497             }
498             mh32->dwBufferLength = mh16->dwBufferLength;
499             ret = MMDRV_MAP_OKMEM;
500         }
501         break;
502
503     case MODM_CACHEPATCHES:
504     case MODM_CACHEDRUMPATCHES:
505     default:
506         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
507         break;
508     }
509     return ret;
510 }
511
512 /**************************************************************************
513  *                              MMDRV_MidiOut_UnMap16To32A      [internal]
514  */
515 static  MMDRV_MapType   MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
516 {
517     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
518
519     switch (wMsg) {
520     case MODM_GETNUMDEVS:
521     case MODM_DATA:
522     case MODM_RESET:
523     case MODM_SETVOLUME:
524         ret = MMDRV_MAP_OK;
525         break;
526         
527     case MODM_OPEN:
528     case MODM_CLOSE:
529     case MODM_GETVOLUME:
530         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
531         break;
532
533     case MODM_GETDEVCAPS:
534         {
535             LPMIDIOUTCAPSA              moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
536             LPMIDIOUTCAPS16             moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
537
538             moc16->wMid                 = moc32->wMid;
539             moc16->wPid                 = moc32->wPid;
540             moc16->vDriverVersion       = moc32->vDriverVersion;
541             strcpy(moc16->szPname, moc32->szPname);
542             moc16->wTechnology          = moc32->wTechnology;
543             moc16->wVoices              = moc32->wVoices;
544             moc16->wNotes               = moc32->wNotes;
545             moc16->wChannelMask         = moc32->wChannelMask;
546             moc16->dwSupport            = moc32->dwSupport;
547             HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
548             ret = MMDRV_MAP_OK;
549         }
550         break;
551     case MODM_PREPARE:
552     case MODM_UNPREPARE:
553     case MODM_LONGDATA:
554         {
555             LPMIDIHDR           mh32 = (LPMIDIHDR)(*lpParam1);
556             LPMIDIHDR           mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
557
558             assert(mh16->lpNext == mh32);
559             mh16->dwBufferLength = mh32->dwBufferLength;
560             mh16->dwBytesRecorded = mh32->dwBytesRecorded;
561             mh16->dwUser = mh32->dwUser;
562             mh16->dwFlags = mh32->dwFlags;
563             if (mh16->reserved >= sizeof(MIDIHDR))
564                 mh16->dwOffset = mh32->dwOffset;
565
566             if (wMsg == MODM_UNPREPARE) {
567                 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
568                 mh16->lpNext = 0;
569             }
570             ret = MMDRV_MAP_OK;
571         }
572         break;
573
574     case MODM_CACHEPATCHES:
575     case MODM_CACHEDRUMPATCHES:
576     default:
577         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
578         break;
579     }
580     return ret;
581 }
582
583 /**************************************************************************
584  *                              MMDRV_MidiOut_Map32ATo16        [internal]
585  */
586 static  MMDRV_MapType   MMDRV_MidiOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
587 {
588     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
589
590     switch (wMsg) {
591     case MODM_CLOSE:
592     case MODM_GETNUMDEVS:
593     case MODM_DATA:
594     case MODM_RESET:
595     case MODM_SETVOLUME:
596         ret = MMDRV_MAP_OK;
597         break;
598     case MODM_GETDEVCAPS:
599         {
600             LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
601             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA)+sizeof(MIDIOUTCAPS16));
602
603             if (ptr) {
604                 *(LPMIDIOUTCAPSA*)ptr = moc32;
605                 ret = MMDRV_MAP_OKMEM;
606             } else {
607                 ret = MMDRV_MAP_NOMEM;
608             }
609             *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSA);
610             *lpParam2 = sizeof(MIDIOUTCAPS16);
611         }
612         break;
613     case MODM_PREPARE:
614         {
615             LPMIDIHDR           mh32 = (LPMIDIHDR)*lpParam1;
616             LPMIDIHDR           mh16; 
617             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
618                                     sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
619
620             if (ptr) {
621                 *(LPMIDIHDR*)ptr = mh32;
622                 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
623                 *lpParam1 = MapLS(mh16);
624                 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
625                 /* data will be copied on WODM_WRITE */
626                 mh16->dwBufferLength = mh32->dwBufferLength;
627                 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
628                 mh16->dwUser = mh32->dwUser;
629                 mh16->dwFlags = mh32->dwFlags;
630                 /* FIXME: nothing on mh32->lpNext */
631                 /* could link the mh32->lpNext at this level for memory house keeping */
632                 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
633                     
634                 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
635                 mh32->reserved = *lpParam2;
636
637                 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n", 
638                       *lpParam1, (DWORD)mh16->lpData,
639                       mh32->dwBufferLength, (DWORD)mh32->lpData);
640                 *lpParam2 = sizeof(MIDIHDR);
641
642                 ret = MMDRV_MAP_OKMEM;
643             } else {
644                 ret = MMDRV_MAP_NOMEM;
645             }
646         }
647         break;
648     case MODM_UNPREPARE:
649     case MODM_LONGDATA:
650         {
651             LPMIDIHDR           mh32 = (LPMIDIHDR)(*lpParam1);
652             LPMIDIHDR           mh16 = (LPMIDIHDR)mh32->lpNext;
653             LPSTR               ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
654
655             assert(*(LPMIDIHDR*)ptr == mh32);
656             
657             if (wMsg == MODM_LONGDATA)
658                 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
659
660             *lpParam1 = MapLS(mh16);
661             *lpParam2 = sizeof(MIDIHDR);
662             TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n", 
663                   *lpParam1, (DWORD)mh16->lpData, mh32->dwBufferLength, (DWORD)mh32->lpData);
664
665             /* dwBufferLength can be reduced between prepare & write */
666             if (mh16->dwBufferLength < mh32->dwBufferLength) {
667                 ERR("Size of buffer has been increased (%ld, %ld)\n",
668                     mh16->dwBufferLength, mh32->dwBufferLength);
669                 return MMDRV_MAP_MSGERROR;
670             }
671             mh16->dwBufferLength = mh32->dwBufferLength;
672             ret = MMDRV_MAP_OKMEM;
673         }
674         break;
675     case MODM_OPEN:
676         {
677             LPMIDIOPENDESC              mod32 = (LPMIDIOPENDESC)*lpParam1;
678             LPVOID                      ptr;
679             LPMIDIOPENDESC16            mod16;
680
681             /* allocated data are mapped as follows:
682                LPMIDIOPENDESC   ptr to orig lParam1
683                DWORD            orig dwUser, which is a pointer to DWORD:driver dwInstance
684                DWORD            dwUser passed to driver
685                MIDIOPENDESC16   mod16: openDesc passed to driver
686                MIDIOPENSTRMID   cIds 
687             */
688             ptr = HeapAlloc( GetProcessHeap(), 0,
689                              sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
690                              mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
691
692             if (ptr) {
693                 SEGPTR segptr = MapLS(ptr);
694                 *(LPMIDIOPENDESC*)ptr = mod32;
695                 *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
696                 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
697
698                 mod16->hMidi = mod32->hMidi;
699                 mod16->dwCallback = mod32->dwCallback;
700                 mod16->dwInstance = mod32->dwInstance;
701                 mod16->dnDevNode = mod32->dnDevNode;
702                 mod16->cIds = mod32->cIds;
703                 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
704
705                 *lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
706                 *lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
707
708                 ret = MMDRV_MAP_OKMEM;
709             } else {
710                 ret = MMDRV_MAP_NOMEM;
711             }
712         }
713         break;
714     case MODM_GETVOLUME:
715     case MODM_CACHEPATCHES:
716     case MODM_CACHEDRUMPATCHES:
717     default:
718         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
719         break;
720     }
721     return ret;
722 }
723
724 /**************************************************************************
725  *                              MMDRV_MidiOut_UnMap32ATo16      [internal]
726  */
727 static  MMDRV_MapType   MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
728 {
729     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
730
731     switch (wMsg) {
732     case MODM_CLOSE:
733     case MODM_GETNUMDEVS:
734     case MODM_DATA:
735     case MODM_RESET:
736     case MODM_SETVOLUME:
737         ret = MMDRV_MAP_OK;
738         break;
739     case MODM_GETDEVCAPS:
740         {
741             LPMIDIOUTCAPS16             moc16 = MapSL(*lpParam1);
742             LPSTR                       ptr   = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
743             LPMIDIOUTCAPSA              moc32 = *(LPMIDIOUTCAPSA*)ptr;
744
745             moc32->wMid                 = moc16->wMid;
746             moc32->wPid                 = moc16->wPid;
747             moc32->vDriverVersion       = moc16->vDriverVersion;
748             strcpy(moc32->szPname, moc16->szPname);
749             moc32->wTechnology          = moc16->wTechnology;
750             moc32->wVoices              = moc16->wVoices;
751             moc32->wNotes               = moc16->wNotes;
752             moc32->wChannelMask         = moc16->wChannelMask;
753             moc32->dwSupport            = moc16->dwSupport;
754             UnMapLS( *lpParam1 );
755             HeapFree( GetProcessHeap(), 0, ptr );
756             ret = MMDRV_MAP_OK;
757         }
758         break;
759     case MODM_PREPARE:
760     case MODM_UNPREPARE:
761     case MODM_LONGDATA:
762         {
763             LPMIDIHDR           mh16 = MapSL(*lpParam1);
764             LPSTR               ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
765             LPMIDIHDR           mh32 = *(LPMIDIHDR*)ptr;
766
767             assert(mh32->lpNext == (LPMIDIHDR)mh16);
768             UnMapLS( *lpParam1 );
769             mh32->dwBytesRecorded = mh16->dwBytesRecorded;
770             mh32->dwUser = mh16->dwUser;
771             mh32->dwFlags = mh16->dwFlags;
772
773             if (wMsg == MODM_UNPREPARE) {
774                 HeapFree( GetProcessHeap(), 0, ptr );
775                 mh32->lpNext = 0;
776             }
777             ret = MMDRV_MAP_OK;
778         }
779         break;
780     case MODM_OPEN:
781         {
782             LPMIDIOPENDESC16            mod16 = MapSL(*lpParam1);
783             LPSTR                       ptr   = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
784             UnMapLS( *lpParam1 );
785             **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
786
787             HeapFree( GetProcessHeap(), 0, ptr );
788             ret = MMDRV_MAP_OK;
789         }
790         break;
791     case MODM_GETVOLUME:
792     case MODM_CACHEPATCHES:
793     case MODM_CACHEDRUMPATCHES:
794     default:
795         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
796         break;
797     }
798     return ret;
799 }
800
801 /**************************************************************************
802  *                              MMDRV_MidiOut_Callback          [internal]
803  */
804 static void     CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
805 {
806     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
807
808     switch (uMsg) {
809     case MOM_OPEN:
810     case MOM_CLOSE:
811         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
812         break;
813     case MOM_DONE:
814         if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
815             /* initial map is: 32 => 16 */
816             LPMIDIHDR           mh16 = MapSL(dwParam1);
817             LPMIDIHDR           mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
818             
819             dwParam1 = (DWORD)mh32;
820             mh32->dwFlags = mh16->dwFlags;
821             mh32->dwOffset = mh16->dwOffset;
822             if (mh32->reserved >= sizeof(MIDIHDR))
823                 mh32->dwOffset = mh16->dwOffset;
824         } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
825             /* initial map is: 16 => 32 */
826             LPMIDIHDR           mh32 = (LPMIDIHDR)(dwParam1);
827             SEGPTR              segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
828             LPMIDIHDR           mh16 = MapSL(segmh16);
829             
830             dwParam1 = (DWORD)segmh16;
831             mh16->dwFlags = mh32->dwFlags;
832             if (mh16->reserved >= sizeof(MIDIHDR))
833                 mh16->dwOffset = mh32->dwOffset;
834         }       
835         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
836         break;
837     /* case MOM_POSITIONCB: */
838     default:
839         ERR("Unknown msg %u\n", uMsg);
840     }
841
842     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
843 }
844
845 /* =================================
846  *   W A V E  I N    M A P P E R S
847  * ================================= */
848
849 /**************************************************************************
850  *                              MMDRV_WaveIn_Map16To32A         [internal]
851  */
852 static  MMDRV_MapType   MMDRV_WaveIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
853 {
854     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
855
856     switch (wMsg) {
857     case WIDM_GETNUMDEVS:
858     case WIDM_RESET:
859     case WIDM_START:
860     case WIDM_STOP:
861         ret = MMDRV_MAP_OK;
862         break;
863     case WIDM_OPEN:
864     case WIDM_CLOSE:
865         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
866         break;
867     case WIDM_GETDEVCAPS:
868         {
869             LPWAVEINCAPSA       wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
870             LPWAVEINCAPS16      wic16 = MapSL(*lpParam1);
871
872             if (wic32) {
873                 *(LPWAVEINCAPS16*)wic32 = wic16;
874                 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
875                 *lpParam1 = (DWORD)wic32;
876                 *lpParam2 = sizeof(WAVEINCAPSA);
877
878                 ret = MMDRV_MAP_OKMEM;
879             } else {
880                 ret = MMDRV_MAP_NOMEM;
881             }
882         }
883         break;
884     case WIDM_GETPOS:
885         {
886             LPMMTIME            mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
887             LPMMTIME16          mmt16 = MapSL(*lpParam1);
888
889             if (mmt32) {
890                 *(LPMMTIME16*)mmt32 = mmt16;
891                 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
892
893                 mmt32->wType = mmt16->wType;
894                 *lpParam1 = (DWORD)mmt32;
895                 *lpParam2 = sizeof(MMTIME);
896
897                 ret = MMDRV_MAP_OKMEM;
898             } else {
899                 ret = MMDRV_MAP_NOMEM;
900             }
901         }
902         break;
903     case WIDM_PREPARE:
904         {
905             LPWAVEHDR           wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
906             LPWAVEHDR           wh16 = MapSL(*lpParam1);
907
908             if (wh32) {
909                 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
910                 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
911                 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
912                 wh32->dwBufferLength = wh16->dwBufferLength;
913                 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
914                 wh32->dwUser = wh16->dwUser;
915                 wh32->dwFlags = wh16->dwFlags;
916                 wh32->dwLoops = wh16->dwLoops;
917                 /* FIXME: nothing on wh32->lpNext */
918                 /* could link the wh32->lpNext at this level for memory house keeping */
919                 wh16->lpNext = wh32; /* for reuse in unprepare and write */
920                 *lpParam1 = (DWORD)wh32;
921                 *lpParam2 = sizeof(WAVEHDR);
922
923                 ret = MMDRV_MAP_OKMEM;
924             } else {
925                 ret = MMDRV_MAP_NOMEM;
926             }
927         }
928         break;
929     case WIDM_ADDBUFFER:
930     case WIDM_UNPREPARE:
931         {
932             LPWAVEHDR           wh16 = MapSL(*lpParam1);
933             LPWAVEHDR           wh32 = (LPWAVEHDR)wh16->lpNext;
934
935             *lpParam1 = (DWORD)wh32;
936             *lpParam2 = sizeof(WAVEHDR);
937             /* dwBufferLength can be reduced between prepare & write */
938             if (wh32->dwBufferLength < wh16->dwBufferLength) {
939                 ERR("Size of buffer has been increased (%ld, %ld)\n",
940                     wh32->dwBufferLength, wh16->dwBufferLength);
941                 return MMDRV_MAP_MSGERROR;
942             }
943             wh32->dwBufferLength = wh16->dwBufferLength;
944             ret = MMDRV_MAP_OKMEM;
945         }
946         break;
947     case WIDM_MAPPER_STATUS:
948         /* just a single DWORD */
949         *lpParam2 = (DWORD)MapSL(*lpParam2);
950         ret = MMDRV_MAP_OK;
951         break;
952     default:
953         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
954         break;
955     }
956     return ret;
957 }
958
959 /**************************************************************************
960  *                              MMDRV_WaveIn_UnMap16To32A       [internal]
961  */
962 static  MMDRV_MapType   MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
963 {
964     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
965
966     switch (wMsg) {
967     case WIDM_GETNUMDEVS:
968     case WIDM_RESET:
969     case WIDM_START:
970     case WIDM_STOP:
971     case WIDM_MAPPER_STATUS:
972         ret = MMDRV_MAP_OK;
973         break;
974     case WIDM_OPEN:
975     case WIDM_CLOSE:
976         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
977         break;
978     case WIDM_GETDEVCAPS:
979         {
980             LPWAVEINCAPSA               wic32 = (LPWAVEINCAPSA)(*lpParam1);
981             LPWAVEINCAPS16              wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
982
983             wic16->wMid = wic32->wMid;
984             wic16->wPid = wic32->wPid; 
985             wic16->vDriverVersion = wic32->vDriverVersion; 
986             strcpy(wic16->szPname, wic32->szPname);
987             wic16->dwFormats = wic32->dwFormats; 
988             wic16->wChannels = wic32->wChannels; 
989             HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
990             ret = MMDRV_MAP_OK;
991         }
992         break;
993     case WIDM_GETPOS:
994         {
995             LPMMTIME            mmt32 = (LPMMTIME)(*lpParam1);
996             LPMMTIME16          mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
997
998             MMSYSTEM_MMTIME32to16(mmt16, mmt32);
999             HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1000             ret = MMDRV_MAP_OK;
1001         }
1002         break;
1003     case WIDM_ADDBUFFER:
1004     case WIDM_PREPARE:
1005     case WIDM_UNPREPARE:
1006         {
1007             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
1008             LPWAVEHDR           wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1009
1010             assert(wh16->lpNext == wh32);
1011             wh16->dwBufferLength = wh32->dwBufferLength;
1012             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1013             wh16->dwUser = wh32->dwUser;
1014             wh16->dwFlags = wh32->dwFlags;
1015             wh16->dwLoops = wh32->dwLoops;
1016
1017             if (wMsg == WIDM_UNPREPARE) {
1018                 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1019                 wh16->lpNext = 0;
1020             }
1021             ret = MMDRV_MAP_OK;
1022         }
1023         break;
1024     default:
1025         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1026         break;
1027     }
1028     return ret;
1029 }
1030
1031 /**************************************************************************
1032  *                              MMDRV_WaveIn_Map32ATo16         [internal]
1033  */
1034 static  MMDRV_MapType   MMDRV_WaveIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1035 {
1036     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
1037
1038     switch (wMsg) {
1039     case WIDM_CLOSE:
1040     case WIDM_GETNUMDEVS:
1041     case WIDM_RESET:
1042     case WIDM_START:
1043     case WIDM_STOP:
1044         ret = MMDRV_MAP_OK;
1045         break;
1046
1047     case WIDM_OPEN:
1048         {
1049             LPWAVEOPENDESC              wod32 = (LPWAVEOPENDESC)*lpParam1;
1050             int                         sz = sizeof(WAVEFORMATEX);
1051             LPVOID                      ptr;
1052             LPWAVEOPENDESC16            wod16;
1053
1054             /* allocated data are mapped as follows:
1055                LPWAVEOPENDESC   ptr to orig lParam1
1056                DWORD            orig dwUser, which is a pointer to DWORD:driver dwInstance
1057                DWORD            dwUser passed to driver
1058                WAVEOPENDESC16   wod16: openDesc passed to driver
1059                WAVEFORMATEX     openDesc->lpFormat passed to driver
1060                xxx              extra bytes to WAVEFORMATEX
1061             */
1062             if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1063                 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1064                 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1065             }
1066
1067             ptr = HeapAlloc( GetProcessHeap(), 0,
1068                              sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1069
1070             if (ptr) {
1071                 SEGPTR seg_ptr = MapLS( ptr );
1072                 *(LPWAVEOPENDESC*)ptr = wod32;
1073                 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1074                 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1075
1076                 wod16->hWave = wod32->hWave;
1077                 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1078                 memcpy(wod16 + 1, wod32->lpFormat, sz);
1079                 
1080                 wod16->dwCallback = wod32->dwCallback;
1081                 wod16->dwInstance = wod32->dwInstance;
1082                 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1083                 wod16->dnDevNode = wod32->dnDevNode;
1084                 
1085                 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1086                 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1087
1088                 ret = MMDRV_MAP_OKMEM;
1089             } else {
1090                 ret = MMDRV_MAP_NOMEM;
1091             }
1092         }
1093         break;
1094     case WIDM_PREPARE:
1095         {
1096             LPWAVEHDR           wh32 = (LPWAVEHDR)*lpParam1;
1097             LPWAVEHDR           wh16; 
1098             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1099                                     sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1100
1101             if (ptr) {
1102                 SEGPTR seg_ptr = MapLS( ptr );
1103                 *(LPWAVEHDR*)ptr = wh32;
1104                 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1105                 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1106                 /* data will be copied on WODM_WRITE */
1107                 wh16->dwBufferLength = wh32->dwBufferLength;
1108                 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1109                 wh16->dwUser = wh32->dwUser;
1110                 wh16->dwFlags = wh32->dwFlags;
1111                 wh16->dwLoops = wh32->dwLoops;
1112                 /* FIXME: nothing on wh32->lpNext */
1113                 /* could link the wh32->lpNext at this level for memory house keeping */
1114                 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1115                 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n", 
1116                       seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1117                       wh32->dwBufferLength, (DWORD)wh32->lpData);
1118                 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1119                 *lpParam2 = sizeof(WAVEHDR);
1120
1121                 ret = MMDRV_MAP_OKMEM;
1122             } else {
1123                 ret = MMDRV_MAP_NOMEM;
1124             }
1125         }
1126         break;
1127     case WIDM_ADDBUFFER:
1128     case WIDM_UNPREPARE:
1129         {
1130             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
1131             LPWAVEHDR           wh16 = wh32->lpNext;
1132             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1133             SEGPTR seg_ptr = MapLS( ptr );
1134
1135             assert(*(LPWAVEHDR*)ptr == wh32);
1136             
1137             TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n", 
1138                   seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1139                   wh32->dwBufferLength, (DWORD)wh32->lpData);
1140
1141             if (wMsg == WIDM_ADDBUFFER)
1142                 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1143
1144             *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1145             *lpParam2 = sizeof(WAVEHDR);
1146             /* dwBufferLength can be reduced between prepare & write */
1147             if (wh32->dwBufferLength < wh16->dwBufferLength) {
1148                 ERR("Size of buffer has been increased (%ld, %ld)\n",
1149                     wh32->dwBufferLength, wh16->dwBufferLength);
1150                 return MMDRV_MAP_MSGERROR;
1151             }
1152             wh32->dwBufferLength = wh16->dwBufferLength;
1153             ret = MMDRV_MAP_OKMEM;
1154         }
1155         break;
1156    case WIDM_GETDEVCAPS:
1157         {
1158             LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
1159             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
1160
1161             if (ptr) {
1162                 *(LPWAVEINCAPSA*)ptr = wic32;
1163                 ret = MMDRV_MAP_OKMEM;
1164             } else {
1165                 ret = MMDRV_MAP_NOMEM;
1166             }
1167             *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSA);
1168             *lpParam2 = sizeof(WAVEINCAPS16);
1169         }
1170         break;
1171     case WIDM_GETPOS:
1172         {
1173             LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1174             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1175             LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1176
1177             if (ptr) {
1178                 *(LPMMTIME*)ptr = mmt32;
1179                 mmt16->wType = mmt32->wType;
1180                 ret = MMDRV_MAP_OKMEM;
1181             } else {
1182                 ret = MMDRV_MAP_NOMEM;
1183             }
1184             *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1185             *lpParam2 = sizeof(MMTIME16);
1186         }
1187         break;
1188     case DRVM_MAPPER_STATUS:
1189         {
1190             LPDWORD p32 = (LPDWORD)*lpParam2;
1191             *lpParam2 = MapLS(p32);
1192             ret = MMDRV_MAP_OKMEM;
1193         }
1194         break;
1195     default:
1196         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1197         break;
1198     }
1199     return ret;
1200 }
1201
1202 /**************************************************************************
1203  *                              MMDRV_WaveIn_UnMap32ATo16       [internal]
1204  */
1205 static  MMDRV_MapType   MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1206 {
1207     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
1208
1209     switch (wMsg) {
1210     case WIDM_CLOSE:
1211     case WIDM_GETNUMDEVS:
1212     case WIDM_RESET:
1213     case WIDM_START:
1214     case WIDM_STOP:
1215         ret = MMDRV_MAP_OK;
1216         break;
1217
1218     case WIDM_OPEN:
1219         {
1220             LPWAVEOPENDESC16            wod16 = MapSL(*lpParam1);
1221             LPSTR                       ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1222             LPWAVEOPENDESC              wod32 = *(LPWAVEOPENDESC*)ptr;
1223
1224             UnMapLS( *lpParam1 );
1225             wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1226             **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1227             HeapFree( GetProcessHeap(), 0, ptr );
1228             ret = MMDRV_MAP_OK;
1229         }
1230         break;
1231
1232     case WIDM_ADDBUFFER:
1233     case WIDM_PREPARE:
1234     case WIDM_UNPREPARE:
1235         {
1236             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1237             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1238             LPWAVEHDR           wh32 = *(LPWAVEHDR*)ptr;
1239
1240             assert(wh32->lpNext == wh16);
1241             wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1242             wh32->dwUser = wh16->dwUser;
1243             wh32->dwFlags = wh16->dwFlags;
1244             wh32->dwLoops = wh16->dwLoops;
1245             UnMapLS( *lpParam1 );
1246
1247             if (wMsg == WIDM_UNPREPARE) {
1248                 HeapFree( GetProcessHeap(), 0, ptr );
1249                 wh32->lpNext = 0;
1250             }
1251             ret = MMDRV_MAP_OK;
1252         }
1253         break;
1254      case WIDM_GETDEVCAPS:
1255         {
1256             LPWAVEINCAPS16              wic16 = MapSL(*lpParam1);
1257             LPSTR                       ptr   = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1258             LPWAVEINCAPSA               wic32 = *(LPWAVEINCAPSA*)ptr;
1259
1260             wic32->wMid = wic16->wMid;
1261             wic32->wPid = wic16->wPid;
1262             wic32->vDriverVersion = wic16->vDriverVersion;
1263             strcpy(wic32->szPname, wic16->szPname);
1264             wic32->dwFormats = wic16->dwFormats;
1265             wic32->wChannels = wic16->wChannels;
1266             UnMapLS( *lpParam1 );
1267             HeapFree( GetProcessHeap(), 0, ptr );
1268             ret = MMDRV_MAP_OK;
1269         }
1270         break;
1271     case WIDM_GETPOS:
1272         {
1273             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1274             LPSTR               ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
1275             LPMMTIME            mmt32 = *(LPMMTIME*)ptr;
1276
1277             MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1278             UnMapLS( *lpParam1 );
1279             HeapFree( GetProcessHeap(), 0, ptr );
1280             ret = MMDRV_MAP_OK;
1281         }
1282         break;
1283     case DRVM_MAPPER_STATUS:
1284         {
1285             UnMapLS( *lpParam2 );
1286             ret = MMDRV_MAP_OK;
1287         }
1288         break;
1289     default:
1290         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1291         break;
1292     }
1293     return ret;
1294 }
1295
1296 /**************************************************************************
1297  *                              MMDRV_WaveIn_Callback           [internal]
1298  */
1299 static void     CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1300 {
1301     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
1302
1303     switch (uMsg) {
1304     case WIM_OPEN:
1305     case WIM_CLOSE:
1306         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1307         break;
1308     case WIM_DATA:
1309         if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1310             /* initial map is: 32 => 16 */
1311             LPWAVEHDR           wh16 = MapSL(dwParam1);
1312             LPWAVEHDR           wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1313             
1314             dwParam1 = (DWORD)wh32;
1315             wh32->dwFlags = wh16->dwFlags;
1316             wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1317         } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1318             /* initial map is: 16 => 32 */
1319             LPWAVEHDR           wh32 = (LPWAVEHDR)(dwParam1);
1320             SEGPTR              segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1321             LPWAVEHDR           wh16 = MapSL(segwh16);
1322             
1323             dwParam1 = (DWORD)segwh16;
1324             wh16->dwFlags = wh32->dwFlags;
1325             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1326         }       
1327         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1328         break;
1329     default:
1330         ERR("Unknown msg %u\n", uMsg);
1331     }
1332
1333     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1334 }
1335
1336 /* =================================
1337  *   W A V E  O U T  M A P P E R S
1338  * ================================= */
1339
1340 /**************************************************************************
1341  *                              MMDRV_WaveOut_Map16To32A        [internal]
1342  */
1343 static  MMDRV_MapType   MMDRV_WaveOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1344 {
1345     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
1346
1347     switch (wMsg) {
1348     /* nothing to do */
1349     case WODM_BREAKLOOP:
1350     case WODM_CLOSE:
1351     case WODM_GETNUMDEVS:
1352     case WODM_PAUSE:
1353     case WODM_RESET:
1354     case WODM_RESTART:
1355     case WODM_SETPITCH:
1356     case WODM_SETPLAYBACKRATE:
1357     case WODM_SETVOLUME:
1358         ret = MMDRV_MAP_OK;
1359         break;
1360
1361     case WODM_GETPITCH:
1362     case WODM_GETPLAYBACKRATE:
1363     case WODM_GETVOLUME:
1364     case WODM_OPEN:
1365         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1366         break;
1367
1368     case WODM_GETDEVCAPS: 
1369         {
1370             LPWAVEOUTCAPSA              woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1371             LPWAVEOUTCAPS16             woc16 = MapSL(*lpParam1);
1372
1373             if (woc32) {
1374                 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1375                 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1376                 *lpParam1 = (DWORD)woc32;
1377                 *lpParam2 = sizeof(WAVEOUTCAPSA);
1378
1379                 ret = MMDRV_MAP_OKMEM;
1380             } else {
1381                 ret = MMDRV_MAP_NOMEM;
1382             }
1383         }
1384         break;
1385     case WODM_GETPOS:
1386         {
1387             LPMMTIME            mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1388             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1389
1390             if (mmt32) {
1391                 *(LPMMTIME16*)mmt32 = mmt16;
1392                 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1393
1394                 mmt32->wType = mmt16->wType;
1395                 *lpParam1 = (DWORD)mmt32;
1396                 *lpParam2 = sizeof(MMTIME);
1397
1398                 ret = MMDRV_MAP_OKMEM;
1399             } else {
1400                 ret = MMDRV_MAP_NOMEM;
1401             }
1402         }
1403         break;
1404     case WODM_PREPARE:
1405         {
1406             LPWAVEHDR           wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1407             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1408
1409             if (wh32) {
1410                 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1411                 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1412                 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1413                 wh32->dwBufferLength = wh16->dwBufferLength;
1414                 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1415                 wh32->dwUser = wh16->dwUser;
1416                 wh32->dwFlags = wh16->dwFlags;
1417                 wh32->dwLoops = wh16->dwLoops;
1418                 /* FIXME: nothing on wh32->lpNext */
1419                 /* could link the wh32->lpNext at this level for memory house keeping */
1420                 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1421                 *lpParam1 = (DWORD)wh32;
1422                 *lpParam2 = sizeof(WAVEHDR);
1423
1424                 ret = MMDRV_MAP_OKMEM;
1425             } else {
1426                 ret = MMDRV_MAP_NOMEM;
1427             }
1428         }
1429         break;
1430     case WODM_UNPREPARE:
1431     case WODM_WRITE:
1432         {
1433             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1434             LPWAVEHDR           wh32 = (LPWAVEHDR)wh16->lpNext;
1435
1436             *lpParam1 = (DWORD)wh32;
1437             *lpParam2 = sizeof(WAVEHDR);
1438             /* dwBufferLength can be reduced between prepare & write */
1439             if (wh32->dwBufferLength < wh16->dwBufferLength) {
1440                 ERR("Size of buffer has been increased (%ld, %ld)\n",
1441                     wh32->dwBufferLength, wh16->dwBufferLength);
1442                 return MMDRV_MAP_MSGERROR;
1443             }
1444             wh32->dwBufferLength = wh16->dwBufferLength;
1445             ret = MMDRV_MAP_OKMEM;
1446         }
1447         break;
1448     case WODM_MAPPER_STATUS:
1449         *lpParam2 = (DWORD)MapSL(*lpParam2);
1450         ret = MMDRV_MAP_OK;
1451         break;
1452     default:
1453         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1454         break;
1455     }
1456     return ret;
1457 }
1458
1459 /**************************************************************************
1460  *                              MMDRV_WaveOut_UnMap16To32A      [internal]
1461  */
1462 static  MMDRV_MapType   MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1463 {
1464     MMDRV_MapType       ret = MMDRV_MAP_MSGERROR;
1465
1466     switch (wMsg) {
1467     /* nothing to do */
1468     case WODM_BREAKLOOP:
1469     case WODM_CLOSE:
1470     case WODM_GETNUMDEVS:
1471     case WODM_PAUSE:
1472     case WODM_RESET:
1473     case WODM_RESTART:
1474     case WODM_SETPITCH:
1475     case WODM_SETPLAYBACKRATE:
1476     case WODM_SETVOLUME:
1477     case WODM_MAPPER_STATUS:
1478         ret = MMDRV_MAP_OK;
1479         break;
1480
1481     case WODM_GETPITCH:
1482     case WODM_GETPLAYBACKRATE:
1483     case WODM_GETVOLUME:
1484     case WODM_OPEN:
1485         FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1486         break;
1487         
1488     case WODM_GETDEVCAPS: 
1489         {
1490             LPWAVEOUTCAPSA              woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1491             LPWAVEOUTCAPS16             woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1492
1493             woc16->wMid = woc32->wMid;
1494             woc16->wPid = woc32->wPid; 
1495             woc16->vDriverVersion = woc32->vDriverVersion; 
1496             strcpy(woc16->szPname, woc32->szPname);
1497             woc16->dwFormats = woc32->dwFormats; 
1498             woc16->wChannels = woc32->wChannels; 
1499             woc16->dwSupport = woc32->dwSupport; 
1500             HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1501             ret = MMDRV_MAP_OK;
1502         }
1503         break;
1504     case WODM_GETPOS:
1505         {
1506             LPMMTIME            mmt32 = (LPMMTIME)(*lpParam1);
1507             LPMMTIME16          mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1508
1509             MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1510             HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1511             ret = MMDRV_MAP_OK;
1512         }
1513         break;
1514     case WODM_PREPARE:
1515     case WODM_UNPREPARE:
1516     case WODM_WRITE:
1517         {
1518             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
1519             LPWAVEHDR           wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1520
1521             assert(wh16->lpNext == wh32);
1522             wh16->dwBufferLength = wh32->dwBufferLength;
1523             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1524             wh16->dwUser = wh32->dwUser;
1525             wh16->dwFlags = wh32->dwFlags;
1526             wh16->dwLoops = wh32->dwLoops;
1527
1528             if (wMsg == WODM_UNPREPARE) {
1529                 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1530                 wh16->lpNext = 0;
1531             }
1532             ret = MMDRV_MAP_OK;
1533         }
1534         break;
1535     default:
1536         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1537         break;
1538     }
1539     return ret;
1540 }
1541
1542 /**************************************************************************
1543  *                              MMDRV_WaveOut_Map32ATo16        [internal]
1544  */
1545 static  MMDRV_MapType   MMDRV_WaveOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1546 {
1547     MMDRV_MapType       ret;
1548
1549     switch (wMsg) {
1550         /* nothing to do */
1551     case WODM_BREAKLOOP:
1552     case WODM_CLOSE:
1553     case WODM_GETNUMDEVS:
1554     case WODM_PAUSE:
1555     case WODM_RESET:
1556     case WODM_RESTART:
1557     case WODM_SETPITCH:
1558     case WODM_SETPLAYBACKRATE:
1559     case WODM_SETVOLUME:
1560         ret = MMDRV_MAP_OK;
1561         break;
1562         
1563     case WODM_GETDEVCAPS:
1564         {
1565             LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1566             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1567                                    sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1568
1569             if (ptr) {
1570                 *(LPWAVEOUTCAPSA*)ptr = woc32;
1571                 ret = MMDRV_MAP_OKMEM;
1572             } else {
1573                 ret = MMDRV_MAP_NOMEM;
1574             }
1575             *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSA);
1576             *lpParam2 = sizeof(WAVEOUTCAPS16);
1577         }
1578         break;
1579     case WODM_GETPITCH:
1580         FIXME("NIY: no conversion yet\n");
1581         ret = MMDRV_MAP_MSGERROR;
1582         break;
1583     case WODM_GETPLAYBACKRATE:
1584         FIXME("NIY: no conversion yet\n");
1585         ret = MMDRV_MAP_MSGERROR;
1586         break;
1587     case WODM_GETPOS:
1588         {
1589             LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1590             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1591             LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1592
1593             if (ptr) {
1594                 *(LPMMTIME*)ptr = mmt32;
1595                 mmt16->wType = mmt32->wType;
1596                 ret = MMDRV_MAP_OKMEM;
1597             } else {
1598                 ret = MMDRV_MAP_NOMEM;
1599             }
1600             *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1601             *lpParam2 = sizeof(MMTIME16);
1602         }
1603         break;
1604     case WODM_GETVOLUME:
1605         FIXME("NIY: no conversion yet\n");
1606         ret = MMDRV_MAP_MSGERROR;
1607         break;
1608     case WODM_OPEN:
1609         {
1610             LPWAVEOPENDESC              wod32 = (LPWAVEOPENDESC)*lpParam1;
1611             int                         sz = sizeof(WAVEFORMATEX);
1612             LPVOID                      ptr;
1613             LPWAVEOPENDESC16            wod16;
1614
1615             /* allocated data are mapped as follows:
1616                LPWAVEOPENDESC   ptr to orig lParam1
1617                DWORD            orig dwUser, which is a pointer to DWORD:driver dwInstance
1618                DWORD            dwUser passed to driver
1619                WAVEOPENDESC16   wod16: openDesc passed to driver
1620                WAVEFORMATEX     openDesc->lpFormat passed to driver
1621                xxx              extra bytes to WAVEFORMATEX
1622             */
1623             if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1624                 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1625                 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1626             }
1627
1628             ptr = HeapAlloc( GetProcessHeap(), 0,
1629                              sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1630
1631             if (ptr) {
1632                 SEGPTR seg_ptr = MapLS( ptr );
1633                 *(LPWAVEOPENDESC*)ptr = wod32;
1634                 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1635                 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1636
1637                 wod16->hWave = wod32->hWave;
1638                 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1639                 memcpy(wod16 + 1, wod32->lpFormat, sz);
1640                 
1641                 wod16->dwCallback = wod32->dwCallback;
1642                 wod16->dwInstance = wod32->dwInstance;
1643                 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1644                 wod16->dnDevNode = wod32->dnDevNode;
1645                 
1646                 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1647                 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1648
1649                 ret = MMDRV_MAP_OKMEM;
1650             } else {
1651                 ret = MMDRV_MAP_NOMEM;
1652             }
1653         }
1654         break;
1655     case WODM_PREPARE:
1656         {
1657             LPWAVEHDR           wh32 = (LPWAVEHDR)*lpParam1;
1658             LPWAVEHDR           wh16; 
1659             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1660                                     sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1661
1662             if (ptr) {
1663                 SEGPTR seg_ptr = MapLS( ptr );
1664                 *(LPWAVEHDR*)ptr = wh32;
1665                 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1666                 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1667                 /* data will be copied on WODM_WRITE */
1668                 wh16->dwBufferLength = wh32->dwBufferLength;
1669                 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1670                 wh16->dwUser = wh32->dwUser;
1671                 wh16->dwFlags = wh32->dwFlags;
1672                 wh16->dwLoops = wh32->dwLoops;
1673                 /* FIXME: nothing on wh32->lpNext */
1674                 /* could link the wh32->lpNext at this level for memory house keeping */
1675                 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1676                 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n", 
1677                       seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1678                       wh32->dwBufferLength, (DWORD)wh32->lpData);
1679                 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1680                 *lpParam2 = sizeof(WAVEHDR);
1681
1682                 ret = MMDRV_MAP_OKMEM;
1683             } else {
1684                 ret = MMDRV_MAP_NOMEM;
1685             }
1686         }
1687         break;
1688     case WODM_UNPREPARE:
1689     case WODM_WRITE:
1690         {
1691             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
1692             LPWAVEHDR           wh16 = wh32->lpNext;
1693             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1694             SEGPTR seg_ptr = MapLS( ptr );
1695
1696             assert(*(LPWAVEHDR*)ptr == wh32);
1697             
1698             TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n", 
1699                   seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1700                   wh32->dwBufferLength, (DWORD)wh32->lpData);
1701
1702             if (wMsg == WODM_WRITE)
1703                 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1704
1705             *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1706             *lpParam2 = sizeof(WAVEHDR);
1707             /* dwBufferLength can be reduced between prepare & write */
1708             if (wh16->dwBufferLength < wh32->dwBufferLength) {
1709                 ERR("Size of buffer has been increased (%ld, %ld)\n",
1710                     wh16->dwBufferLength, wh32->dwBufferLength);
1711                 return MMDRV_MAP_MSGERROR;
1712             }
1713             wh16->dwBufferLength = wh32->dwBufferLength;
1714             ret = MMDRV_MAP_OKMEM;
1715         }
1716         break;
1717     case DRVM_MAPPER_STATUS:
1718         {
1719             LPDWORD p32 = (LPDWORD)*lpParam2;
1720             *lpParam2 = MapLS(p32);
1721             ret = MMDRV_MAP_OKMEM;
1722         }
1723         break;
1724     default:
1725         FIXME("NIY: no conversion yet\n");
1726         ret = MMDRV_MAP_MSGERROR;
1727         break;
1728     }
1729     return ret;
1730 }
1731
1732 /**************************************************************************
1733  *                              MMDRV_WaveOut_UnMap32ATo16      [internal]
1734  */
1735 static  MMDRV_MapType   MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1736 {
1737     MMDRV_MapType       ret;
1738
1739     switch (wMsg) {
1740         /* nothing to do */
1741     case WODM_BREAKLOOP:
1742     case WODM_CLOSE:
1743     case WODM_GETNUMDEVS:
1744     case WODM_PAUSE:
1745     case WODM_RESET:
1746     case WODM_RESTART:
1747     case WODM_SETPITCH:
1748     case WODM_SETPLAYBACKRATE:
1749     case WODM_SETVOLUME:
1750         ret = MMDRV_MAP_OK;
1751         break;
1752         
1753     case WODM_GETDEVCAPS:
1754         {
1755             LPWAVEOUTCAPS16             woc16 = MapSL(*lpParam1);
1756             LPSTR                       ptr   = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1757             LPWAVEOUTCAPSA              woc32 = *(LPWAVEOUTCAPSA*)ptr;
1758
1759             woc32->wMid = woc16->wMid;
1760             woc32->wPid = woc16->wPid;
1761             woc32->vDriverVersion = woc16->vDriverVersion;
1762             strcpy(woc32->szPname, woc16->szPname);
1763             woc32->dwFormats = woc16->dwFormats;
1764             woc32->wChannels = woc16->wChannels;
1765             woc32->dwSupport = woc16->dwSupport;
1766             UnMapLS( *lpParam1 );
1767             HeapFree( GetProcessHeap(), 0, ptr );
1768             ret = MMDRV_MAP_OK;
1769         }
1770         break;
1771     case WODM_GETPITCH:
1772         FIXME("NIY: no conversion yet\n");
1773         ret = MMDRV_MAP_MSGERROR;
1774         break;
1775     case WODM_GETPLAYBACKRATE:
1776         FIXME("NIY: no conversion yet\n");
1777         ret = MMDRV_MAP_MSGERROR;
1778         break;
1779     case WODM_GETPOS:
1780         {
1781             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1782             LPSTR               ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
1783             LPMMTIME            mmt32 = *(LPMMTIME*)ptr;
1784
1785             MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1786             UnMapLS( *lpParam1 );
1787             HeapFree( GetProcessHeap(), 0, ptr );
1788             ret = MMDRV_MAP_OK;
1789         }
1790         break;
1791     case WODM_OPEN:
1792         {
1793             LPWAVEOPENDESC16            wod16 = MapSL(*lpParam1);
1794             LPSTR                       ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1795             LPWAVEOPENDESC              wod32 = *(LPWAVEOPENDESC*)ptr;
1796
1797             wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1798             **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1799             UnMapLS( *lpParam1 );
1800             HeapFree( GetProcessHeap(), 0, ptr );
1801             ret = MMDRV_MAP_OK;
1802         }
1803         break;
1804     case WODM_PREPARE:
1805     case WODM_UNPREPARE:
1806     case WODM_WRITE:
1807         {
1808             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1809             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1810             LPWAVEHDR           wh32 = *(LPWAVEHDR*)ptr;
1811
1812             assert(wh32->lpNext == wh16);
1813             wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1814             wh32->dwUser = wh16->dwUser;
1815             wh32->dwFlags = wh16->dwFlags;
1816             wh32->dwLoops = wh16->dwLoops;
1817
1818             UnMapLS( *lpParam1 );
1819             if (wMsg == WODM_UNPREPARE) {
1820                 HeapFree( GetProcessHeap(), 0, ptr );
1821                 wh32->lpNext = 0;
1822             }
1823             ret = MMDRV_MAP_OK;
1824         }
1825         break;
1826     case WODM_GETVOLUME:
1827         FIXME("NIY: no conversion yet\n");
1828         ret = MMDRV_MAP_MSGERROR;
1829         break;
1830     case DRVM_MAPPER_STATUS:
1831         {
1832             UnMapLS( *lpParam2 );
1833             ret = MMDRV_MAP_OK;
1834         }
1835         break;
1836     default:
1837         FIXME("NIY: no conversion yet\n");
1838         ret = MMDRV_MAP_MSGERROR;
1839         break;
1840     }
1841     return ret;
1842 }
1843
1844 /**************************************************************************
1845  *                              MMDRV_WaveOut_Callback          [internal]
1846  */
1847 static void     CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1848 {
1849     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
1850
1851     switch (uMsg) {
1852     case WOM_OPEN:
1853     case WOM_CLOSE:
1854         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1855         break;
1856     case WOM_DONE:
1857         if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1858             /* initial map is: 32 => 16 */
1859             LPWAVEHDR           wh16 = MapSL(dwParam1);
1860             LPWAVEHDR           wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1861             
1862             dwParam1 = (DWORD)wh32;
1863             wh32->dwFlags = wh16->dwFlags;
1864         } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1865             /* initial map is: 16 => 32 */
1866             LPWAVEHDR           wh32 = (LPWAVEHDR)(dwParam1);
1867             SEGPTR              segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1868             LPWAVEHDR           wh16 = MapSL(segwh16);
1869             
1870             dwParam1 = (DWORD)segwh16;
1871             wh16->dwFlags = wh32->dwFlags;
1872         }       
1873         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1874         break;
1875     default:
1876         ERR("Unknown msg %u\n", uMsg);
1877     }
1878
1879     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1880 }
1881
1882 #define A(_x,_y) {#_y, _x, \
1883 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1884 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1885 MMDRV_##_y##_Callback, 0, NULL, -1}
1886
1887 /* Note: the indices of this array must match the definitions
1888  *       of the MMDRV_???? manifest constants
1889  */
1890 static WINE_LLTYPE      llTypes[MMDRV_MAX] = {
1891     A(TRUE,  Aux),
1892     A(FALSE, Mixer),
1893     A(TRUE,  MidiIn),
1894     A(TRUE,  MidiOut),
1895     A(TRUE,  WaveIn),
1896     A(TRUE,  WaveOut),
1897 };
1898 #undef A
1899
1900 /**************************************************************************
1901  *                      MMDRV_GetNum                            [internal]
1902  */
1903 UINT    MMDRV_GetNum(UINT type)
1904 {
1905     assert(type < MMDRV_MAX);
1906     return llTypes[type].wMaxId;
1907 }
1908
1909 /**************************************************************************
1910  *                              WINE_Message                    [internal]
1911  */
1912 DWORD   MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1, 
1913                       DWORD dwParam2, BOOL bFrom32)
1914 {
1915     LPWINE_MM_DRIVER            lpDrv;
1916     DWORD                       ret;
1917     WINE_MM_DRIVER_PART*        part;
1918     WINE_LLTYPE*                llType = &llTypes[mld->type];
1919     MMDRV_MapType               map;
1920     int                         devID;
1921
1922     TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n", 
1923           llTypes[mld->type].typestr, mld->uDeviceID, wMsg, 
1924           mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
1925
1926     if (mld->uDeviceID == (UINT16)-1) {
1927         if (!llType->bSupportMapper) {
1928             WARN("uDev=-1 requested on non-mappable ll type %s\n", 
1929                  llTypes[mld->type].typestr);
1930             return MMSYSERR_BADDEVICEID;
1931         }
1932         devID = -1;
1933     } else {
1934         if (mld->uDeviceID >= llType->wMaxId) {
1935             WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
1936             return MMSYSERR_BADDEVICEID;
1937         }
1938         devID = mld->uDeviceID;
1939     }
1940
1941     lpDrv = &MMDrvs[mld->mmdIndex];
1942     part = &lpDrv->parts[mld->type];
1943
1944 #if 0
1945     /* some sanity checks */
1946     if (!(part->nIDMin <= devID))
1947         ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
1948     if (!(devID < part->nIDMax))
1949         ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
1950 #endif
1951
1952     if (lpDrv->bIs32) {
1953         assert(part->u.fnMessage32);
1954         
1955         if (bFrom32) {
1956             TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n", 
1957                   mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1958             ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1959             TRACE("=> %lu\n", ret);
1960         } else {
1961             map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1962             switch (map) {
1963             case MMDRV_MAP_NOMEM:
1964                 ret = MMSYSERR_NOMEM;
1965                 break;
1966             case MMDRV_MAP_MSGERROR:
1967                 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
1968                 ret = MMSYSERR_ERROR;
1969                 break;
1970             case MMDRV_MAP_OK:
1971             case MMDRV_MAP_OKMEM:
1972                 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n", 
1973                       mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1974                 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, 
1975                                           dwParam1, dwParam2);
1976                 TRACE("=> %lu\n", ret);
1977                 if (map == MMDRV_MAP_OKMEM)
1978                     llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1979                 break;
1980             default:
1981             case MMDRV_MAP_PASS:
1982                 FIXME("NIY: pass used ?\n");
1983                 ret = MMSYSERR_NOTSUPPORTED;
1984                 break;
1985             }
1986         }
1987     } else {
1988         assert(part->u.fnMessage16);
1989
1990         if (bFrom32) {
1991             map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1992             switch (map) {
1993             case MMDRV_MAP_NOMEM:
1994                 ret = MMSYSERR_NOMEM;
1995                 break;
1996             case MMDRV_MAP_MSGERROR:
1997                 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
1998                 ret = MMSYSERR_ERROR;
1999                 break;
2000             case MMDRV_MAP_OK:
2001             case MMDRV_MAP_OKMEM:
2002                 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n", 
2003                       mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2004                 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID, 
2005                                                 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2006                 TRACE("=> %lu\n", ret);
2007                 if (map == MMDRV_MAP_OKMEM)
2008                     llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
2009                 break;
2010             default:
2011             case MMDRV_MAP_PASS:
2012                 FIXME("NIY: pass used ?\n");
2013                 ret = MMSYSERR_NOTSUPPORTED;
2014                 break;
2015             }
2016         } else {
2017             TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n", 
2018                   mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2019             ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID, 
2020                                             wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2021             TRACE("=> %lu\n", ret);
2022         }
2023     }
2024     return ret;
2025 }
2026
2027 /**************************************************************************
2028  *                              MMDRV_Alloc                     [internal]
2029  */
2030 LPWINE_MLD      MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags, 
2031                             DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
2032 {
2033     LPWINE_MLD  mld;
2034
2035     mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2036     if (!mld)   return NULL;
2037
2038     /* find an empty slot in MM_MLDrvs table */
2039     for (*hndl = 0; *hndl < MAX_MM_MLDRVS; (*hndl)++) {
2040         if (!MM_MLDrvs[*hndl]) break;
2041     }
2042     if (*hndl == MAX_MM_MLDRVS) {
2043         /* the MM_MLDrvs table could be made growable in the future if needed */
2044         ERR("Too many open drivers\n");
2045         return NULL;
2046     }
2047     MM_MLDrvs[*hndl] = mld;
2048     *hndl |= 0x8000;
2049
2050     mld->type = type;
2051     if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
2052         /* FIXME: those conditions must be fulfilled so that:
2053          * - we can distinguish between device IDs and handles
2054          * - we can use handles as 16 or 32 bit entities
2055          */
2056         ERR("Shouldn't happen. Bad allocation scheme\n");
2057     }
2058
2059     mld->bFrom32 = bFrom32;
2060     mld->dwFlags = HIWORD(*dwFlags);
2061     mld->dwCallback = *dwCallback;
2062     mld->dwClientInstance = *dwInstance;
2063
2064     *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
2065     *dwCallback = (DWORD)llTypes[type].Callback;
2066     *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2067
2068     return mld;
2069 }
2070
2071 /**************************************************************************
2072  *                              MMDRV_Free                      [internal]
2073  */
2074 void    MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
2075 {
2076     if (hndl & 0x8000) {
2077         unsigned idx = hndl & ~0x8000;
2078         if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2079             MM_MLDrvs[idx] = NULL;
2080             HeapFree(GetProcessHeap(), 0, mld);
2081             return;
2082         }
2083     }
2084     ERR("Bad Handle %08x at %p (not freed)\n", hndl, mld);
2085 }
2086
2087 /**************************************************************************
2088  *                              MMDRV_Open                      [internal]
2089  */
2090 DWORD   MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
2091 {
2092     DWORD               dwRet = MMSYSERR_BADDEVICEID;
2093     DWORD               dwInstance;
2094     WINE_LLTYPE*        llType = &llTypes[mld->type];
2095
2096     mld->dwDriverInstance = (DWORD)&dwInstance;
2097
2098     if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
2099         TRACE("MAPPER mode requested !\n");
2100         /* check if mapper is supported by type */
2101         if (llType->bSupportMapper) {
2102             if (llType->nMapper == -1) {
2103                 /* no driver for mapper has been loaded, try a dumb implementation */
2104                 TRACE("No mapper loaded, doing it by hand\n");
2105                 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
2106                     if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
2107                         /* to share this function epilog */
2108                         dwInstance = mld->dwDriverInstance;
2109                         break;
2110                     }
2111                 }
2112             } else {
2113                 mld->uDeviceID = (UINT16)-1;
2114                 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
2115                 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2116                 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2117             }
2118         }
2119     } else {
2120         if (mld->uDeviceID < llType->wMaxId) {
2121             mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
2122             TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2123             dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2124         }
2125     }
2126     if (dwRet == MMSYSERR_NOERROR)
2127         mld->dwDriverInstance = dwInstance;
2128     return dwRet;
2129 }
2130
2131 /**************************************************************************
2132  *                              MMDRV_Close                     [internal]
2133  */
2134 DWORD   MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
2135 {
2136     return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
2137 }
2138
2139 /**************************************************************************
2140  *                              MMDRV_GetByID                   [internal]
2141  */
2142 LPWINE_MLD      MMDRV_GetByID(UINT uDevID, UINT type)
2143 {
2144     if (uDevID < llTypes[type].wMaxId)
2145         return &llTypes[type].lpMlds[uDevID];
2146     if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
2147         return &llTypes[type].lpMlds[-1];
2148     return NULL;
2149 }
2150
2151 /**************************************************************************
2152  *                              MMDRV_Get                       [internal]
2153  */
2154 LPWINE_MLD      MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
2155 {
2156     LPWINE_MLD  mld = NULL;
2157
2158     assert(type < MMDRV_MAX);
2159
2160     if ((UINT)hndl >= llTypes[type].wMaxId && 
2161         hndl != (UINT16)-1 && hndl != (UINT)-1) {
2162         if (hndl & 0x8000) {
2163             hndl &= ~0x8000;
2164             if (hndl < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2165                 mld = MM_MLDrvs[hndl];
2166                 if (!mld || !HeapValidate(GetProcessHeap(), 0, mld) || mld->type != type)
2167                     mld = NULL;
2168             }
2169             hndl |= 0x8000;
2170         }
2171     }
2172     if (mld == NULL && bCanBeID) {
2173         mld = MMDRV_GetByID((UINT)hndl, type);
2174     }
2175     return mld;
2176 }
2177
2178 /**************************************************************************
2179  *                              MMDRV_GetRelated                [internal]
2180  */
2181 LPWINE_MLD      MMDRV_GetRelated(HANDLE hndl, UINT srcType,
2182                                  BOOL bSrcCanBeID, UINT dstType)
2183 {
2184     LPWINE_MLD          mld;
2185
2186     if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
2187         WINE_MM_DRIVER_PART*    part = &MMDrvs[mld->mmdIndex].parts[dstType];
2188         if (part->nIDMin < part->nIDMax)
2189             return MMDRV_GetByID(part->nIDMin, dstType);
2190     } 
2191     return NULL;
2192 }
2193
2194 /**************************************************************************
2195  *                              MMDRV_PhysicalFeatures          [internal]
2196  */
2197 UINT    MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1, 
2198                                DWORD dwParam2)
2199 {
2200     WINE_MM_DRIVER*     lpDrv = &MMDrvs[mld->mmdIndex];
2201
2202     TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
2203
2204     /* all those function calls are undocumented */
2205     switch (uMsg) {
2206     case DRV_QUERYDRVENTRY:
2207         lstrcpynA((LPSTR)dwParam1, lpDrv->drvname, LOWORD(dwParam2));
2208         break;
2209     case DRV_QUERYDEVNODE:
2210         *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
2211         break;
2212     case DRV_QUERYNAME:
2213         WARN("NIY QueryName\n");
2214         break;
2215     case DRV_QUERYDRIVERIDS:
2216         WARN("NIY call VxD\n");
2217         /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2218          * dwParam1 is buffer and dwParam2 is sizeof buffer
2219          * I don't know where the result is stored though
2220          */
2221         break;
2222     case DRV_QUERYMAPPABLE:
2223         return (lpDrv->bIsMapper) ? 2 : 0;
2224
2225     case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
2226         return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
2227
2228     default:
2229         WARN("Unknown call %04x\n", uMsg);
2230         return MMSYSERR_INVALPARAM;
2231     }
2232     return 0L;
2233 }
2234
2235 /**************************************************************************
2236  *                              MMDRV_InitPerType               [internal]
2237  */
2238 static  BOOL    MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT type, UINT wMsg)
2239 {
2240     WINE_MM_DRIVER_PART*        part = &lpDrv->parts[type];
2241     DWORD                       ret;
2242     UINT                        count = 0;
2243     int                         i, k;
2244
2245     part->nIDMin = part->nIDMax = 0;
2246
2247     /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2248     /* the DRVM_ENABLE is only required when the PnP node is non zero */
2249
2250     if (lpDrv->bIs32 && part->u.fnMessage32) {
2251         ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
2252         TRACE("DRVM_INIT => %08lx\n", ret);
2253 #if 0
2254         ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
2255         TRACE("DRVM_ENABLE => %08lx\n", ret);
2256 #endif
2257         count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
2258     } else if (!lpDrv->bIs32 && part->u.fnMessage16) {
2259         ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, 
2260                                         0, DRVM_INIT, 0L, 0L, 0L);
2261         TRACE("DRVM_INIT => %08lx\n", ret);
2262 #if 0
2263         ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2264                                         0, DRVM_ENABLE, 0L, 0L, 0L);
2265         TRACE("DRVM_ENABLE => %08lx\n", ret);
2266 #endif
2267         count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, 
2268                                           0, wMsg, 0L, 0L, 0L);
2269     } else {
2270         return FALSE;
2271     }
2272
2273     TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->drvname, llTypes[type].typestr);
2274
2275     /* got some drivers */
2276     if (lpDrv->bIsMapper) {
2277         /* it seems native mappers return 0 devices :-( */
2278         if (llTypes[type].nMapper != -1)
2279             ERR("Two mappers for type %s (%d, %s)\n", 
2280                 llTypes[type].typestr, llTypes[type].nMapper, lpDrv->drvname);
2281         if (count > 1)
2282             ERR("Strange: mapper with %d > 1 devices\n", count);
2283         llTypes[type].nMapper = MMDrvsHi;
2284     } else {
2285         if (count == 0)
2286             return FALSE;
2287         part->nIDMin = llTypes[type].wMaxId;
2288         llTypes[type].wMaxId += count;
2289         part->nIDMax = llTypes[type].wMaxId;
2290     }
2291     TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2292           part->nIDMin, part->nIDMax, llTypes[type].wMaxId, 
2293           lpDrv->drvname, llTypes[type].typestr);
2294     /* realloc translation table */
2295     llTypes[type].lpMlds = (LPWINE_MLD)
2296         HeapReAlloc(GetProcessHeap(), 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
2297                     sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
2298     /* re-build the translation table */
2299     if (llTypes[type].nMapper != -1) {
2300         TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, -1, MMDrvs[llTypes[type].nMapper].drvname);
2301         llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
2302         llTypes[type].lpMlds[-1].type = type;
2303         llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
2304         llTypes[type].lpMlds[-1].dwDriverInstance = 0;
2305     }
2306     for (i = k = 0; i <= MMDrvsHi; i++) {
2307         while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
2308             TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, k, MMDrvs[i].drvname);
2309             llTypes[type].lpMlds[k].uDeviceID = k;
2310             llTypes[type].lpMlds[k].type = type;
2311             llTypes[type].lpMlds[k].mmdIndex = i;
2312             llTypes[type].lpMlds[k].dwDriverInstance = 0;
2313             k++;
2314         }
2315     }
2316     return TRUE;
2317 }
2318
2319 /**************************************************************************
2320  *                              MMDRV_Install                   [internal]
2321  */
2322 static  BOOL    MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
2323 {
2324     int                 i, count = 0;
2325     char                buffer[128];
2326     LPWINE_MM_DRIVER    lpDrv = &MMDrvs[MMDrvsHi];
2327     LPWINE_DRIVER       d;
2328
2329     TRACE("('%s', '%s', mapper=%c);\n", drvRegName, drvFileName, bIsMapper ? 'Y' : 'N');
2330
2331     /* be sure that size of MMDrvs matches the max number of loadable drivers !! 
2332      * if not just increase size of MMDrvs */
2333     assert(MMDrvsHi <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
2334     
2335     for (i = 0; i < MMDrvsHi; i++) {
2336         if (!strcmp(drvRegName, MMDrvs[i].drvname)) return FALSE;
2337     }
2338
2339     memset(lpDrv, 0, sizeof(*lpDrv));
2340
2341     if (!(lpDrv->hDriver = OpenDriverA(drvFileName, 0, 0))) {
2342         WARN("Couldn't open driver '%s'\n", drvFileName);
2343         return FALSE;
2344     }
2345     
2346     d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
2347     lpDrv->bIs32 = (d->dwFlags & WINE_GDF_16BIT) ? FALSE : TRUE;
2348
2349     /* Then look for xxxMessage functions */
2350 #define AA(_h,_w,_x,_y,_z)                                      \
2351     func = (WINEMM_msgFunc##_y) _z ((_h), #_x);                 \
2352     if (func != NULL)                                           \
2353         { lpDrv->parts[_w].u.fnMessage##_y = func; count++;     \
2354           TRACE("Got %d bit func '%s'\n", _y, #_x);         }
2355
2356     if (lpDrv->bIs32) {
2357         WINEMM_msgFunc32        func;
2358
2359         if (d->d.d32.hModule) {
2360 #define A(_x,_y)        AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
2361             A(MMDRV_AUX,        auxMessage);
2362             A(MMDRV_MIXER,      mixMessage);
2363             A(MMDRV_MIDIIN,     midMessage);
2364             A(MMDRV_MIDIOUT,    modMessage);
2365             A(MMDRV_WAVEIN,     widMessage);
2366             A(MMDRV_WAVEOUT,    wodMessage);
2367 #undef A
2368         }
2369     } else {
2370         WINEMM_msgFunc16        func;
2371
2372         /*
2373          * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2374          * The beginning of the module description indicates the driver supports 
2375          * waveform, auxiliary, and mixer devices. Use one of the following 
2376          * device-type names, followed by a colon (:) to indicate the type of
2377          * device your driver supports. If the driver supports more than one
2378          * type of device, separate each device-type name with a comma (,). 
2379          *      
2380          * wave for waveform audio devices 
2381          * wavemapper for wave mappers
2382          * midi for MIDI audio devices 
2383          * midimapper for midi mappers
2384          * aux for auxiliary audio devices 
2385          * mixer for mixer devices 
2386          */
2387         
2388         if (d->d.d16.hDriver16) {
2389             HMODULE16   hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
2390
2391 #define A(_x,_y)        AA(hMod16,_x,_y,16,GetProcAddress16)
2392             A(MMDRV_AUX,        auxMessage);
2393             A(MMDRV_MIXER,      mixMessage);
2394             A(MMDRV_MIDIIN,     midMessage);
2395             A(MMDRV_MIDIOUT,    modMessage);
2396             A(MMDRV_WAVEIN,     widMessage);
2397             A(MMDRV_WAVEOUT,    wodMessage);
2398 #undef A
2399         }
2400     }
2401 #undef AA
2402
2403     if (TRACE_ON(mmsys)) {
2404         if ((lpDrv->bIs32) ? MMDRV_GetDescription32(drvFileName, buffer, sizeof(buffer)) :
2405                              MMDRV_GetDescription16(drvFileName, buffer, sizeof(buffer)))
2406             TRACE("%s => %s\n", drvFileName, buffer);
2407         else
2408             TRACE("%s => No description\n", drvFileName);
2409     }
2410
2411     if (!count) {
2412         CloseDriver(lpDrv->hDriver, 0, 0);
2413         WARN("No message functions found\n");
2414         return FALSE;
2415     }
2416
2417     /* FIXME: being a mapper or not should be known by another way */
2418     /* it's known for NE drvs (the description is of the form '*mapper: *'
2419      * I don't have any clue for PE drvs
2420      */
2421     lpDrv->bIsMapper = bIsMapper;
2422     lpDrv->drvname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(drvRegName) + 1), drvRegName);
2423
2424     /* Finish init and get the count of the devices */
2425     MMDRV_InitPerType(lpDrv, MMDRV_AUX,         AUXDM_GETNUMDEVS);
2426     MMDRV_InitPerType(lpDrv, MMDRV_MIXER,       MXDM_GETNUMDEVS);
2427     MMDRV_InitPerType(lpDrv, MMDRV_MIDIIN,      MIDM_GETNUMDEVS);
2428     MMDRV_InitPerType(lpDrv, MMDRV_MIDIOUT,     MODM_GETNUMDEVS);
2429     MMDRV_InitPerType(lpDrv, MMDRV_WAVEIN,      WIDM_GETNUMDEVS);
2430     MMDRV_InitPerType(lpDrv, MMDRV_WAVEOUT,     WODM_GETNUMDEVS);
2431     /* FIXME: if all those func calls return FALSE, 
2432      * then the driver must be unloaded
2433      */
2434
2435     MMDrvsHi++;
2436
2437     return TRUE;
2438 }
2439
2440 /**************************************************************************
2441  *                              MMDRV_InitFromRegistry          [internal]
2442  */
2443 static BOOL     MMDRV_InitFromRegistry(void)
2444 {
2445     HKEY        hKey;
2446     char        buffer[256];
2447     char*       p1;
2448     char*       p2;
2449     DWORD       type, size;
2450     BOOL        ret = FALSE;
2451
2452     if (RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\WinMM", &hKey)) {
2453         TRACE("Cannot open WinMM config key\n");
2454         return FALSE;
2455     }
2456
2457     size = sizeof(buffer);
2458     if (!RegQueryValueExA(hKey, "Drivers", 0, &type, (LPVOID)buffer, &size)) {
2459         p1 = buffer;
2460         while (p1) {
2461             p2 = strchr(p1, ';');
2462             if (p2) *p2++ = '\0';
2463             ret |= MMDRV_Install(p1, p1, FALSE);
2464             p1 = p2;
2465         }
2466     }
2467
2468     /* finish with mappers */
2469     size = sizeof(buffer);
2470     if (!RegQueryValueExA(hKey, "WaveMapper", 0, &type, (LPVOID)buffer, &size))
2471         ret |= MMDRV_Install("wavemapper", buffer, TRUE);
2472     size = sizeof(buffer);
2473     if (!RegQueryValueExA(hKey, "MidiMapper", 0, &type, (LPVOID)buffer, &size))
2474         ret |= MMDRV_Install("midimapper", buffer, TRUE);
2475
2476     RegCloseKey(hKey);
2477
2478     return ret;
2479 }
2480
2481 /**************************************************************************
2482  *                              MMDRV_InitHardcoded             [internal]
2483  */
2484 static BOOL     MMDRV_InitHardcoded(void)
2485 {
2486     ERR("You didn't setup properly the config file for the Wine multimedia modules.\n"
2487         "Will use the hard-coded setup, but this will disappear soon.\n"
2488         "Please add a WinMM section to your Wine config file.\n");
2489
2490     /* first load hardware drivers */
2491     MMDRV_Install("wineoss.drv",        "wineoss.drv",  FALSE);
2492
2493     /* finish with mappers */
2494     MMDRV_Install("wavemapper",         "msacm.drv",    TRUE);
2495     MMDRV_Install("midimapper",         "midimap.drv",  TRUE);
2496
2497     return TRUE;
2498 }
2499
2500 /**************************************************************************
2501  *                              MMDRV_Init                      [internal]
2502  */
2503 BOOL    MMDRV_Init(void)
2504 {
2505     /* FIXME: MMDRV_InitFromRegistry shall be MMDRV_Init in a near future */
2506     return MMDRV_InitFromRegistry() || MMDRV_InitHardcoded();
2507 }