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