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