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