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