comctl32/listview: Free ID array when removing all items.
[wine] / dlls / winmm / message16.c
1 /*
2  * MMSYSTEM MCI and low level mapping functions
3  *
4  * Copyright 1999 Eric Pouech
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <string.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #include "wine/winbase16.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wownt32.h"
29 #include "winemm.h"
30 #include "winemm16.h"
31 #include "digitalv.h"
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(winmm);
35
36 /**************************************************************************
37  *                              MMDRV_Callback                  [internal]
38  */
39 static  void    MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
40 {
41     TRACE("CB (*%08lx)(%p %08x %08lx %08lx %08lx\n",
42           mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
43
44     if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION)
45     {
46         WORD args[8];
47         /* 16 bit func, call it */
48         TRACE("Function (16 bit) !\n");
49
50         args[7] = HDRVR_16(hDev);
51         args[6] = uMsg;
52         args[5] = HIWORD(mld->dwClientInstance);
53         args[4] = LOWORD(mld->dwClientInstance);
54         args[3] = HIWORD(dwParam1);
55         args[2] = LOWORD(dwParam1);
56         args[1] = HIWORD(dwParam2);
57         args[0] = LOWORD(dwParam2);
58         WOWCallback16Ex( mld->dwCallback, WCB16_PASCAL, sizeof(args), args, NULL );
59     } else {
60         DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
61                        mld->dwClientInstance, dwParam1, dwParam2);
62     }
63 }
64
65 /* =================================
66  *       A U X    M A P P E R S
67  * ================================= */
68
69 /**************************************************************************
70  *                              MMDRV_Aux_Map16To32W            [internal]
71  */
72 static  WINMM_MapType   MMDRV_Aux_Map16To32W  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
73 {
74     return WINMM_MAP_MSGERROR;
75 }
76
77 /**************************************************************************
78  *                              MMDRV_Aux_UnMap16To32W          [internal]
79  */
80 static  WINMM_MapType   MMDRV_Aux_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
81 {
82     return WINMM_MAP_MSGERROR;
83 }
84
85 /**************************************************************************
86  *                              MMDRV_Aux_Map32WTo16            [internal]
87  */
88 static  WINMM_MapType   MMDRV_Aux_Map32WTo16  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
89 {
90     return WINMM_MAP_MSGERROR;
91 }
92
93 /**************************************************************************
94  *                              MMDRV_Aux_UnMap32WTo16          [internal]
95  */
96 static  WINMM_MapType   MMDRV_Aux_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
97 {
98 #if 0
99  case AUXDM_GETDEVCAPS:
100     lpCaps->wMid = ac16.wMid;
101     lpCaps->wPid = ac16.wPid;
102     lpCaps->vDriverVersion = ac16.vDriverVersion;
103     strcpy(lpCaps->szPname, ac16.szPname);
104     lpCaps->wTechnology = ac16.wTechnology;
105     lpCaps->dwSupport = ac16.dwSupport;
106 #endif
107     return WINMM_MAP_MSGERROR;
108 }
109
110 /**************************************************************************
111  *                              MMDRV_Aux_Callback              [internal]
112  */
113 static  void    CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
114 {
115     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
116
117     FIXME("NIY\n");
118     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
119 }
120
121 /* =================================
122  *     M I X E R  M A P P E R S
123  * ================================= */
124
125 /**************************************************************************
126  *                              xMMDRV_Mixer_Map16To32W         [internal]
127  */
128 static  WINMM_MapType   MMDRV_Mixer_Map16To32W  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
129 {
130     return WINMM_MAP_MSGERROR;
131 }
132
133 /**************************************************************************
134  *                              MMDRV_Mixer_UnMap16To32W        [internal]
135  */
136 static  WINMM_MapType   MMDRV_Mixer_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
137 {
138 #if 0
139     MIXERCAPSA  micA;
140     UINT        ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
141
142     if (ret == MMSYSERR_NOERROR) {
143         mixcaps->wMid           = micA.wMid;
144         mixcaps->wPid           = micA.wPid;
145         mixcaps->vDriverVersion = micA.vDriverVersion;
146         strcpy(mixcaps->szPname, micA.szPname);
147         mixcaps->fdwSupport     = micA.fdwSupport;
148         mixcaps->cDestinations  = micA.cDestinations;
149     }
150     return ret;
151 #endif
152     return WINMM_MAP_MSGERROR;
153 }
154
155 /**************************************************************************
156  *                              MMDRV_Mixer_Map32WTo16          [internal]
157  */
158 static  WINMM_MapType   MMDRV_Mixer_Map32WTo16  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
159 {
160     return WINMM_MAP_MSGERROR;
161 }
162
163 /**************************************************************************
164  *                              MMDRV_Mixer_UnMap32WTo16        [internal]
165  */
166 static  WINMM_MapType   MMDRV_Mixer_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
167 {
168     return WINMM_MAP_MSGERROR;
169 }
170
171 /**************************************************************************
172  *                              MMDRV_Mixer_Callback            [internal]
173  */
174 static  void    CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
175 {
176     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
177
178     FIXME("NIY\n");
179     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
180 }
181
182 /* =================================
183  *   M I D I  I N    M A P P E R S
184  * ================================= */
185
186 /**************************************************************************
187  *                              MMDRV_MidiIn_Map16To32W         [internal]
188  */
189 static  WINMM_MapType   MMDRV_MidiIn_Map16To32W  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
190 {
191     return WINMM_MAP_MSGERROR;
192 }
193
194 /**************************************************************************
195  *                              MMDRV_MidiIn_UnMap16To32W       [internal]
196  */
197 static  WINMM_MapType   MMDRV_MidiIn_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
198 {
199     return WINMM_MAP_MSGERROR;
200 }
201
202 /**************************************************************************
203  *                              MMDRV_MidiIn_Map32WTo16         [internal]
204  */
205 static  WINMM_MapType   MMDRV_MidiIn_Map32WTo16  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
206 {
207     return WINMM_MAP_MSGERROR;
208 }
209
210 /**************************************************************************
211  *                              MMDRV_MidiIn_UnMap32WTo16       [internal]
212  */
213 static  WINMM_MapType   MMDRV_MidiIn_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
214 {
215     return WINMM_MAP_MSGERROR;
216 }
217
218 /**************************************************************************
219  *                              MMDRV_MidiIn_Callback           [internal]
220  */
221 static  void    CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
222 {
223     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
224
225     switch (uMsg) {
226     case MIM_OPEN:
227     case MIM_CLOSE:
228         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
229
230     case MIM_DATA:
231     case MIM_MOREDATA:
232     case MIM_ERROR:
233         /* dwParam1 & dwParam2 are data, nothing to do */
234         break;
235     case MIM_LONGDATA:
236     case MIM_LONGERROR:
237         /* dwParam1 points to a MidiHdr, work to be done !!! */
238         if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
239             /* initial map is: 32 => 16 */
240             LPMIDIHDR           mh16 = MapSL(dwParam1);
241             LPMIDIHDR           mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
242
243             dwParam1 = (DWORD)mh32;
244             mh32->dwFlags = mh16->dwFlags;
245             mh32->dwBytesRecorded = mh16->dwBytesRecorded;
246             if (mh32->reserved >= sizeof(MIDIHDR))
247                 mh32->dwOffset = mh16->dwOffset;
248         } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
249             /* initial map is: 16 => 32 */
250             LPMIDIHDR           mh32 = (LPMIDIHDR)(dwParam1);
251             SEGPTR              segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
252             LPMIDIHDR           mh16 = MapSL(segmh16);
253
254             dwParam1 = (DWORD)segmh16;
255             mh16->dwFlags = mh32->dwFlags;
256             mh16->dwBytesRecorded = mh32->dwBytesRecorded;
257             if (mh16->reserved >= sizeof(MIDIHDR))
258                 mh16->dwOffset = mh32->dwOffset;
259         }
260         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
261         break;
262     /* case MOM_POSITIONCB: */
263     default:
264         ERR("Unknown msg %u\n", uMsg);
265     }
266
267     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
268 }
269
270 /* =================================
271  *   M I D I  O U T  M A P P E R S
272  * ================================= */
273
274 /**************************************************************************
275  *                              MMDRV_MidiOut_Map16To32W        [internal]
276  */
277 static  WINMM_MapType   MMDRV_MidiOut_Map16To32W  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
278 {
279     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
280
281     switch (wMsg) {
282     case MODM_GETNUMDEVS:
283     case MODM_DATA:
284     case MODM_RESET:
285     case MODM_SETVOLUME:
286         ret = WINMM_MAP_OK;
287         break;
288
289     case MODM_OPEN:
290     case MODM_CLOSE:
291     case MODM_GETVOLUME:
292         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
293         break;
294
295     case MODM_GETDEVCAPS:
296         {
297             LPMIDIOUTCAPSW      moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSW));
298             LPMIDIOUTCAPS16     moc16 = MapSL(*lpParam1);
299
300             if (moc32) {
301                 *(LPMIDIOUTCAPS16*)moc32 = moc16;
302                 moc32 = (LPMIDIOUTCAPSW)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
303                 *lpParam1 = (DWORD)moc32;
304                 *lpParam2 = sizeof(MIDIOUTCAPSW);
305
306                 ret = WINMM_MAP_OKMEM;
307             } else {
308                 ret = WINMM_MAP_NOMEM;
309             }
310         }
311         break;
312     case MODM_PREPARE:
313         {
314             LPMIDIHDR           mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
315             LPMIDIHDR           mh16 = MapSL(*lpParam1);
316
317             if (mh32) {
318                 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
319                 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
320                 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
321                 mh32->dwBufferLength = mh16->dwBufferLength;
322                 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
323                 mh32->dwUser = mh16->dwUser;
324                 mh32->dwFlags = mh16->dwFlags;
325                 /* FIXME: nothing on mh32->lpNext */
326                 /* could link the mh32->lpNext at this level for memory house keeping */
327                 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh16->dwOffset : 0;
328                 mh16->lpNext = mh32; /* for reuse in unprepare and write */
329                 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
330                 mh16->reserved = *lpParam2;
331                 *lpParam1 = (DWORD)mh32;
332                 *lpParam2 = sizeof(MIDIHDR);
333
334                 ret = WINMM_MAP_OKMEM;
335             } else {
336                 ret = WINMM_MAP_NOMEM;
337             }
338         }
339         break;
340     case MODM_UNPREPARE:
341     case MODM_LONGDATA:
342         {
343             LPMIDIHDR           mh16 = MapSL(*lpParam1);
344             LPMIDIHDR           mh32 = mh16->lpNext;
345
346             *lpParam1 = (DWORD)mh32;
347             *lpParam2 = sizeof(MIDIHDR);
348             /* dwBufferLength can be reduced between prepare & write */
349             if (wMsg == MODM_LONGDATA && mh32->dwBufferLength < mh16->dwBufferLength) {
350                 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
351                     mh32->dwBufferLength, mh16->dwBufferLength);
352             } else
353                 mh32->dwBufferLength = mh16->dwBufferLength;
354             ret = WINMM_MAP_OKMEM;
355         }
356         break;
357
358     case MODM_CACHEPATCHES:
359     case MODM_CACHEDRUMPATCHES:
360     default:
361         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
362         break;
363     }
364     return ret;
365 }
366
367 /**************************************************************************
368  *                              MMDRV_MidiOut_UnMap16To32W      [internal]
369  */
370 static  WINMM_MapType   MMDRV_MidiOut_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
371 {
372     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
373
374     switch (wMsg) {
375     case MODM_GETNUMDEVS:
376     case MODM_DATA:
377     case MODM_RESET:
378     case MODM_SETVOLUME:
379         ret = WINMM_MAP_OK;
380         break;
381
382     case MODM_OPEN:
383     case MODM_CLOSE:
384     case MODM_GETVOLUME:
385         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
386         break;
387
388     case MODM_GETDEVCAPS:
389         {
390             LPMIDIOUTCAPSW              moc32 = (LPMIDIOUTCAPSW)(*lpParam1);
391             LPMIDIOUTCAPS16             moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
392
393             moc16->wMid                 = moc32->wMid;
394             moc16->wPid                 = moc32->wPid;
395             moc16->vDriverVersion       = moc32->vDriverVersion;
396             WideCharToMultiByte( CP_ACP, 0, moc32->szPname, -1, moc16->szPname,
397                                  sizeof(moc16->szPname), NULL, NULL );
398             moc16->wTechnology          = moc32->wTechnology;
399             moc16->wVoices              = moc32->wVoices;
400             moc16->wNotes               = moc32->wNotes;
401             moc16->wChannelMask         = moc32->wChannelMask;
402             moc16->dwSupport            = moc32->dwSupport;
403             HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
404             ret = WINMM_MAP_OK;
405         }
406         break;
407     case MODM_PREPARE:
408     case MODM_UNPREPARE:
409     case MODM_LONGDATA:
410         {
411             LPMIDIHDR           mh32 = (LPMIDIHDR)(*lpParam1);
412             LPMIDIHDR           mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
413
414             assert(mh16->lpNext == mh32);
415             mh16->dwBufferLength = mh32->dwBufferLength;
416             mh16->dwBytesRecorded = mh32->dwBytesRecorded;
417             mh16->dwUser = mh32->dwUser;
418             mh16->dwFlags = mh32->dwFlags;
419             if (mh16->reserved >= sizeof(MIDIHDR))
420                 mh16->dwOffset = mh32->dwOffset;
421
422             if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
423                 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
424                 mh16->lpNext = 0;
425             }
426             ret = WINMM_MAP_OK;
427         }
428         break;
429
430     case MODM_CACHEPATCHES:
431     case MODM_CACHEDRUMPATCHES:
432     default:
433         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
434         break;
435     }
436     return ret;
437 }
438
439 /**************************************************************************
440  *                              MMDRV_MidiOut_Map32WTo16        [internal]
441  */
442 static  WINMM_MapType   MMDRV_MidiOut_Map32WTo16  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
443 {
444     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
445
446     switch (wMsg) {
447     case MODM_CLOSE:
448     case MODM_GETNUMDEVS:
449     case MODM_DATA:
450     case MODM_RESET:
451     case MODM_SETVOLUME:
452         ret = WINMM_MAP_OK;
453         break;
454     case MODM_GETDEVCAPS:
455         {
456             LPMIDIOUTCAPSW moc32 = (LPMIDIOUTCAPSW)*lpParam1;
457             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSW)+sizeof(MIDIOUTCAPS16));
458
459             if (ptr) {
460                 *(LPMIDIOUTCAPSW*)ptr = moc32;
461                 ret = WINMM_MAP_OKMEM;
462             } else {
463                 ret = WINMM_MAP_NOMEM;
464             }
465             *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSW);
466             *lpParam2 = sizeof(MIDIOUTCAPS16);
467         }
468         break;
469     case MODM_PREPARE:
470         {
471             LPMIDIHDR           mh32 = (LPMIDIHDR)*lpParam1;
472             LPMIDIHDR           mh16;
473             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
474                                     sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
475
476             if (ptr) {
477                 *(LPMIDIHDR*)ptr = mh32;
478                 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
479                 *lpParam1 = MapLS(mh16);
480                 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
481                 /* data will be copied on WODM_WRITE */
482                 mh16->dwBufferLength = mh32->dwBufferLength;
483                 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
484                 mh16->dwUser = mh32->dwUser;
485                 mh16->dwFlags = mh32->dwFlags;
486                 /* FIXME: nothing on mh32->lpNext */
487                 /* could link the mh32->lpNext at this level for memory house keeping */
488                 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
489
490                 mh32->lpNext = mh16; /* for reuse in unprepare and write */
491                 mh32->reserved = *lpParam2;
492
493                 TRACE("mh16=%08lx mh16->lpData=%p mh32->buflen=%u mh32->lpData=%p\n",
494                       *lpParam1, mh16->lpData, mh32->dwBufferLength, mh32->lpData);
495                 *lpParam2 = sizeof(MIDIHDR);
496
497                 ret = WINMM_MAP_OKMEM;
498             } else {
499                 ret = WINMM_MAP_NOMEM;
500             }
501         }
502         break;
503     case MODM_UNPREPARE:
504     case MODM_LONGDATA:
505         {
506             LPMIDIHDR           mh32 = (LPMIDIHDR)(*lpParam1);
507             LPMIDIHDR           mh16 = mh32->lpNext;
508             LPSTR               ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
509
510             assert(*(LPMIDIHDR*)ptr == mh32);
511
512             if (wMsg == MODM_LONGDATA)
513                 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
514
515             *lpParam1 = MapLS(mh16);
516             *lpParam2 = sizeof(MIDIHDR);
517             TRACE("mh16=%08lx mh16->lpData=%p mh32->buflen=%u mh32->lpData=%p\n",
518                   *lpParam1, mh16->lpData, mh32->dwBufferLength, mh32->lpData);
519
520             /* dwBufferLength can be reduced between prepare & write */
521             if (wMsg == MODM_LONGDATA && mh16->dwBufferLength < mh32->dwBufferLength) {
522                 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
523                     mh16->dwBufferLength, mh32->dwBufferLength);
524             } else
525                 mh16->dwBufferLength = mh32->dwBufferLength;
526             ret = WINMM_MAP_OKMEM;
527         }
528         break;
529     case MODM_OPEN:
530         {
531             LPMIDIOPENDESC              mod32 = (LPMIDIOPENDESC)*lpParam1;
532             LPVOID                      ptr;
533             LPMIDIOPENDESC16            mod16;
534
535             /* allocated data are mapped as follows:
536                LPMIDIOPENDESC   ptr to orig lParam1
537                DWORD            orig dwUser, which is a pointer to DWORD:driver dwInstance
538                DWORD            dwUser passed to driver
539                MIDIOPENDESC16   mod16: openDesc passed to driver
540                MIDIOPENSTRMID   cIds
541             */
542             ptr = HeapAlloc( GetProcessHeap(), 0,
543                              sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
544                              mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
545
546             if (ptr) {
547                 SEGPTR segptr = MapLS(ptr);
548                 *(LPMIDIOPENDESC*)ptr = mod32;
549                 *(LPDWORD)((char*)ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
550                 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
551
552                 mod16->hMidi = HMIDI_16(mod32->hMidi);
553                 mod16->dwCallback = mod32->dwCallback;
554                 mod16->dwInstance = mod32->dwInstance;
555                 mod16->dnDevNode = mod32->dnDevNode;
556                 mod16->cIds = mod32->cIds;
557                 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
558
559                 *lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
560                 *lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
561
562                 ret = WINMM_MAP_OKMEM;
563             } else {
564                 ret = WINMM_MAP_NOMEM;
565             }
566         }
567         break;
568     case MODM_GETVOLUME:
569     case MODM_CACHEPATCHES:
570     case MODM_CACHEDRUMPATCHES:
571     default:
572         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
573         break;
574     }
575     return ret;
576 }
577
578 /**************************************************************************
579  *                              MMDRV_MidiOut_UnMap32WTo16      [internal]
580  */
581 static  WINMM_MapType   MMDRV_MidiOut_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
582 {
583     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
584
585     switch (wMsg) {
586     case MODM_CLOSE:
587     case MODM_GETNUMDEVS:
588     case MODM_DATA:
589     case MODM_RESET:
590     case MODM_SETVOLUME:
591         ret = WINMM_MAP_OK;
592         break;
593     case MODM_GETDEVCAPS:
594         {
595             LPMIDIOUTCAPS16             moc16 = MapSL(*lpParam1);
596             LPSTR                       ptr   = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSW);
597             LPMIDIOUTCAPSW              moc32 = *(LPMIDIOUTCAPSW*)ptr;
598
599             moc32->wMid                 = moc16->wMid;
600             moc32->wPid                 = moc16->wPid;
601             moc32->vDriverVersion       = moc16->vDriverVersion;
602             WideCharToMultiByte( CP_ACP, 0, moc32->szPname, -1, moc16->szPname,
603                                  sizeof(moc16->szPname), NULL, NULL );
604             moc32->wTechnology          = moc16->wTechnology;
605             moc32->wVoices              = moc16->wVoices;
606             moc32->wNotes               = moc16->wNotes;
607             moc32->wChannelMask         = moc16->wChannelMask;
608             moc32->dwSupport            = moc16->dwSupport;
609             UnMapLS( *lpParam1 );
610             HeapFree( GetProcessHeap(), 0, ptr );
611             ret = WINMM_MAP_OK;
612         }
613         break;
614     case MODM_PREPARE:
615     case MODM_UNPREPARE:
616     case MODM_LONGDATA:
617         {
618             LPMIDIHDR           mh16 = MapSL(*lpParam1);
619             LPSTR               ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
620             LPMIDIHDR           mh32 = *(LPMIDIHDR*)ptr;
621
622             assert(mh32->lpNext == mh16);
623             UnMapLS( *lpParam1 );
624             mh32->dwBytesRecorded = mh16->dwBytesRecorded;
625             mh32->dwUser = mh16->dwUser;
626             mh32->dwFlags = mh16->dwFlags;
627
628             if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
629                 HeapFree( GetProcessHeap(), 0, ptr );
630                 mh32->lpNext = 0;
631             }
632             ret = WINMM_MAP_OK;
633         }
634         break;
635     case MODM_OPEN:
636         {
637             LPMIDIOPENDESC16            mod16 = MapSL(*lpParam1);
638             LPSTR                       ptr   = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
639             UnMapLS( *lpParam1 );
640             **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
641
642             HeapFree( GetProcessHeap(), 0, ptr );
643             ret = WINMM_MAP_OK;
644         }
645         break;
646     case MODM_GETVOLUME:
647     case MODM_CACHEPATCHES:
648     case MODM_CACHEDRUMPATCHES:
649     default:
650         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
651         break;
652     }
653     return ret;
654 }
655
656 /**************************************************************************
657  *                              MMDRV_MidiOut_Callback          [internal]
658  */
659 static  void    CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
660 {
661     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
662
663     switch (uMsg) {
664     case MOM_OPEN:
665     case MOM_CLOSE:
666         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
667         break;
668     case MOM_DONE:
669         if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
670             /* initial map is: 32 => 16 */
671             LPMIDIHDR           mh16 = MapSL(dwParam1);
672             LPMIDIHDR           mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
673
674             dwParam1 = (DWORD)mh32;
675             mh32->dwFlags = mh16->dwFlags;
676             mh32->dwOffset = mh16->dwOffset;
677             if (mh32->reserved >= sizeof(MIDIHDR))
678                 mh32->dwOffset = mh16->dwOffset;
679         } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
680             /* initial map is: 16 => 32 */
681             LPMIDIHDR           mh32 = (LPMIDIHDR)(dwParam1);
682             SEGPTR              segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
683             LPMIDIHDR           mh16 = MapSL(segmh16);
684
685             dwParam1 = (DWORD)segmh16;
686             mh16->dwFlags = mh32->dwFlags;
687             if (mh16->reserved >= sizeof(MIDIHDR))
688                 mh16->dwOffset = mh32->dwOffset;
689         }
690         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
691         break;
692     /* case MOM_POSITIONCB: */
693     default:
694         ERR("Unknown msg %u\n", uMsg);
695     }
696
697     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
698 }
699
700 /* =================================
701  *   W A V E  I N    M A P P E R S
702  * ================================= */
703
704 /**************************************************************************
705  *                              MMDRV_WaveIn_Map16To32W         [internal]
706  */
707 static  WINMM_MapType   MMDRV_WaveIn_Map16To32W  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
708 {
709     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
710
711     switch (wMsg) {
712     case WIDM_GETNUMDEVS:
713     case WIDM_RESET:
714     case WIDM_START:
715     case WIDM_STOP:
716         ret = WINMM_MAP_OK;
717         break;
718     case WIDM_OPEN:
719     case WIDM_CLOSE:
720         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
721         break;
722     case WIDM_GETDEVCAPS:
723         {
724             LPWAVEINCAPSW       wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSW));
725             LPWAVEINCAPS16      wic16 = MapSL(*lpParam1);
726
727             if (wic32) {
728                 *(LPWAVEINCAPS16*)wic32 = wic16;
729                 wic32 = (LPWAVEINCAPSW)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
730                 *lpParam1 = (DWORD)wic32;
731                 *lpParam2 = sizeof(WAVEINCAPSW);
732
733                 ret = WINMM_MAP_OKMEM;
734             } else {
735                 ret = WINMM_MAP_NOMEM;
736             }
737         }
738         break;
739     case WIDM_GETPOS:
740         {
741             LPMMTIME            mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
742             LPMMTIME16          mmt16 = MapSL(*lpParam1);
743
744             if (mmt32) {
745                 *(LPMMTIME16*)mmt32 = mmt16;
746                 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
747
748                 mmt32->wType = mmt16->wType;
749                 *lpParam1 = (DWORD)mmt32;
750                 *lpParam2 = sizeof(MMTIME);
751
752                 ret = WINMM_MAP_OKMEM;
753             } else {
754                 ret = WINMM_MAP_NOMEM;
755             }
756         }
757         break;
758     case WIDM_PREPARE:
759         {
760             LPWAVEHDR           wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
761             LPWAVEHDR           wh16 = MapSL(*lpParam1);
762
763             if (wh32) {
764                 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
765                 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
766                 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
767                 wh32->dwBufferLength = wh16->dwBufferLength;
768                 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
769                 wh32->dwUser = wh16->dwUser;
770                 wh32->dwFlags = wh16->dwFlags;
771                 wh32->dwLoops = wh16->dwLoops;
772                 /* FIXME: nothing on wh32->lpNext */
773                 /* could link the wh32->lpNext at this level for memory house keeping */
774                 wh16->lpNext = wh32; /* for reuse in unprepare and write */
775                 *lpParam1 = (DWORD)wh32;
776                 *lpParam2 = sizeof(WAVEHDR);
777
778                 ret = WINMM_MAP_OKMEM;
779             } else {
780                 ret = WINMM_MAP_NOMEM;
781             }
782         }
783         break;
784     case WIDM_ADDBUFFER:
785     case WIDM_UNPREPARE:
786         {
787             LPWAVEHDR           wh16 = MapSL(*lpParam1);
788             LPWAVEHDR           wh32 = wh16->lpNext;
789
790             *lpParam1 = (DWORD)wh32;
791             *lpParam2 = sizeof(WAVEHDR);
792             /* dwBufferLength can be reduced between prepare & write */
793             if (wMsg == WIDM_ADDBUFFER && wh32->dwBufferLength < wh16->dwBufferLength) {
794                 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
795                     wh32->dwBufferLength, wh16->dwBufferLength);
796             } else
797                 wh32->dwBufferLength = wh16->dwBufferLength;
798             ret = WINMM_MAP_OKMEM;
799         }
800         break;
801     case WIDM_MAPPER_STATUS:
802         /* just a single DWORD */
803         *lpParam2 = (DWORD)MapSL(*lpParam2);
804         ret = WINMM_MAP_OK;
805         break;
806     default:
807         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
808         break;
809     }
810     return ret;
811 }
812
813 /**************************************************************************
814  *                              MMDRV_WaveIn_UnMap16To32W       [internal]
815  */
816 static  WINMM_MapType   MMDRV_WaveIn_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
817 {
818     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
819
820     switch (wMsg) {
821     case WIDM_GETNUMDEVS:
822     case WIDM_RESET:
823     case WIDM_START:
824     case WIDM_STOP:
825     case WIDM_MAPPER_STATUS:
826         ret = WINMM_MAP_OK;
827         break;
828     case WIDM_OPEN:
829     case WIDM_CLOSE:
830         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
831         break;
832     case WIDM_GETDEVCAPS:
833         {
834             LPWAVEINCAPSW               wic32 = (LPWAVEINCAPSW)(*lpParam1);
835             LPWAVEINCAPS16              wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
836
837             wic16->wMid = wic32->wMid;
838             wic16->wPid = wic32->wPid;
839             wic16->vDriverVersion = wic32->vDriverVersion;
840             WideCharToMultiByte( CP_ACP, 0, wic32->szPname, -1, wic16->szPname,
841                                  sizeof(wic16->szPname), NULL, NULL );
842             wic16->dwFormats = wic32->dwFormats;
843             wic16->wChannels = wic32->wChannels;
844             HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
845             ret = WINMM_MAP_OK;
846         }
847         break;
848     case WIDM_GETPOS:
849         {
850             LPMMTIME            mmt32 = (LPMMTIME)(*lpParam1);
851             LPMMTIME16          mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
852
853             MMSYSTEM_MMTIME32to16(mmt16, mmt32);
854             HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
855             ret = WINMM_MAP_OK;
856         }
857         break;
858     case WIDM_ADDBUFFER:
859     case WIDM_PREPARE:
860     case WIDM_UNPREPARE:
861         {
862             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
863             LPWAVEHDR           wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
864
865             assert(wh16->lpNext == wh32);
866             wh16->dwBufferLength = wh32->dwBufferLength;
867             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
868             wh16->dwUser = wh32->dwUser;
869             wh16->dwFlags = wh32->dwFlags;
870             wh16->dwLoops = wh32->dwLoops;
871
872             if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
873                 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
874                 wh16->lpNext = 0;
875             }
876             ret = WINMM_MAP_OK;
877         }
878         break;
879     default:
880         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
881         break;
882     }
883     return ret;
884 }
885
886 /**************************************************************************
887  *                              MMDRV_WaveIn_Map32WTo16         [internal]
888  */
889 static  WINMM_MapType   MMDRV_WaveIn_Map32WTo16  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
890 {
891     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
892
893     switch (wMsg) {
894     case WIDM_CLOSE:
895     case WIDM_GETNUMDEVS:
896     case WIDM_RESET:
897     case WIDM_START:
898     case WIDM_STOP:
899         ret = WINMM_MAP_OK;
900         break;
901
902     case WIDM_OPEN:
903         {
904             LPWAVEOPENDESC              wod32 = (LPWAVEOPENDESC)*lpParam1;
905             int                         sz = sizeof(WAVEFORMATEX);
906             LPVOID                      ptr;
907             LPWAVEOPENDESC16            wod16;
908
909             /* allocated data are mapped as follows:
910                LPWAVEOPENDESC   ptr to orig lParam1
911                DWORD            orig dwUser, which is a pointer to DWORD:driver dwInstance
912                DWORD            dwUser passed to driver
913                WAVEOPENDESC16   wod16: openDesc passed to driver
914                WAVEFORMATEX     openDesc->lpFormat passed to driver
915                xxx              extra bytes to WAVEFORMATEX
916             */
917             if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
918                 TRACE("Allocating %u extra bytes (%d)\n", wod32->lpFormat->cbSize, wod32->lpFormat->wFormatTag);
919                 sz += wod32->lpFormat->cbSize;
920             }
921
922             ptr = HeapAlloc( GetProcessHeap(), 0,
923                              sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
924
925             if (ptr) {
926                 SEGPTR seg_ptr = MapLS( ptr );
927                 *(LPWAVEOPENDESC*)ptr = wod32;
928                 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
929                 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
930
931                 wod16->hWave = HWAVE_16(wod32->hWave);
932                 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
933                 memcpy(wod16 + 1, wod32->lpFormat, sz);
934
935                 wod16->dwCallback = wod32->dwCallback;
936                 wod16->dwInstance = wod32->dwInstance;
937                 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
938                 wod16->dnDevNode = wod32->dnDevNode;
939
940                 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
941                 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
942
943                 ret = WINMM_MAP_OKMEM;
944             } else {
945                 ret = WINMM_MAP_NOMEM;
946             }
947         }
948         break;
949     case WIDM_PREPARE:
950         {
951             LPWAVEHDR           wh32 = (LPWAVEHDR)*lpParam1;
952             LPWAVEHDR           wh16;
953             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
954                                     sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
955
956             if (ptr) {
957                 SEGPTR seg_ptr = MapLS( ptr );
958                 *(LPWAVEHDR*)ptr = wh32;
959                 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
960                 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
961                 /* data will be copied on WODM_WRITE */
962                 wh16->dwBufferLength = wh32->dwBufferLength;
963                 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
964                 wh16->dwUser = wh32->dwUser;
965                 wh16->dwFlags = wh32->dwFlags;
966                 wh16->dwLoops = wh32->dwLoops;
967                 /* FIXME: nothing on wh32->lpNext */
968                 /* could link the wh32->lpNext at this level for memory house keeping */
969                 wh32->lpNext = wh16; /* for reuse in unprepare and write */
970                 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
971                 *lpParam2 = sizeof(WAVEHDR);
972                 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
973                       *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
974
975                 ret = WINMM_MAP_OKMEM;
976             } else {
977                 ret = WINMM_MAP_NOMEM;
978             }
979         }
980         break;
981     case WIDM_ADDBUFFER:
982     case WIDM_UNPREPARE:
983         {
984             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
985             LPWAVEHDR           wh16 = wh32->lpNext;
986             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
987             SEGPTR seg_ptr = MapLS( ptr );
988
989             assert(*(LPWAVEHDR*)ptr == wh32);
990
991             if (wMsg == WIDM_ADDBUFFER)
992                 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
993
994             *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
995             *lpParam2 = sizeof(WAVEHDR);
996             TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
997                   *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
998
999             /* dwBufferLength can be reduced between prepare & write */
1000             if (wMsg == WIDM_ADDBUFFER && wh16->dwBufferLength < wh32->dwBufferLength) {
1001                 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1002                     wh16->dwBufferLength, wh32->dwBufferLength);
1003             } else
1004                 wh16->dwBufferLength = wh32->dwBufferLength;
1005             ret = WINMM_MAP_OKMEM;
1006         }
1007         break;
1008    case WIDM_GETDEVCAPS:
1009         {
1010             LPWAVEINCAPSW wic32 = (LPWAVEINCAPSW)*lpParam1;
1011             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSW) + sizeof(WAVEINCAPS16));
1012
1013             if (ptr) {
1014                 *(LPWAVEINCAPSW*)ptr = wic32;
1015                 ret = WINMM_MAP_OKMEM;
1016             } else {
1017                 ret = WINMM_MAP_NOMEM;
1018             }
1019             *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSW);
1020             *lpParam2 = sizeof(WAVEINCAPS16);
1021         }
1022         break;
1023     case WIDM_GETPOS:
1024         {
1025             LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1026             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1027             LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1028
1029             if (ptr) {
1030                 *(LPMMTIME*)ptr = mmt32;
1031                 mmt16->wType = mmt32->wType;
1032                 ret = WINMM_MAP_OKMEM;
1033             } else {
1034                 ret = WINMM_MAP_NOMEM;
1035             }
1036             *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1037             *lpParam2 = sizeof(MMTIME16);
1038         }
1039         break;
1040     case DRVM_MAPPER_STATUS:
1041         {
1042             LPDWORD p32 = (LPDWORD)*lpParam2;
1043             *lpParam2 = MapLS(p32);
1044             ret = WINMM_MAP_OKMEM;
1045         }
1046         break;
1047     default:
1048         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1049         break;
1050     }
1051     return ret;
1052 }
1053
1054 /**************************************************************************
1055  *                              MMDRV_WaveIn_UnMap32WTo16       [internal]
1056  */
1057 static  WINMM_MapType   MMDRV_WaveIn_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1058 {
1059     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
1060
1061     switch (wMsg) {
1062     case WIDM_CLOSE:
1063     case WIDM_GETNUMDEVS:
1064     case WIDM_RESET:
1065     case WIDM_START:
1066     case WIDM_STOP:
1067         ret = WINMM_MAP_OK;
1068         break;
1069
1070     case WIDM_OPEN:
1071         {
1072             LPWAVEOPENDESC16            wod16 = MapSL(*lpParam1);
1073             LPSTR                       ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1074             LPWAVEOPENDESC              wod32 = *(LPWAVEOPENDESC*)ptr;
1075
1076             UnMapLS( *lpParam1 );
1077             wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1078             **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1079             HeapFree( GetProcessHeap(), 0, ptr );
1080             ret = WINMM_MAP_OK;
1081         }
1082         break;
1083
1084     case WIDM_ADDBUFFER:
1085     case WIDM_PREPARE:
1086     case WIDM_UNPREPARE:
1087         {
1088             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1089             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1090             LPWAVEHDR           wh32 = *(LPWAVEHDR*)ptr;
1091
1092             assert(wh32->lpNext == wh16);
1093             wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1094             wh32->dwUser = wh16->dwUser;
1095             wh32->dwFlags = wh16->dwFlags;
1096             wh32->dwLoops = wh16->dwLoops;
1097             UnMapLS( *lpParam1 );
1098
1099             if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1100                 HeapFree( GetProcessHeap(), 0, ptr );
1101                 wh32->lpNext = 0;
1102             }
1103             ret = WINMM_MAP_OK;
1104         }
1105         break;
1106      case WIDM_GETDEVCAPS:
1107         {
1108             LPWAVEINCAPS16              wic16 = MapSL(*lpParam1);
1109             LPSTR                       ptr   = (LPSTR)wic16 - sizeof(LPWAVEINCAPSW);
1110             LPWAVEINCAPSW               wic32 = *(LPWAVEINCAPSW*)ptr;
1111
1112             wic32->wMid = wic16->wMid;
1113             wic32->wPid = wic16->wPid;
1114             wic32->vDriverVersion = wic16->vDriverVersion;
1115             WideCharToMultiByte( CP_ACP, 0, wic32->szPname, -1, wic16->szPname,
1116                                  sizeof(wic16->szPname), NULL, NULL );
1117             wic32->dwFormats = wic16->dwFormats;
1118             wic32->wChannels = wic16->wChannels;
1119             UnMapLS( *lpParam1 );
1120             HeapFree( GetProcessHeap(), 0, ptr );
1121             ret = WINMM_MAP_OK;
1122         }
1123         break;
1124     case WIDM_GETPOS:
1125         {
1126             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1127             LPSTR               ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
1128             LPMMTIME            mmt32 = *(LPMMTIME*)ptr;
1129
1130             MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1131             UnMapLS( *lpParam1 );
1132             HeapFree( GetProcessHeap(), 0, ptr );
1133             ret = WINMM_MAP_OK;
1134         }
1135         break;
1136     case DRVM_MAPPER_STATUS:
1137         {
1138             UnMapLS( *lpParam2 );
1139             ret = WINMM_MAP_OK;
1140         }
1141         break;
1142     default:
1143         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1144         break;
1145     }
1146     return ret;
1147 }
1148
1149 /**************************************************************************
1150  *                              MMDRV_WaveIn_Callback           [internal]
1151  */
1152 static  void    CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1153 {
1154     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
1155
1156     switch (uMsg) {
1157     case WIM_OPEN:
1158     case WIM_CLOSE:
1159         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1160         break;
1161     case WIM_DATA:
1162         if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1163             /* initial map is: 32 => 16 */
1164             LPWAVEHDR           wh16 = MapSL(dwParam1);
1165             LPWAVEHDR           wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1166
1167             dwParam1 = (DWORD)wh32;
1168             wh32->dwFlags = wh16->dwFlags;
1169             wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1170         } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1171             /* initial map is: 16 => 32 */
1172             LPWAVEHDR           wh32 = (LPWAVEHDR)(dwParam1);
1173             SEGPTR              segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1174             LPWAVEHDR           wh16 = MapSL(segwh16);
1175
1176             dwParam1 = (DWORD)segwh16;
1177             wh16->dwFlags = wh32->dwFlags;
1178             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1179         }
1180         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1181         break;
1182     default:
1183         ERR("Unknown msg %u\n", uMsg);
1184     }
1185
1186     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1187 }
1188
1189 /* =================================
1190  *   W A V E  O U T  M A P P E R S
1191  * ================================= */
1192
1193 /**************************************************************************
1194  *                              MMDRV_WaveOut_Map16To32W        [internal]
1195  */
1196 static  WINMM_MapType   MMDRV_WaveOut_Map16To32W  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
1197 {
1198     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
1199
1200     switch (wMsg) {
1201     /* nothing to do */
1202     case WODM_BREAKLOOP:
1203     case WODM_CLOSE:
1204     case WODM_GETNUMDEVS:
1205     case WODM_PAUSE:
1206     case WODM_RESET:
1207     case WODM_RESTART:
1208     case WODM_SETPITCH:
1209     case WODM_SETPLAYBACKRATE:
1210     case WODM_SETVOLUME:
1211         ret = WINMM_MAP_OK;
1212         break;
1213
1214     case WODM_GETPITCH:
1215     case WODM_GETPLAYBACKRATE:
1216     case WODM_GETVOLUME:
1217     case WODM_OPEN:
1218         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1219         break;
1220
1221     case WODM_GETDEVCAPS:
1222         {
1223             LPWAVEOUTCAPSW              woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSW));
1224             LPWAVEOUTCAPS16             woc16 = MapSL(*lpParam1);
1225
1226             if (woc32) {
1227                 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1228                 woc32 = (LPWAVEOUTCAPSW)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1229                 *lpParam1 = (DWORD)woc32;
1230                 *lpParam2 = sizeof(WAVEOUTCAPSW);
1231
1232                 ret = WINMM_MAP_OKMEM;
1233             } else {
1234                 ret = WINMM_MAP_NOMEM;
1235             }
1236         }
1237         break;
1238     case WODM_GETPOS:
1239         {
1240             LPMMTIME            mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1241             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1242
1243             if (mmt32) {
1244                 *(LPMMTIME16*)mmt32 = mmt16;
1245                 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1246
1247                 mmt32->wType = mmt16->wType;
1248                 *lpParam1 = (DWORD)mmt32;
1249                 *lpParam2 = sizeof(MMTIME);
1250
1251                 ret = WINMM_MAP_OKMEM;
1252             } else {
1253                 ret = WINMM_MAP_NOMEM;
1254             }
1255         }
1256         break;
1257     case WODM_PREPARE:
1258         {
1259             LPWAVEHDR           wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1260             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1261
1262             if (wh32) {
1263                 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1264                 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1265                 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1266                 wh32->dwBufferLength = wh16->dwBufferLength;
1267                 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1268                 wh32->dwUser = wh16->dwUser;
1269                 wh32->dwFlags = wh16->dwFlags;
1270                 wh32->dwLoops = wh16->dwLoops;
1271                 /* FIXME: nothing on wh32->lpNext */
1272                 /* could link the wh32->lpNext at this level for memory house keeping */
1273                 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1274                 *lpParam1 = (DWORD)wh32;
1275                 *lpParam2 = sizeof(WAVEHDR);
1276
1277                 ret = WINMM_MAP_OKMEM;
1278             } else {
1279                 ret = WINMM_MAP_NOMEM;
1280             }
1281         }
1282         break;
1283     case WODM_UNPREPARE:
1284     case WODM_WRITE:
1285         {
1286             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1287             LPWAVEHDR           wh32 = wh16->lpNext;
1288
1289             *lpParam1 = (DWORD)wh32;
1290             *lpParam2 = sizeof(WAVEHDR);
1291             /* dwBufferLength can be reduced between prepare & write */
1292             if (wMsg == WODM_WRITE && wh32->dwBufferLength < wh16->dwBufferLength) {
1293                 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1294                     wh32->dwBufferLength, wh16->dwBufferLength);
1295             } else
1296                 wh32->dwBufferLength = wh16->dwBufferLength;
1297             ret = WINMM_MAP_OKMEM;
1298         }
1299         break;
1300     case WODM_MAPPER_STATUS:
1301         *lpParam2 = (DWORD)MapSL(*lpParam2);
1302         ret = WINMM_MAP_OK;
1303         break;
1304     default:
1305         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1306         break;
1307     }
1308     return ret;
1309 }
1310
1311 /**************************************************************************
1312  *                              MMDRV_WaveOut_UnMap16To32W      [internal]
1313  */
1314 static  WINMM_MapType   MMDRV_WaveOut_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1315 {
1316     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
1317
1318     switch (wMsg) {
1319     /* nothing to do */
1320     case WODM_BREAKLOOP:
1321     case WODM_CLOSE:
1322     case WODM_GETNUMDEVS:
1323     case WODM_PAUSE:
1324     case WODM_RESET:
1325     case WODM_RESTART:
1326     case WODM_SETPITCH:
1327     case WODM_SETPLAYBACKRATE:
1328     case WODM_SETVOLUME:
1329     case WODM_MAPPER_STATUS:
1330         ret = WINMM_MAP_OK;
1331         break;
1332
1333     case WODM_GETPITCH:
1334     case WODM_GETPLAYBACKRATE:
1335     case WODM_GETVOLUME:
1336     case WODM_OPEN:
1337         FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1338         break;
1339
1340     case WODM_GETDEVCAPS:
1341         {
1342             LPWAVEOUTCAPSW              woc32 = (LPWAVEOUTCAPSW)(*lpParam1);
1343             LPWAVEOUTCAPS16             woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1344
1345             woc16->wMid = woc32->wMid;
1346             woc16->wPid = woc32->wPid;
1347             woc16->vDriverVersion = woc32->vDriverVersion;
1348             WideCharToMultiByte( CP_ACP, 0, woc32->szPname, -1, woc16->szPname,
1349                                  sizeof(woc16->szPname), NULL, NULL );
1350             woc16->dwFormats = woc32->dwFormats;
1351             woc16->wChannels = woc32->wChannels;
1352             woc16->dwSupport = woc32->dwSupport;
1353             HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1354             ret = WINMM_MAP_OK;
1355         }
1356         break;
1357     case WODM_GETPOS:
1358         {
1359             LPMMTIME            mmt32 = (LPMMTIME)(*lpParam1);
1360             LPMMTIME16          mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1361
1362             MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1363             HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1364             ret = WINMM_MAP_OK;
1365         }
1366         break;
1367     case WODM_PREPARE:
1368     case WODM_UNPREPARE:
1369     case WODM_WRITE:
1370         {
1371             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
1372             LPWAVEHDR           wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1373
1374             assert(wh16->lpNext == wh32);
1375             wh16->dwBufferLength = wh32->dwBufferLength;
1376             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1377             wh16->dwUser = wh32->dwUser;
1378             wh16->dwFlags = wh32->dwFlags;
1379             wh16->dwLoops = wh32->dwLoops;
1380
1381             if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1382                 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1383                 wh16->lpNext = 0;
1384             }
1385             ret = WINMM_MAP_OK;
1386         }
1387         break;
1388     default:
1389         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1390         break;
1391     }
1392     return ret;
1393 }
1394
1395 /**************************************************************************
1396  *                              MMDRV_WaveOut_Map32WTo16        [internal]
1397  */
1398 static  WINMM_MapType   MMDRV_WaveOut_Map32WTo16  (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
1399 {
1400     WINMM_MapType       ret;
1401
1402     switch (wMsg) {
1403         /* nothing to do */
1404     case WODM_BREAKLOOP:
1405     case WODM_CLOSE:
1406     case WODM_GETNUMDEVS:
1407     case WODM_PAUSE:
1408     case WODM_RESET:
1409     case WODM_RESTART:
1410     case WODM_SETPITCH:
1411     case WODM_SETPLAYBACKRATE:
1412     case WODM_SETVOLUME:
1413         ret = WINMM_MAP_OK;
1414         break;
1415
1416     case WODM_GETDEVCAPS:
1417         {
1418             LPWAVEOUTCAPSW woc32 = (LPWAVEOUTCAPSW)*lpParam1;
1419             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1420                                    sizeof(LPWAVEOUTCAPSW) + sizeof(WAVEOUTCAPS16));
1421
1422             if (ptr) {
1423                 *(LPWAVEOUTCAPSW*)ptr = woc32;
1424                 ret = WINMM_MAP_OKMEM;
1425             } else {
1426                 ret = WINMM_MAP_NOMEM;
1427             }
1428             *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSW);
1429             *lpParam2 = sizeof(WAVEOUTCAPS16);
1430         }
1431         break;
1432     case WODM_GETPITCH:
1433         FIXME("NIY: no conversion yet\n");
1434         ret = WINMM_MAP_MSGERROR;
1435         break;
1436     case WODM_GETPLAYBACKRATE:
1437         FIXME("NIY: no conversion yet\n");
1438         ret = WINMM_MAP_MSGERROR;
1439         break;
1440     case WODM_GETPOS:
1441         {
1442             LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1443             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1444             LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1445
1446             if (ptr) {
1447                 *(LPMMTIME*)ptr = mmt32;
1448                 mmt16->wType = mmt32->wType;
1449                 ret = WINMM_MAP_OKMEM;
1450             } else {
1451                 ret = WINMM_MAP_NOMEM;
1452             }
1453             *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1454             *lpParam2 = sizeof(MMTIME16);
1455         }
1456         break;
1457     case WODM_GETVOLUME:
1458         FIXME("NIY: no conversion yet\n");
1459         ret = WINMM_MAP_MSGERROR;
1460         break;
1461     case WODM_OPEN:
1462         {
1463             LPWAVEOPENDESC              wod32 = (LPWAVEOPENDESC)*lpParam1;
1464             int                         sz = sizeof(WAVEFORMATEX);
1465             LPVOID                      ptr;
1466             LPWAVEOPENDESC16            wod16;
1467
1468             /* allocated data are mapped as follows:
1469                LPWAVEOPENDESC   ptr to orig lParam1
1470                DWORD            orig dwUser, which is a pointer to DWORD:driver dwInstance
1471                DWORD            dwUser passed to driver
1472                WAVEOPENDESC16   wod16: openDesc passed to driver
1473                WAVEFORMATEX     openDesc->lpFormat passed to driver
1474                xxx              extra bytes to WAVEFORMATEX
1475             */
1476             if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1477                 TRACE("Allocating %u extra bytes (%d)\n", wod32->lpFormat->cbSize, wod32->lpFormat->wFormatTag);
1478                 sz += wod32->lpFormat->cbSize;
1479             }
1480
1481             ptr = HeapAlloc( GetProcessHeap(), 0,
1482                              sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1483
1484             if (ptr) {
1485                 SEGPTR seg_ptr = MapLS( ptr );
1486                 *(LPWAVEOPENDESC*)ptr = wod32;
1487                 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1488                 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1489
1490                 wod16->hWave = HWAVE_16(wod32->hWave);
1491                 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1492                 memcpy(wod16 + 1, wod32->lpFormat, sz);
1493
1494                 wod16->dwCallback = wod32->dwCallback;
1495                 wod16->dwInstance = wod32->dwInstance;
1496                 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1497                 wod16->dnDevNode = wod32->dnDevNode;
1498
1499                 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1500                 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1501
1502                 ret = WINMM_MAP_OKMEM;
1503             } else {
1504                 ret = WINMM_MAP_NOMEM;
1505             }
1506         }
1507         break;
1508     case WODM_PREPARE:
1509         {
1510             LPWAVEHDR           wh32 = (LPWAVEHDR)*lpParam1;
1511             LPWAVEHDR           wh16;
1512             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1513                                     sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1514
1515             if (ptr) {
1516                 SEGPTR seg_ptr = MapLS( ptr );
1517                 *(LPWAVEHDR*)ptr = wh32;
1518                 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1519                 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1520                 /* data will be copied on WODM_WRITE */
1521                 wh16->dwBufferLength = wh32->dwBufferLength;
1522                 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1523                 wh16->dwUser = wh32->dwUser;
1524                 wh16->dwFlags = wh32->dwFlags;
1525                 wh16->dwLoops = wh32->dwLoops;
1526                 /* FIXME: nothing on wh32->lpNext */
1527                 /* could link the wh32->lpNext at this level for memory house keeping */
1528                 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1529                 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1530                 *lpParam2 = sizeof(WAVEHDR);
1531                 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
1532                       *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
1533
1534                 ret = WINMM_MAP_OKMEM;
1535             } else {
1536                 ret = WINMM_MAP_NOMEM;
1537             }
1538         }
1539         break;
1540     case WODM_UNPREPARE:
1541     case WODM_WRITE:
1542         {
1543             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
1544             LPWAVEHDR           wh16 = wh32->lpNext;
1545             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1546             SEGPTR seg_ptr = MapLS( ptr );
1547
1548             assert(*(LPWAVEHDR*)ptr == wh32);
1549
1550             if (wMsg == WODM_WRITE)
1551                 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1552
1553             *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1554             *lpParam2 = sizeof(WAVEHDR);
1555             TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
1556                   *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
1557
1558             /* dwBufferLength can be reduced between prepare & write */
1559             if (wMsg == WODM_WRITE && wh16->dwBufferLength < wh32->dwBufferLength) {
1560                 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1561                     wh16->dwBufferLength, wh32->dwBufferLength);
1562             } else
1563                 wh16->dwBufferLength = wh32->dwBufferLength;
1564             ret = WINMM_MAP_OKMEM;
1565         }
1566         break;
1567     case DRVM_MAPPER_STATUS:
1568         {
1569             LPDWORD p32 = (LPDWORD)*lpParam2;
1570             *lpParam2 = MapLS(p32);
1571             ret = WINMM_MAP_OKMEM;
1572         }
1573         break;
1574     default:
1575         FIXME("NIY: no conversion yet\n");
1576         ret = WINMM_MAP_MSGERROR;
1577         break;
1578     }
1579     return ret;
1580 }
1581
1582 /**************************************************************************
1583  *                              MMDRV_WaveOut_UnMap32WTo16      [internal]
1584  */
1585 static  WINMM_MapType   MMDRV_WaveOut_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1586 {
1587     WINMM_MapType       ret;
1588
1589     switch (wMsg) {
1590         /* nothing to do */
1591     case WODM_BREAKLOOP:
1592     case WODM_CLOSE:
1593     case WODM_GETNUMDEVS:
1594     case WODM_PAUSE:
1595     case WODM_RESET:
1596     case WODM_RESTART:
1597     case WODM_SETPITCH:
1598     case WODM_SETPLAYBACKRATE:
1599     case WODM_SETVOLUME:
1600         ret = WINMM_MAP_OK;
1601         break;
1602
1603     case WODM_GETDEVCAPS:
1604         {
1605             LPWAVEOUTCAPS16             woc16 = MapSL(*lpParam1);
1606             LPSTR                       ptr   = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSW);
1607             LPWAVEOUTCAPSW              woc32 = *(LPWAVEOUTCAPSW*)ptr;
1608
1609             woc32->wMid = woc16->wMid;
1610             woc32->wPid = woc16->wPid;
1611             woc32->vDriverVersion = woc16->vDriverVersion;
1612             WideCharToMultiByte( CP_ACP, 0, woc32->szPname, -1, woc16->szPname,
1613                                  sizeof(woc16->szPname), NULL, NULL );
1614             woc32->dwFormats = woc16->dwFormats;
1615             woc32->wChannels = woc16->wChannels;
1616             woc32->dwSupport = woc16->dwSupport;
1617             UnMapLS( *lpParam1 );
1618             HeapFree( GetProcessHeap(), 0, ptr );
1619             ret = WINMM_MAP_OK;
1620         }
1621         break;
1622     case WODM_GETPITCH:
1623         FIXME("NIY: no conversion yet\n");
1624         ret = WINMM_MAP_MSGERROR;
1625         break;
1626     case WODM_GETPLAYBACKRATE:
1627         FIXME("NIY: no conversion yet\n");
1628         ret = WINMM_MAP_MSGERROR;
1629         break;
1630     case WODM_GETPOS:
1631         {
1632             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1633             LPSTR               ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
1634             LPMMTIME            mmt32 = *(LPMMTIME*)ptr;
1635
1636             MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1637             UnMapLS( *lpParam1 );
1638             HeapFree( GetProcessHeap(), 0, ptr );
1639             ret = WINMM_MAP_OK;
1640         }
1641         break;
1642     case WODM_OPEN:
1643         {
1644             LPWAVEOPENDESC16            wod16 = MapSL(*lpParam1);
1645             LPSTR                       ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1646             LPWAVEOPENDESC              wod32 = *(LPWAVEOPENDESC*)ptr;
1647
1648             wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1649             **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1650             UnMapLS( *lpParam1 );
1651             HeapFree( GetProcessHeap(), 0, ptr );
1652             ret = WINMM_MAP_OK;
1653         }
1654         break;
1655     case WODM_PREPARE:
1656     case WODM_UNPREPARE:
1657     case WODM_WRITE:
1658         {
1659             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1660             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1661             LPWAVEHDR           wh32 = *(LPWAVEHDR*)ptr;
1662
1663             assert(wh32->lpNext == wh16);
1664             wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1665             wh32->dwUser = wh16->dwUser;
1666             wh32->dwFlags = wh16->dwFlags;
1667             wh32->dwLoops = wh16->dwLoops;
1668
1669             UnMapLS( *lpParam1 );
1670             if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1671                 HeapFree( GetProcessHeap(), 0, ptr );
1672                 wh32->lpNext = 0;
1673             }
1674             ret = WINMM_MAP_OK;
1675         }
1676         break;
1677     case WODM_GETVOLUME:
1678         FIXME("NIY: no conversion yet\n");
1679         ret = WINMM_MAP_MSGERROR;
1680         break;
1681     case DRVM_MAPPER_STATUS:
1682         {
1683             UnMapLS( *lpParam2 );
1684             ret = WINMM_MAP_OK;
1685         }
1686         break;
1687     default:
1688         FIXME("NIY: no conversion yet\n");
1689         ret = WINMM_MAP_MSGERROR;
1690         break;
1691     }
1692     return ret;
1693 }
1694
1695 /**************************************************************************
1696  *                              MMDRV_WaveOut_Callback          [internal]
1697  */
1698 static  void    CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1699 {
1700     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
1701
1702     switch (uMsg) {
1703     case WOM_OPEN:
1704     case WOM_CLOSE:
1705         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1706         break;
1707     case WOM_DONE:
1708         if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1709             /* initial map is: 32 => 16 */
1710             LPWAVEHDR           wh16 = MapSL(dwParam1);
1711             LPWAVEHDR           wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1712
1713             dwParam1 = (DWORD)wh32;
1714             wh32->dwFlags = wh16->dwFlags;
1715         } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1716             /* initial map is: 16 => 32 */
1717             LPWAVEHDR           wh32 = (LPWAVEHDR)(dwParam1);
1718             SEGPTR              segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1719             LPWAVEHDR           wh16 = MapSL(segwh16);
1720
1721             dwParam1 = (DWORD)segwh16;
1722             wh16->dwFlags = wh32->dwFlags;
1723         }
1724         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1725         break;
1726     default:
1727         ERR("Unknown msg %u\n", uMsg);
1728     }
1729
1730     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1731 }
1732
1733 /* =================================
1734  *  M A P P E R S   H A N D L I N G
1735  * ================================= */
1736
1737 static  LRESULT    MMDRV_CallMMDrvFunc16(DWORD fp16, WORD dev, WORD msg, LONG instance,
1738                                          LONG lp1, LONG lp2)
1739 {
1740     WORD args[8];
1741     DWORD ret;
1742
1743     args[7] = dev;
1744     args[6] = msg;
1745     args[5] = HIWORD(instance);
1746     args[4] = LOWORD(instance);
1747     args[3] = HIWORD(lp1);
1748     args[2] = LOWORD(lp1);
1749     args[1] = HIWORD(lp2);
1750     args[0] = LOWORD(lp2);
1751     WOWCallback16Ex( fp16, WCB16_PASCAL, sizeof(args), args, &ret );
1752     return LOWORD(ret);
1753 }
1754
1755 /**************************************************************************
1756  *                              MMDRV_GetDescription16          [internal]
1757  */
1758 static  BOOL    MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
1759 {
1760     OFSTRUCT    ofs;
1761     HFILE       hFile;
1762     WORD        w;
1763     DWORD       dw;
1764     BOOL        ret = FALSE;
1765
1766     if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
1767         ERR("Can't open file %s (builtin driver ?)\n", fname);
1768         return FALSE;
1769     }
1770
1771 #define E(_x)   do {TRACE _x;goto theEnd;} while(0)
1772
1773     if (_lread(hFile, &w, 2) != 2)                      E(("Can't read sig\n"));
1774     if (w != ('Z' * 256 + 'M'))                         E(("Bad sig %04x\n", w));
1775     if (_llseek(hFile, 0x3C, SEEK_SET) < 0)             E(("Can't seek to ext header offset\n"));
1776     if (_lread(hFile, &dw, 4) != 4)                     E(("Can't read ext header offset\n"));
1777     if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0)        E(("Can't seek to ext header.nr table %u\n", dw+0x2C));
1778     if (_lread(hFile, &dw, 4) != 4)                     E(("Can't read nr table offset\n"));
1779     if (_llseek(hFile, dw, SEEK_SET) < 0)               E(("Can't seek to nr table %u\n", dw));
1780     if (_lread(hFile, buf, 1) != 1)                     E(("Can't read descr length\n"));
1781     buflen = min((int)(unsigned)(BYTE)buf[0], buflen - 1);
1782     if (_lread(hFile, buf, buflen) != buflen)           E(("Can't read descr (%d)\n", buflen));
1783     buf[buflen] = '\0';
1784     ret = TRUE;
1785     TRACE("Got '%s' [%d]\n", buf, buflen);
1786 theEnd:
1787     _lclose(hFile);
1788     return ret;
1789 }
1790
1791 /******************************************************************
1792  *              MMDRV_LoadMMDrvFunc16
1793  *
1794  */
1795 static unsigned MMDRV_LoadMMDrvFunc16(LPCSTR drvName, LPWINE_DRIVER d,
1796                                       LPWINE_MM_DRIVER lpDrv)
1797 {
1798     WINEMM_msgFunc16    func;
1799     unsigned            count = 0;
1800     char                buffer[128];
1801     /*
1802      * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
1803      * The beginning of the module description indicates the driver supports
1804      * waveform, auxiliary, and mixer devices. Use one of the following
1805      * device-type names, followed by a colon (:) to indicate the type of
1806      * device your driver supports. If the driver supports more than one
1807      * type of device, separate each device-type name with a comma (,).
1808      *
1809      * wave for waveform audio devices
1810      * wavemapper for wave mappers
1811      * midi for MIDI audio devices
1812      * midimapper for midi mappers
1813      * aux for auxiliary audio devices
1814      * mixer for mixer devices
1815      */
1816
1817     if (d->d.d16.hDriver16) {
1818         HMODULE16       hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
1819
1820 #define AA(_h,_w,_x,_y,_z)                                      \
1821     func = (WINEMM_msgFunc##_y) _z ((_h), #_x);                 \
1822     if (func != NULL)                                           \
1823         { lpDrv->parts[_w].u.fnMessage##_y = func; count++;     \
1824           TRACE("Got %d bit func '%s'\n", _y, #_x);         }
1825
1826 #define A(_x,_y)        AA(hMod16,_x,_y,16,GetProcAddress16)
1827         A(MMDRV_AUX,    auxMessage);
1828         A(MMDRV_MIXER,  mxdMessage);
1829         A(MMDRV_MIDIIN, midMessage);
1830         A(MMDRV_MIDIOUT,modMessage);
1831         A(MMDRV_WAVEIN, widMessage);
1832         A(MMDRV_WAVEOUT,wodMessage);
1833 #undef A
1834 #undef AA
1835     }
1836     if (TRACE_ON(winmm)) {
1837         if (MMDRV_GetDescription16(drvName, buffer, sizeof(buffer)))
1838             TRACE("%s => %s\n", drvName, buffer);
1839         else
1840             TRACE("%s => No description\n", drvName);
1841     }
1842
1843     return count;
1844 }
1845
1846 /* =================================
1847  *              M C I
1848  * ================================= */
1849
1850 /*
1851  * 0000 stop
1852  * 0001 squeeze   signed 4 bytes to 2 bytes     *( LPINT16)D = ( INT16)*( LPINT16)S; D += 2;     S += 4
1853  * 0010 squeeze unsigned 4 bytes to 2 bytes     *(LPUINT16)D = (UINT16)*(LPUINT16)S; D += 2;     S += 4
1854  * 0100
1855  * 0101
1856  * 0110 zero 4 bytes                            *(DWORD)D = 0                        D += 4;     S += 4
1857  * 0111 copy string                             *(LPSTR*)D = seg dup(*(LPSTR*)S)     D += 4;     S += 4
1858  * 1xxx copy xxx + 1 bytes                      memcpy(D, S, xxx + 1);               D += xxx+1; S += xxx+1
1859  */
1860
1861 /**************************************************************************
1862  *                      MCI_MsgMapper32WTo16_Create             [internal]
1863  *
1864  * Helper for MCI_MapMsg32WTo16.
1865  * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit
1866  * segmented pointer.
1867  * map contains a list of action to be performed for the mapping (see list
1868  * above)
1869  * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area.
1870  */
1871 static  WINMM_MapType   MCI_MsgMapper32WTo16_Create(void** ptr, int size16, DWORD map, BOOLEAN keep)
1872 {
1873     void*       lp = HeapAlloc( GetProcessHeap(), 0, (keep ? sizeof(void**) : 0) + size16 );
1874     LPBYTE      p16, p32;
1875
1876     if (!lp) {
1877         return WINMM_MAP_NOMEM;
1878     }
1879     p32 = *ptr;
1880     if (keep) {
1881         *(void**)lp = *ptr;
1882         p16 = (LPBYTE)lp + sizeof(void**);
1883         *ptr = (char*)MapLS(lp) + sizeof(void**);
1884     } else {
1885         p16 = lp;
1886         *ptr = (void*)MapLS(lp);
1887     }
1888
1889     if (map == 0) {
1890         memcpy(p16, p32, size16);
1891     } else {
1892         unsigned        nibble;
1893         unsigned        sz;
1894
1895         while (map & 0xF) {
1896             nibble = map & 0xF;
1897             if (nibble & 0x8) {
1898                 sz = (nibble & 7) + 1;
1899                 memcpy(p16, p32, sz);
1900                 p16 += sz;
1901                 p32 += sz;
1902                 size16 -= sz;   /* DEBUG only */
1903             } else {
1904                 switch (nibble) {
1905                 case 0x1:
1906                     *(LPINT16)p16 = *(LPINT)p32;
1907                     p16 += sizeof(INT16);
1908                     p32 += sizeof(INT);
1909                     size16 -= sizeof(INT16);
1910                     break;
1911                 case 0x2:
1912                     *(LPUINT16)p16 = *(LPUINT)p32;
1913                     p16 += sizeof(UINT16);
1914                     p32 += sizeof(UINT);
1915                     size16 -= sizeof(UINT16);
1916                     break;
1917                 case 0x6:
1918                     *(LPDWORD)p16 = 0;
1919                     p16 += sizeof(DWORD);
1920                     p32 += sizeof(DWORD);
1921                     size16 -= sizeof(DWORD);
1922                     break;
1923                 case 0x7:
1924                     *(SEGPTR *)p16 = MapLS( MCI_strdupWtoA( *(LPCWSTR *)p32 ) );
1925                     p16 += sizeof(SEGPTR);
1926                     p32 += sizeof(LPSTR);
1927                     size16 -= sizeof(SEGPTR);
1928                     break;
1929                 default:
1930                     FIXME("Unknown nibble for mapping (%x)\n", nibble);
1931                 }
1932             }
1933             map >>= 4;
1934         }
1935         if (size16 != 0) /* DEBUG only */
1936             FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
1937     }
1938     return WINMM_MAP_OKMEM;
1939 }
1940
1941 /**************************************************************************
1942  *                      MCI_MsgMapper32WTo16_Destroy            [internal]
1943  *
1944  * Helper for MCI_UnMapMsg32WTo16.
1945  */
1946 static  WINMM_MapType   MCI_MsgMapper32WTo16_Destroy(void* ptr, int size16, DWORD map, BOOLEAN kept)
1947 {
1948     if (ptr) {
1949         void*           msg16 = MapSL((SEGPTR)ptr);
1950         void*           alloc;
1951         LPBYTE          p32, p16;
1952         unsigned        nibble;
1953
1954         UnMapLS( (SEGPTR)ptr );
1955         if (kept) {
1956             alloc = (char*)msg16 - sizeof(void**);
1957             p32 = *(void**)alloc;
1958             p16 = msg16;
1959
1960             if (map == 0) {
1961                 memcpy(p32, p16, size16);
1962             } else {
1963                 while (map & 0xF) {
1964                     nibble = map & 0xF;
1965                     if (nibble & 0x8) {
1966                         memcpy(p32, p16, (nibble & 7) + 1);
1967                         p16 += (nibble & 7) + 1;
1968                         p32 += (nibble & 7) + 1;
1969                         size16 -= (nibble & 7) + 1;
1970                     } else {
1971                         switch (nibble) {
1972                         case 0x1:
1973                             *(LPINT)p32 = *(LPINT16)p16;
1974                             p16 += sizeof(INT16);
1975                             p32 += sizeof(INT);
1976                             size16 -= sizeof(INT16);
1977                             break;
1978                         case 0x2:
1979                             *(LPUINT)p32 = *(LPUINT16)p16;
1980                             p16 += sizeof(UINT16);
1981                             p32 += sizeof(UINT);
1982                             size16 -= sizeof(UINT16);
1983                             break;
1984                         case 0x6:
1985                             p16 += sizeof(UINT);
1986                             p32 += sizeof(UINT);
1987                             size16 -= sizeof(UINT);
1988                             break;
1989                         case 0x7:
1990                             HeapFree(GetProcessHeap(), 0, MapSL(*(SEGPTR *)p16));
1991                             UnMapLS( *(SEGPTR *)p16 );
1992                             p16 += sizeof(SEGPTR);
1993                             p32 += sizeof(char*);
1994                             size16 -= sizeof(SEGPTR);
1995                             break;
1996                         default:
1997                             FIXME("Unknown nibble for mapping (%x)\n", nibble);
1998                         }
1999                     }
2000                     map >>= 4;
2001                 }
2002                 if (size16 != 0) /* DEBUG only */
2003                     FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2004             }
2005         } else {
2006             alloc = msg16;
2007         }
2008
2009         HeapFree( GetProcessHeap(), 0, alloc );
2010     }
2011     return WINMM_MAP_OK;
2012 }
2013
2014 /**************************************************************************
2015  *                      MCI_MapMsg32WTo16                       [internal]
2016  *
2017  * Map a 32W bit MCI message to a 16 bit MCI message.
2018  */
2019 static  WINMM_MapType   MCI_MapMsg32WTo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR* lParam)
2020 {
2021     int         size;
2022     BOOLEAN     keep = FALSE;
2023     DWORD       map = 0;
2024
2025     if (*lParam == 0)
2026         return WINMM_MAP_OK;
2027
2028     /* FIXME: to add also (with seg/linear modifications to do):
2029      * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
2030      * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
2031      */
2032     switch (wMsg) {
2033     case MCI_BREAK:
2034         size = sizeof(MCI_BREAK_PARMS);
2035         break;
2036         /* case MCI_CAPTURE */
2037     case MCI_CLOSE:
2038     case MCI_CLOSE_DRIVER:
2039     case MCI_CONFIGURE:
2040         size = sizeof(MCI_GENERIC_PARMS);
2041         break;
2042         /* case MCI_COPY: */
2043     case MCI_CUE:
2044         switch (uDevType) {
2045         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_CUE_PARMS);       break;
2046         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_CUE_PARMS);     break;*/        FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2047         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2048         }
2049         break;
2050         /* case MCI_CUT:*/
2051     case MCI_DELETE:
2052         switch (uDevType) {
2053         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_DELETE_PARMS16);  map = 0x0F1111FB;       break;
2054         case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_DELETE_PARMS);   break;
2055         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2056         }
2057         break;
2058         /* case MCI_ESCAPE: */
2059     case MCI_FREEZE:
2060         switch (uDevType) {
2061         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_FREEZE_PARMS);    map = 0x0001111B;       break;
2062         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS);     map = 0x0001111B;       break;
2063         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2064         }
2065         break;
2066     case MCI_GETDEVCAPS:
2067         keep = TRUE;
2068         size = sizeof(MCI_GETDEVCAPS_PARMS);
2069         break;
2070         /* case MCI_INDEX: */
2071     case MCI_INFO:
2072         {
2073             LPMCI_INFO_PARMSW   mip32w = (LPMCI_INFO_PARMSW)(*lParam);
2074             char*               ptr;
2075             LPMCI_INFO_PARMS16  mip16;
2076
2077             switch (uDevType) {
2078             case MCI_DEVTYPE_DIGITAL_VIDEO:     size = sizeof(MCI_DGV_INFO_PARMS16);    break;
2079             default:                            size = sizeof(MCI_INFO_PARMS16);        break;
2080             }
2081             ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMCI_INFO_PARMSW) + size);
2082             if (ptr)
2083             {
2084                 *(LPMCI_INFO_PARMSW*)ptr = mip32w;
2085                 mip16 = (LPMCI_INFO_PARMS16)(ptr + sizeof(LPMCI_INFO_PARMSW));
2086                 mip16->dwCallback  = mip32w->dwCallback;
2087                 mip16->lpstrReturn = MapLS( HeapAlloc(GetProcessHeap(), 0, mip32w->dwRetSize / sizeof(WCHAR)) );
2088                 mip16->dwRetSize   = mip32w->dwRetSize / sizeof(WCHAR);
2089                 if (uDevType == MCI_DEVTYPE_DIGITAL_VIDEO) {
2090                     ((LPMCI_DGV_INFO_PARMS16)mip16)->dwItem = ((LPMCI_DGV_INFO_PARMSW)mip32w)->dwItem;
2091                 }
2092             } else {
2093                 return WINMM_MAP_NOMEM;
2094             }
2095             *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_INFO_PARMSW);
2096         }
2097         return WINMM_MAP_OKMEM;
2098         /* case MCI_MARK: */
2099         /* case MCI_MONITOR: */
2100     case MCI_OPEN:
2101     case MCI_OPEN_DRIVER:
2102         {
2103             LPMCI_OPEN_PARMSW   mop32w = (LPMCI_OPEN_PARMSW)(*lParam);
2104             char* ptr = HeapAlloc( GetProcessHeap(), 0,
2105                                    sizeof(LPMCI_OPEN_PARMSW) + sizeof(MCI_OPEN_PARMS16) + 2 * sizeof(DWORD));
2106             LPMCI_OPEN_PARMS16  mop16;
2107
2108
2109             if (ptr) {
2110                 *(LPMCI_OPEN_PARMSW*)(ptr) = mop32w;
2111                 mop16 = (LPMCI_OPEN_PARMS16)(ptr + sizeof(LPMCI_OPEN_PARMSW));
2112                 mop16->dwCallback       = mop32w->dwCallback;
2113                 mop16->wDeviceID        = mop32w->wDeviceID;
2114                 if (dwFlags & MCI_OPEN_TYPE) {
2115                     if (dwFlags & MCI_OPEN_TYPE_ID) {
2116                         /* dword "transparent" value */
2117                         mop16->lpstrDeviceType = (SEGPTR)mop32w->lpstrDeviceType;
2118                     } else {
2119                         /* string */
2120                         mop16->lpstrDeviceType = MapLS( MCI_strdupWtoA(mop32w->lpstrDeviceType) );
2121                     }
2122                 } else {
2123                     /* nuthin' */
2124                     mop16->lpstrDeviceType = 0;
2125                 }
2126                 if (dwFlags & MCI_OPEN_ELEMENT) {
2127                     if (dwFlags & MCI_OPEN_ELEMENT_ID) {
2128                         mop16->lpstrElementName = (SEGPTR)mop32w->lpstrElementName;
2129                     } else {
2130                         mop16->lpstrElementName = MapLS( MCI_strdupWtoA(mop32w->lpstrElementName) );
2131                     }
2132                 } else {
2133                     mop16->lpstrElementName = 0;
2134                 }
2135                 if (dwFlags & MCI_OPEN_ALIAS) {
2136                     mop16->lpstrAlias = MapLS( MCI_strdupWtoA(mop32w->lpstrAlias) );
2137                 } else {
2138                     mop16->lpstrAlias = 0;
2139                 }
2140                 /* copy extended information if any...
2141                  * FIXME: this may seg fault if initial structure does not contain them and
2142                  * the reads after msip16 fail under LDT limits...
2143                  * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
2144                  * should not take care of extended parameters, and should be used by MCI_Open
2145                  * to fetch uDevType. When, this is known, the mapping for sending the
2146                  * MCI_OPEN_DRIVER shall be done depending on uDevType.
2147                  */
2148                 memcpy(mop16 + 1, mop32w + 1, 2 * sizeof(DWORD));
2149             } else {
2150                 return WINMM_MAP_NOMEM;
2151             }
2152             *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_PARMSW);
2153         }
2154         return WINMM_MAP_OKMEM;
2155         /* case MCI_PASTE:*/
2156     case MCI_PAUSE:
2157         size = sizeof(MCI_GENERIC_PARMS);
2158         break;
2159     case MCI_PLAY:
2160         size = sizeof(MCI_PLAY_PARMS);
2161         break;
2162     case MCI_PUT:
2163         switch (uDevType) {
2164         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16);    map = 0x0001111B;       break;
2165         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS);     map = 0x0001111B;       break;
2166         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2167         }
2168         break;
2169     case MCI_REALIZE:
2170         size = sizeof(MCI_GENERIC_PARMS);
2171         break;
2172     case MCI_RECORD:
2173         switch (uDevType) {
2174         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECORD_PARMS16);  map = 0x0F1111FB;       break;
2175         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_RECORD_PARMS);  break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2176         default:                        size = sizeof(MCI_RECORD_PARMS);        break;
2177         }
2178         break;
2179     case MCI_RESUME:
2180         size = sizeof(MCI_GENERIC_PARMS);
2181         break;
2182     case MCI_SEEK:
2183         switch (uDevType) {
2184         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_SEEK_PARMS);    break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2185         default:                        size = sizeof(MCI_SEEK_PARMS);          break;
2186         }
2187         break;
2188     case MCI_SET:
2189         switch (uDevType) {
2190         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SET_PARMS);       break;
2191         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_SET_PARMS);     break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2192         case MCI_DEVTYPE_SEQUENCER:     size = sizeof(MCI_SEQ_SET_PARMS);       break;
2193         /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned,
2194          * so not doing anything should work...
2195          */
2196         case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_SET_PARMS);      break;
2197         default:                        size = sizeof(MCI_SET_PARMS);           break;
2198         }
2199         break;
2200     case MCI_SETAUDIO:
2201         switch (uDevType) {
2202         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SETAUDIO_PARMS16);map = 0x0000077FF;      break;
2203         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_SETAUDIO_PARMS);        break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2204         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2205         }
2206         break;
2207         /* case MCI_SETTIMECODE:*/
2208         /* case MCI_SIGNAL:*/
2209         /* case MCI_SOUND:*/
2210     case MCI_SPIN:
2211         size = sizeof(MCI_SET_PARMS);
2212         break;
2213     case MCI_STATUS:
2214         keep = TRUE;
2215         switch (uDevType) {
2216         /* FIXME:
2217          * don't know if buffer for value is the one passed through lpstrDevice
2218          * or is provided by MCI driver.
2219          * Assuming solution 2: provided by MCI driver, so zeroing on entry
2220          */
2221         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16);  map = 0x0B6FF;          break;
2222         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_STATUS_PARMS);  break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2223         default:                        size = sizeof(MCI_STATUS_PARMS);        break;
2224         }
2225         break;
2226     case MCI_STEP:
2227         switch (uDevType) {
2228         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STEP_PARMS);      break;
2229         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_STEP_PARMS);    break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2230         case MCI_DEVTYPE_VIDEODISC:     size = sizeof(MCI_VD_STEP_PARMS);       break;
2231         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2232         }
2233         break;
2234     case MCI_STOP:
2235         size = sizeof(MCI_SET_PARMS);
2236         break;
2237     case MCI_SYSINFO:
2238         {
2239             LPMCI_SYSINFO_PARMSW  msip32w = (LPMCI_SYSINFO_PARMSW)(*lParam);
2240             LPMCI_SYSINFO_PARMS16 msip16;
2241             char* ptr = HeapAlloc( GetProcessHeap(), 0,
2242                                    sizeof(LPMCI_SYSINFO_PARMSW) + sizeof(MCI_SYSINFO_PARMS16) );
2243
2244             if (ptr) {
2245                 *(LPMCI_SYSINFO_PARMSW*)(ptr) = msip32w;
2246                 msip16 = (LPMCI_SYSINFO_PARMS16)(ptr + sizeof(LPMCI_SYSINFO_PARMSW));
2247
2248                 msip16->dwCallback       = msip32w->dwCallback;
2249                 msip16->lpstrReturn      = MapLS( HeapAlloc(GetProcessHeap(), 0, msip32w->dwRetSize) );
2250                 msip16->dwRetSize        = msip32w->dwRetSize;
2251                 msip16->dwNumber         = msip32w->dwNumber;
2252                 msip16->wDeviceType      = msip32w->wDeviceType;
2253             } else {
2254                 return WINMM_MAP_NOMEM;
2255             }
2256             *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_SYSINFO_PARMSW);
2257         }
2258         return WINMM_MAP_OKMEM;
2259         /* case MCI_UNDO: */
2260     case MCI_UNFREEZE:
2261         switch (uDevType) {
2262         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16);    map = 0x0001111B;       break;
2263         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS16);   map = 0x0001111B;       break;
2264         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2265         }
2266         break;
2267     case MCI_UPDATE:
2268         switch (uDevType) {
2269         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_UPDATE_PARMS16);  map = 0x000B1111B;      break;
2270         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2271         }
2272         break;
2273     case MCI_WHERE:
2274         switch (uDevType) {
2275         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16);    map = 0x0001111B;       keep = TRUE;    break;
2276         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS16);   map = 0x0001111B;       keep = TRUE;    break;
2277         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2278         }
2279         break;
2280     case MCI_WINDOW:
2281         switch (uDevType) {
2282         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16);  if (dwFlags & MCI_DGV_WINDOW_TEXT)  map = 0x7FB;        break;
2283         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7FB;        break;
2284         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2285         }
2286         break;
2287     case DRV_OPEN:
2288         {
2289             LPMCI_OPEN_DRIVER_PARMSW  modp32w = (LPMCI_OPEN_DRIVER_PARMSW)(*lParam);
2290             LPMCI_OPEN_DRIVER_PARMS16 modp16;
2291             char *ptr = HeapAlloc( GetProcessHeap(), 0,
2292                                    sizeof(LPMCI_OPEN_DRIVER_PARMSW) + sizeof(MCI_OPEN_DRIVER_PARMS16));
2293
2294             if (ptr) {
2295                 *(LPMCI_OPEN_DRIVER_PARMSW*)(ptr) = modp32w;
2296                 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSW));
2297                 modp16->wDeviceID = modp32w->wDeviceID;
2298                 modp16->lpstrParams = MapLS( MCI_strdupWtoA(modp32w->lpstrParams) );
2299                 /* other fields are gonna be filled by the driver, don't copy them */
2300             } else {
2301                 return WINMM_MAP_NOMEM;
2302             }
2303             *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_DRIVER_PARMSW);
2304         }
2305         return WINMM_MAP_OKMEM;
2306     case DRV_LOAD:
2307     case DRV_ENABLE:
2308     case DRV_CLOSE:
2309     case DRV_DISABLE:
2310     case DRV_FREE:
2311     case DRV_CONFIGURE:
2312     case DRV_QUERYCONFIGURE:
2313     case DRV_INSTALL:
2314     case DRV_REMOVE:
2315     case DRV_EXITSESSION:
2316     case DRV_EXITAPPLICATION:
2317     case DRV_POWER:
2318         return WINMM_MAP_OK;
2319
2320     default:
2321         FIXME("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2322         return WINMM_MAP_MSGERROR;
2323     }
2324     return MCI_MsgMapper32WTo16_Create((void**)lParam, size, map, keep);
2325 }
2326
2327 /**************************************************************************
2328  *                      MCI_UnMapMsg32WTo16                     [internal]
2329  */
2330 static  WINMM_MapType   MCI_UnMapMsg32WTo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR lParam)
2331 {
2332     int         size = 0;
2333     BOOLEAN     kept = FALSE;   /* there is no need to compute size when kept is FALSE */
2334     DWORD       map = 0;
2335
2336     switch (wMsg) {
2337     case MCI_BREAK:
2338         break;
2339         /* case MCI_CAPTURE */
2340     case MCI_CLOSE:
2341     case MCI_CLOSE_DRIVER:
2342     case MCI_CONFIGURE:
2343         break;
2344         /* case MCI_COPY: */
2345     case MCI_CUE:
2346         break;
2347         /* case MCI_CUT: */
2348     case MCI_DELETE:
2349         break;
2350         /* case MCI_ESCAPE: */
2351     case MCI_FREEZE:
2352         break;
2353     case MCI_GETDEVCAPS:
2354         kept = TRUE;
2355         size = sizeof(MCI_GETDEVCAPS_PARMS);
2356         break;
2357         /* case MCI_INDEX: */
2358     case MCI_INFO:
2359         if (lParam) {
2360             LPMCI_INFO_PARMS16  mip16  = (LPMCI_INFO_PARMS16)MapSL(lParam);
2361             LPMCI_INFO_PARMSW   mip32w = *(LPMCI_INFO_PARMSW*)((char*)mip16 - sizeof(LPMCI_INFO_PARMSW));
2362
2363             MultiByteToWideChar(CP_ACP, 0, MapSL(mip16->lpstrReturn), mip16->dwRetSize, 
2364                                 mip32w->lpstrReturn, mip32w->dwRetSize / sizeof(WCHAR));
2365             UnMapLS( lParam );
2366             UnMapLS( mip16->lpstrReturn );
2367             HeapFree( GetProcessHeap(), 0, MapSL(mip16->lpstrReturn) );
2368             HeapFree( GetProcessHeap(), 0, (char*)mip16 - sizeof(LPMCI_OPEN_PARMSW) );
2369         }
2370         return WINMM_MAP_OK;
2371         /* case MCI_MARK: */
2372         /* case MCI_MONITOR: */
2373     case MCI_OPEN:
2374     case MCI_OPEN_DRIVER:
2375         if (lParam) {
2376             LPMCI_OPEN_PARMS16  mop16  = (LPMCI_OPEN_PARMS16)MapSL(lParam);
2377             LPMCI_OPEN_PARMSW   mop32w = *(LPMCI_OPEN_PARMSW*)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSW));
2378             UnMapLS( lParam );
2379             mop32w->wDeviceID = mop16->wDeviceID;
2380             if ((dwFlags & MCI_OPEN_TYPE) && !(dwFlags & MCI_OPEN_TYPE_ID))
2381             {
2382                 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrDeviceType));
2383                 UnMapLS( mop16->lpstrDeviceType );
2384             }
2385             if ((dwFlags & MCI_OPEN_ELEMENT) && !(dwFlags & MCI_OPEN_ELEMENT_ID))
2386             {
2387                 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrElementName));
2388                 UnMapLS( mop16->lpstrElementName );
2389             }
2390             if (dwFlags & MCI_OPEN_ALIAS)
2391             {
2392                 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrAlias));
2393                 UnMapLS( mop16->lpstrAlias );
2394             }
2395             HeapFree( GetProcessHeap(), 0, (char*)mop16 - sizeof(LPMCI_OPEN_PARMSW) );
2396         }
2397         return WINMM_MAP_OK;
2398         /* case MCI_PASTE:*/
2399     case MCI_PAUSE:
2400         break;
2401     case MCI_PLAY:
2402         break;
2403     case MCI_PUT:
2404         break;
2405     case MCI_REALIZE:
2406         break;
2407     case MCI_RECORD:
2408         break;
2409     case MCI_RESUME:
2410         break;
2411     case MCI_SEEK:
2412         break;
2413     case MCI_SET:
2414         break;
2415     case MCI_SETAUDIO:
2416         switch (uDevType) {
2417         case MCI_DEVTYPE_DIGITAL_VIDEO: map = 0x0000077FF;      break;
2418         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_SETAUDIO_PARMS);        break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2419         }
2420         break;
2421         /* case MCI_SETTIMECODE:*/
2422         /* case MCI_SIGNAL:*/
2423         /* case MCI_SOUND:*/
2424     case MCI_SPIN:
2425         break;
2426     case MCI_STATUS:
2427         kept = TRUE;
2428         switch (uDevType) {
2429         case MCI_DEVTYPE_DIGITAL_VIDEO:
2430         if (lParam) {
2431             LPMCI_DGV_STATUS_PARMS16    mdsp16  = (LPMCI_DGV_STATUS_PARMS16)MapSL(lParam);
2432             LPMCI_DGV_STATUS_PARMSA     mdsp32a = *(LPMCI_DGV_STATUS_PARMSA*)((char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA));
2433
2434             UnMapLS( lParam );
2435             if (mdsp16) {
2436                 mdsp32a->dwReturn = mdsp16->dwReturn;
2437                 if (dwFlags & MCI_DGV_STATUS_DISKSPACE) {
2438                     TRACE("MCI_STATUS (DGV) lpstrDrive=%08x\n", mdsp16->lpstrDrive);
2439                     TRACE("MCI_STATUS (DGV) lpstrDrive=%s\n", (LPSTR)MapSL(mdsp16->lpstrDrive));
2440                     UnMapLS( mdsp16->lpstrDrive );
2441                 }
2442                 HeapFree( GetProcessHeap(), 0, (char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA) );
2443             } else {
2444                 return WINMM_MAP_NOMEM;
2445             }
2446         }
2447         return WINMM_MAP_OKMEM;
2448         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_STATUS_PARMS);  break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2449         default:                        size = sizeof(MCI_STATUS_PARMS);        break;
2450         }
2451         break;
2452     case MCI_STEP:
2453         break;
2454     case MCI_STOP:
2455         break;
2456     case MCI_SYSINFO:
2457         if (lParam) {
2458             LPMCI_SYSINFO_PARMS16       msip16  = (LPMCI_SYSINFO_PARMS16)MapSL(lParam);
2459             LPMCI_SYSINFO_PARMSW        msip32w = *(LPMCI_SYSINFO_PARMSW*)((char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSW));
2460
2461             UnMapLS( lParam );
2462             if (msip16) {
2463                 MultiByteToWideChar(CP_ACP, 0, MapSL(msip16->lpstrReturn), msip16->dwRetSize, 
2464                                     msip32w->lpstrReturn, msip32w->dwRetSize/sizeof(WCHAR));
2465                 UnMapLS( msip16->lpstrReturn );
2466                 HeapFree( GetProcessHeap(), 0, MapSL(msip16->lpstrReturn) );
2467                 HeapFree( GetProcessHeap(), 0, (char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSW) );
2468             } else {
2469                 return WINMM_MAP_NOMEM;
2470             }
2471         }
2472         return WINMM_MAP_OKMEM;
2473         /* case MCI_UNDO: */
2474     case MCI_UNFREEZE:
2475         break;
2476     case MCI_UPDATE:
2477         break;
2478     case MCI_WHERE:
2479         switch (uDevType) {
2480         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16);    map = 0x0001111B;       kept = TRUE;    break;
2481         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS16);   map = 0x0001111B;       kept = TRUE;    break;
2482         default:                        break;
2483         }
2484         break;
2485     case MCI_WINDOW:
2486         switch (uDevType) {
2487         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16);  if (dwFlags & MCI_DGV_WINDOW_TEXT)  map = 0x7666;       break;
2488         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7666;       break;
2489         default:                        break;
2490         }
2491         /* FIXME: see map function */
2492         break;
2493     case DRV_OPEN:
2494         if (lParam) {
2495             LPMCI_OPEN_DRIVER_PARMS16   modp16  = (LPMCI_OPEN_DRIVER_PARMS16)MapSL(lParam);
2496             LPMCI_OPEN_DRIVER_PARMSW    modp32w = *(LPMCI_OPEN_DRIVER_PARMSW*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSW));
2497
2498             UnMapLS( lParam );
2499             modp32w->wCustomCommandTable = modp16->wCustomCommandTable;
2500             modp32w->wType = modp16->wType;
2501             HeapFree(GetProcessHeap(), 0, MapSL(modp16->lpstrParams));
2502             UnMapLS( modp16->lpstrParams );
2503             HeapFree( GetProcessHeap(), 0, (char *)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSW) );
2504         }
2505         return WINMM_MAP_OK;
2506     case DRV_LOAD:
2507     case DRV_ENABLE:
2508     case DRV_CLOSE:
2509     case DRV_DISABLE:
2510     case DRV_FREE:
2511     case DRV_CONFIGURE:
2512     case DRV_QUERYCONFIGURE:
2513     case DRV_INSTALL:
2514     case DRV_REMOVE:
2515     case DRV_EXITSESSION:
2516     case DRV_EXITAPPLICATION:
2517     case DRV_POWER:
2518         FIXME("This is a hack\n");
2519         return WINMM_MAP_OK;
2520
2521     default:
2522         FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2523         return WINMM_MAP_MSGERROR;
2524     }
2525     return MCI_MsgMapper32WTo16_Destroy((void*)lParam, size, map, kept);
2526 }
2527
2528 void    MMDRV_Init16(void)
2529 {
2530 #define A(_x,_y) MMDRV_InstallMap(_x, \
2531 MMDRV_##_y##_Map16To32W, MMDRV_##_y##_UnMap16To32W, \
2532 MMDRV_##_y##_Map32WTo16, MMDRV_##_y##_UnMap32WTo16, \
2533 MMDRV_##_y##_Callback)
2534     A(MMDRV_AUX,        Aux);
2535     A(MMDRV_MIXER,      Mixer);
2536     A(MMDRV_MIDIIN,     MidiIn);
2537     A(MMDRV_MIDIOUT,    MidiOut);
2538     A(MMDRV_WAVEIN,     WaveIn);
2539     A(MMDRV_WAVEOUT,    WaveOut);
2540 #undef A
2541
2542     pFnCallMMDrvFunc16 = MMDRV_CallMMDrvFunc16;
2543     pFnLoadMMDrvFunc16 = MMDRV_LoadMMDrvFunc16;
2544
2545     pFnMciMapMsg32WTo16   = MCI_MapMsg32WTo16;
2546     pFnMciUnMapMsg32WTo16 = MCI_UnMapMsg32WTo16;
2547 }