Replaced most uses of the auto-generated glue code by explicit calls
[wine] / dlls / winmm / message16.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  * MMSYTEM MCI and low level mapping functions
5  *
6  * Copyright 1999 Eric Pouech
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <string.h>
24 #include <stdio.h>
25 #include <assert.h>
26 #include "wine/winbase16.h"
27 #include "winreg.h"
28 #include "winver.h"
29 #include "wownt32.h"
30 #include "winemm.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 dwParam1, DWORD 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_Map16To32A            [internal]
71  */
72 static  WINMM_MapType   MMDRV_Aux_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
73 {
74     return WINMM_MAP_MSGERROR;
75 }
76
77 /**************************************************************************
78  *                              MMDRV_Aux_UnMap16To32A          [internal]
79  */
80 static  WINMM_MapType   MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
81 {
82     return WINMM_MAP_MSGERROR;
83 }
84
85 /**************************************************************************
86  *                              MMDRV_Aux_Map32ATo16            [internal]
87  */
88 static  WINMM_MapType   MMDRV_Aux_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
89 {
90     return WINMM_MAP_MSGERROR;
91 }
92
93 /**************************************************************************
94  *                              MMDRV_Aux_UnMap32ATo16          [internal]
95  */
96 static  WINMM_MapType   MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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 dwInstance, DWORD dwParam1, DWORD 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_Map16To32A         [internal]
127  */
128 static  WINMM_MapType   MMDRV_Mixer_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
129 {
130     return WINMM_MAP_MSGERROR;
131 }
132
133 /**************************************************************************
134  *                              MMDRV_Mixer_UnMap16To32A        [internal]
135  */
136 static  WINMM_MapType   MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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_Map32ATo16          [internal]
157  */
158 static  WINMM_MapType   MMDRV_Mixer_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
159 {
160     return WINMM_MAP_MSGERROR;
161 }
162
163 /**************************************************************************
164  *                              MMDRV_Mixer_UnMap32ATo16        [internal]
165  */
166 static  WINMM_MapType   MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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 dwInstance, DWORD dwParam1, DWORD 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_Map16To32A         [internal]
188  */
189 static  WINMM_MapType   MMDRV_MidiIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
190 {
191     return WINMM_MAP_MSGERROR;
192 }
193
194 /**************************************************************************
195  *                              MMDRV_MidiIn_UnMap16To32A       [internal]
196  */
197 static  WINMM_MapType   MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
198 {
199     return WINMM_MAP_MSGERROR;
200 }
201
202 /**************************************************************************
203  *                              MMDRV_MidiIn_Map32ATo16         [internal]
204  */
205 static  WINMM_MapType   MMDRV_MidiIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
206 {
207     return WINMM_MAP_MSGERROR;
208 }
209
210 /**************************************************************************
211  *                              MMDRV_MidiIn_UnMap32ATo16       [internal]
212  */
213 static  WINMM_MapType   MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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 dwInstance, DWORD dwParam1, DWORD 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 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_Map16To32A        [internal]
276  */
277 static  WINMM_MapType   MMDRV_MidiOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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             LPMIDIOUTCAPSA      moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
298             LPMIDIOUTCAPS16     moc16 = MapSL(*lpParam1);
299
300             if (moc32) {
301                 *(LPMIDIOUTCAPS16*)moc32 = moc16;
302                 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
303                 *lpParam1 = (DWORD)moc32;
304                 *lpParam2 = sizeof(MIDIOUTCAPSA);
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)) ? ((LPMIDIHDR)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 = (LPMIDIHDR)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 %ld to %ld, 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_UnMap16To32A      [internal]
369  */
370 static  WINMM_MapType   MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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             LPMIDIOUTCAPSA              moc32 = (LPMIDIOUTCAPSA)(*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             strcpy(moc16->szPname, moc32->szPname);
397             moc16->wTechnology          = moc32->wTechnology;
398             moc16->wVoices              = moc32->wVoices;
399             moc16->wNotes               = moc32->wNotes;
400             moc16->wChannelMask         = moc32->wChannelMask;
401             moc16->dwSupport            = moc32->dwSupport;
402             HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
403             ret = WINMM_MAP_OK;
404         }
405         break;
406     case MODM_PREPARE:
407     case MODM_UNPREPARE:
408     case MODM_LONGDATA:
409         {
410             LPMIDIHDR           mh32 = (LPMIDIHDR)(*lpParam1);
411             LPMIDIHDR           mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
412
413             assert(mh16->lpNext == mh32);
414             mh16->dwBufferLength = mh32->dwBufferLength;
415             mh16->dwBytesRecorded = mh32->dwBytesRecorded;
416             mh16->dwUser = mh32->dwUser;
417             mh16->dwFlags = mh32->dwFlags;
418             if (mh16->reserved >= sizeof(MIDIHDR))
419                 mh16->dwOffset = mh32->dwOffset;
420
421             if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
422                 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
423                 mh16->lpNext = 0;
424             }
425             ret = WINMM_MAP_OK;
426         }
427         break;
428
429     case MODM_CACHEPATCHES:
430     case MODM_CACHEDRUMPATCHES:
431     default:
432         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
433         break;
434     }
435     return ret;
436 }
437
438 /**************************************************************************
439  *                              MMDRV_MidiOut_Map32ATo16        [internal]
440  */
441 static  WINMM_MapType   MMDRV_MidiOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
442 {
443     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
444
445     switch (wMsg) {
446     case MODM_CLOSE:
447     case MODM_GETNUMDEVS:
448     case MODM_DATA:
449     case MODM_RESET:
450     case MODM_SETVOLUME:
451         ret = WINMM_MAP_OK;
452         break;
453     case MODM_GETDEVCAPS:
454         {
455             LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
456             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA)+sizeof(MIDIOUTCAPS16));
457
458             if (ptr) {
459                 *(LPMIDIOUTCAPSA*)ptr = moc32;
460                 ret = WINMM_MAP_OKMEM;
461             } else {
462                 ret = WINMM_MAP_NOMEM;
463             }
464             *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSA);
465             *lpParam2 = sizeof(MIDIOUTCAPS16);
466         }
467         break;
468     case MODM_PREPARE:
469         {
470             LPMIDIHDR           mh32 = (LPMIDIHDR)*lpParam1;
471             LPMIDIHDR           mh16;
472             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
473                                     sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
474
475             if (ptr) {
476                 *(LPMIDIHDR*)ptr = mh32;
477                 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
478                 *lpParam1 = MapLS(mh16);
479                 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
480                 /* data will be copied on WODM_WRITE */
481                 mh16->dwBufferLength = mh32->dwBufferLength;
482                 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
483                 mh16->dwUser = mh32->dwUser;
484                 mh16->dwFlags = mh32->dwFlags;
485                 /* FIXME: nothing on mh32->lpNext */
486                 /* could link the mh32->lpNext at this level for memory house keeping */
487                 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
488
489                 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
490                 mh32->reserved = *lpParam2;
491
492                 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
493                       *lpParam1, (DWORD)mh16->lpData,
494                       mh32->dwBufferLength, (DWORD)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 = (LPMIDIHDR)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=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
518                   *lpParam1, (DWORD)mh16->lpData, mh32->dwBufferLength, (DWORD)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 %ld to %ld, 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_UnMap32ATo16      [internal]
580  */
581 static  WINMM_MapType   MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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(LPMIDIOUTCAPSA);
597             LPMIDIOUTCAPSA              moc32 = *(LPMIDIOUTCAPSA*)ptr;
598
599             moc32->wMid                 = moc16->wMid;
600             moc32->wPid                 = moc16->wPid;
601             moc32->vDriverVersion       = moc16->vDriverVersion;
602             strcpy(moc32->szPname, moc16->szPname);
603             moc32->wTechnology          = moc16->wTechnology;
604             moc32->wVoices              = moc16->wVoices;
605             moc32->wNotes               = moc16->wNotes;
606             moc32->wChannelMask         = moc16->wChannelMask;
607             moc32->dwSupport            = moc16->dwSupport;
608             UnMapLS( *lpParam1 );
609             HeapFree( GetProcessHeap(), 0, ptr );
610             ret = WINMM_MAP_OK;
611         }
612         break;
613     case MODM_PREPARE:
614     case MODM_UNPREPARE:
615     case MODM_LONGDATA:
616         {
617             LPMIDIHDR           mh16 = MapSL(*lpParam1);
618             LPSTR               ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
619             LPMIDIHDR           mh32 = *(LPMIDIHDR*)ptr;
620
621             assert(mh32->lpNext == (LPMIDIHDR)mh16);
622             UnMapLS( *lpParam1 );
623             mh32->dwBytesRecorded = mh16->dwBytesRecorded;
624             mh32->dwUser = mh16->dwUser;
625             mh32->dwFlags = mh16->dwFlags;
626
627             if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
628                 HeapFree( GetProcessHeap(), 0, ptr );
629                 mh32->lpNext = 0;
630             }
631             ret = WINMM_MAP_OK;
632         }
633         break;
634     case MODM_OPEN:
635         {
636             LPMIDIOPENDESC16            mod16 = MapSL(*lpParam1);
637             LPSTR                       ptr   = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
638             UnMapLS( *lpParam1 );
639             **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
640
641             HeapFree( GetProcessHeap(), 0, ptr );
642             ret = WINMM_MAP_OK;
643         }
644         break;
645     case MODM_GETVOLUME:
646     case MODM_CACHEPATCHES:
647     case MODM_CACHEDRUMPATCHES:
648     default:
649         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
650         break;
651     }
652     return ret;
653 }
654
655 /**************************************************************************
656  *                              MMDRV_MidiOut_Callback          [internal]
657  */
658 static  void    CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
659 {
660     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
661
662     switch (uMsg) {
663     case MOM_OPEN:
664     case MOM_CLOSE:
665         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
666         break;
667     case MOM_DONE:
668         if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
669             /* initial map is: 32 => 16 */
670             LPMIDIHDR           mh16 = MapSL(dwParam1);
671             LPMIDIHDR           mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
672
673             dwParam1 = (DWORD)mh32;
674             mh32->dwFlags = mh16->dwFlags;
675             mh32->dwOffset = mh16->dwOffset;
676             if (mh32->reserved >= sizeof(MIDIHDR))
677                 mh32->dwOffset = mh16->dwOffset;
678         } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
679             /* initial map is: 16 => 32 */
680             LPMIDIHDR           mh32 = (LPMIDIHDR)(dwParam1);
681             SEGPTR              segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
682             LPMIDIHDR           mh16 = MapSL(segmh16);
683
684             dwParam1 = (DWORD)segmh16;
685             mh16->dwFlags = mh32->dwFlags;
686             if (mh16->reserved >= sizeof(MIDIHDR))
687                 mh16->dwOffset = mh32->dwOffset;
688         }
689         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
690         break;
691     /* case MOM_POSITIONCB: */
692     default:
693         ERR("Unknown msg %u\n", uMsg);
694     }
695
696     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
697 }
698
699 /* =================================
700  *   W A V E  I N    M A P P E R S
701  * ================================= */
702
703 /**************************************************************************
704  *                              MMDRV_WaveIn_Map16To32A         [internal]
705  */
706 static  WINMM_MapType   MMDRV_WaveIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
707 {
708     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
709
710     switch (wMsg) {
711     case WIDM_GETNUMDEVS:
712     case WIDM_RESET:
713     case WIDM_START:
714     case WIDM_STOP:
715         ret = WINMM_MAP_OK;
716         break;
717     case WIDM_OPEN:
718     case WIDM_CLOSE:
719         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
720         break;
721     case WIDM_GETDEVCAPS:
722         {
723             LPWAVEINCAPSA       wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
724             LPWAVEINCAPS16      wic16 = MapSL(*lpParam1);
725
726             if (wic32) {
727                 *(LPWAVEINCAPS16*)wic32 = wic16;
728                 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
729                 *lpParam1 = (DWORD)wic32;
730                 *lpParam2 = sizeof(WAVEINCAPSA);
731
732                 ret = WINMM_MAP_OKMEM;
733             } else {
734                 ret = WINMM_MAP_NOMEM;
735             }
736         }
737         break;
738     case WIDM_GETPOS:
739         {
740             LPMMTIME            mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
741             LPMMTIME16          mmt16 = MapSL(*lpParam1);
742
743             if (mmt32) {
744                 *(LPMMTIME16*)mmt32 = mmt16;
745                 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
746
747                 mmt32->wType = mmt16->wType;
748                 *lpParam1 = (DWORD)mmt32;
749                 *lpParam2 = sizeof(MMTIME);
750
751                 ret = WINMM_MAP_OKMEM;
752             } else {
753                 ret = WINMM_MAP_NOMEM;
754             }
755         }
756         break;
757     case WIDM_PREPARE:
758         {
759             LPWAVEHDR           wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
760             LPWAVEHDR           wh16 = MapSL(*lpParam1);
761
762             if (wh32) {
763                 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
764                 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
765                 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
766                 wh32->dwBufferLength = wh16->dwBufferLength;
767                 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
768                 wh32->dwUser = wh16->dwUser;
769                 wh32->dwFlags = wh16->dwFlags;
770                 wh32->dwLoops = wh16->dwLoops;
771                 /* FIXME: nothing on wh32->lpNext */
772                 /* could link the wh32->lpNext at this level for memory house keeping */
773                 wh16->lpNext = wh32; /* for reuse in unprepare and write */
774                 *lpParam1 = (DWORD)wh32;
775                 *lpParam2 = sizeof(WAVEHDR);
776
777                 ret = WINMM_MAP_OKMEM;
778             } else {
779                 ret = WINMM_MAP_NOMEM;
780             }
781         }
782         break;
783     case WIDM_ADDBUFFER:
784     case WIDM_UNPREPARE:
785         {
786             LPWAVEHDR           wh16 = MapSL(*lpParam1);
787             LPWAVEHDR           wh32 = (LPWAVEHDR)wh16->lpNext;
788
789             *lpParam1 = (DWORD)wh32;
790             *lpParam2 = sizeof(WAVEHDR);
791             /* dwBufferLength can be reduced between prepare & write */
792             if (wMsg == WIDM_ADDBUFFER && wh32->dwBufferLength < wh16->dwBufferLength) {
793                 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
794                     wh32->dwBufferLength, wh16->dwBufferLength);
795             } else
796                 wh32->dwBufferLength = wh16->dwBufferLength;
797             ret = WINMM_MAP_OKMEM;
798         }
799         break;
800     case WIDM_MAPPER_STATUS:
801         /* just a single DWORD */
802         *lpParam2 = (DWORD)MapSL(*lpParam2);
803         ret = WINMM_MAP_OK;
804         break;
805     default:
806         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
807         break;
808     }
809     return ret;
810 }
811
812 /**************************************************************************
813  *                              MMDRV_WaveIn_UnMap16To32A       [internal]
814  */
815 static  WINMM_MapType   MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
816 {
817     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
818
819     switch (wMsg) {
820     case WIDM_GETNUMDEVS:
821     case WIDM_RESET:
822     case WIDM_START:
823     case WIDM_STOP:
824     case WIDM_MAPPER_STATUS:
825         ret = WINMM_MAP_OK;
826         break;
827     case WIDM_OPEN:
828     case WIDM_CLOSE:
829         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
830         break;
831     case WIDM_GETDEVCAPS:
832         {
833             LPWAVEINCAPSA               wic32 = (LPWAVEINCAPSA)(*lpParam1);
834             LPWAVEINCAPS16              wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
835
836             wic16->wMid = wic32->wMid;
837             wic16->wPid = wic32->wPid;
838             wic16->vDriverVersion = wic32->vDriverVersion;
839             strcpy(wic16->szPname, wic32->szPname);
840             wic16->dwFormats = wic32->dwFormats;
841             wic16->wChannels = wic32->wChannels;
842             HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
843             ret = WINMM_MAP_OK;
844         }
845         break;
846     case WIDM_GETPOS:
847         {
848             LPMMTIME            mmt32 = (LPMMTIME)(*lpParam1);
849             LPMMTIME16          mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
850
851             MMSYSTEM_MMTIME32to16(mmt16, mmt32);
852             HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
853             ret = WINMM_MAP_OK;
854         }
855         break;
856     case WIDM_ADDBUFFER:
857     case WIDM_PREPARE:
858     case WIDM_UNPREPARE:
859         {
860             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
861             LPWAVEHDR           wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
862
863             assert(wh16->lpNext == wh32);
864             wh16->dwBufferLength = wh32->dwBufferLength;
865             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
866             wh16->dwUser = wh32->dwUser;
867             wh16->dwFlags = wh32->dwFlags;
868             wh16->dwLoops = wh32->dwLoops;
869
870             if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
871                 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
872                 wh16->lpNext = 0;
873             }
874             ret = WINMM_MAP_OK;
875         }
876         break;
877     default:
878         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
879         break;
880     }
881     return ret;
882 }
883
884 /**************************************************************************
885  *                              MMDRV_WaveIn_Map32ATo16         [internal]
886  */
887 static  WINMM_MapType   MMDRV_WaveIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
888 {
889     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
890
891     switch (wMsg) {
892     case WIDM_CLOSE:
893     case WIDM_GETNUMDEVS:
894     case WIDM_RESET:
895     case WIDM_START:
896     case WIDM_STOP:
897         ret = WINMM_MAP_OK;
898         break;
899
900     case WIDM_OPEN:
901         {
902             LPWAVEOPENDESC              wod32 = (LPWAVEOPENDESC)*lpParam1;
903             int                         sz = sizeof(WAVEFORMATEX);
904             LPVOID                      ptr;
905             LPWAVEOPENDESC16            wod16;
906
907             /* allocated data are mapped as follows:
908                LPWAVEOPENDESC   ptr to orig lParam1
909                DWORD            orig dwUser, which is a pointer to DWORD:driver dwInstance
910                DWORD            dwUser passed to driver
911                WAVEOPENDESC16   wod16: openDesc passed to driver
912                WAVEFORMATEX     openDesc->lpFormat passed to driver
913                xxx              extra bytes to WAVEFORMATEX
914             */
915             if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
916                 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
917                 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
918             }
919
920             ptr = HeapAlloc( GetProcessHeap(), 0,
921                              sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
922
923             if (ptr) {
924                 SEGPTR seg_ptr = MapLS( ptr );
925                 *(LPWAVEOPENDESC*)ptr = wod32;
926                 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
927                 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
928
929                 wod16->hWave = HWAVE_16(wod32->hWave);
930                 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
931                 memcpy(wod16 + 1, wod32->lpFormat, sz);
932
933                 wod16->dwCallback = wod32->dwCallback;
934                 wod16->dwInstance = wod32->dwInstance;
935                 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
936                 wod16->dnDevNode = wod32->dnDevNode;
937
938                 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
939                 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
940
941                 ret = WINMM_MAP_OKMEM;
942             } else {
943                 ret = WINMM_MAP_NOMEM;
944             }
945         }
946         break;
947     case WIDM_PREPARE:
948         {
949             LPWAVEHDR           wh32 = (LPWAVEHDR)*lpParam1;
950             LPWAVEHDR           wh16;
951             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
952                                     sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
953
954             if (ptr) {
955                 SEGPTR seg_ptr = MapLS( ptr );
956                 *(LPWAVEHDR*)ptr = wh32;
957                 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
958                 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
959                 /* data will be copied on WODM_WRITE */
960                 wh16->dwBufferLength = wh32->dwBufferLength;
961                 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
962                 wh16->dwUser = wh32->dwUser;
963                 wh16->dwFlags = wh32->dwFlags;
964                 wh16->dwLoops = wh32->dwLoops;
965                 /* FIXME: nothing on wh32->lpNext */
966                 /* could link the wh32->lpNext at this level for memory house keeping */
967                 wh32->lpNext = wh16; /* for reuse in unprepare and write */
968                 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
969                       seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
970                       wh32->dwBufferLength, (DWORD)wh32->lpData);
971                 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
972                 *lpParam2 = sizeof(WAVEHDR);
973
974                 ret = WINMM_MAP_OKMEM;
975             } else {
976                 ret = WINMM_MAP_NOMEM;
977             }
978         }
979         break;
980     case WIDM_ADDBUFFER:
981     case WIDM_UNPREPARE:
982         {
983             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
984             LPWAVEHDR           wh16 = wh32->lpNext;
985             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
986             SEGPTR seg_ptr = MapLS( ptr );
987
988             assert(*(LPWAVEHDR*)ptr == wh32);
989
990             TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
991                   seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
992                   wh32->dwBufferLength, (DWORD)wh32->lpData);
993
994             if (wMsg == WIDM_ADDBUFFER)
995                 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
996
997             *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
998             *lpParam2 = sizeof(WAVEHDR);
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 %ld to %ld, 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             LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
1011             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
1012
1013             if (ptr) {
1014                 *(LPWAVEINCAPSA*)ptr = wic32;
1015                 ret = WINMM_MAP_OKMEM;
1016             } else {
1017                 ret = WINMM_MAP_NOMEM;
1018             }
1019             *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSA);
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_UnMap32ATo16       [internal]
1056  */
1057 static  WINMM_MapType   MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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(LPWAVEINCAPSA);
1110             LPWAVEINCAPSA               wic32 = *(LPWAVEINCAPSA*)ptr;
1111
1112             wic32->wMid = wic16->wMid;
1113             wic32->wPid = wic16->wPid;
1114             wic32->vDriverVersion = wic16->vDriverVersion;
1115             strcpy(wic32->szPname, wic16->szPname);
1116             wic32->dwFormats = wic16->dwFormats;
1117             wic32->wChannels = wic16->wChannels;
1118             UnMapLS( *lpParam1 );
1119             HeapFree( GetProcessHeap(), 0, ptr );
1120             ret = WINMM_MAP_OK;
1121         }
1122         break;
1123     case WIDM_GETPOS:
1124         {
1125             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1126             LPSTR               ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
1127             LPMMTIME            mmt32 = *(LPMMTIME*)ptr;
1128
1129             MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1130             UnMapLS( *lpParam1 );
1131             HeapFree( GetProcessHeap(), 0, ptr );
1132             ret = WINMM_MAP_OK;
1133         }
1134         break;
1135     case DRVM_MAPPER_STATUS:
1136         {
1137             UnMapLS( *lpParam2 );
1138             ret = WINMM_MAP_OK;
1139         }
1140         break;
1141     default:
1142         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1143         break;
1144     }
1145     return ret;
1146 }
1147
1148 /**************************************************************************
1149  *                              MMDRV_WaveIn_Callback           [internal]
1150  */
1151 static  void    CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1152 {
1153     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
1154
1155     switch (uMsg) {
1156     case WIM_OPEN:
1157     case WIM_CLOSE:
1158         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1159         break;
1160     case WIM_DATA:
1161         if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1162             /* initial map is: 32 => 16 */
1163             LPWAVEHDR           wh16 = MapSL(dwParam1);
1164             LPWAVEHDR           wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1165
1166             dwParam1 = (DWORD)wh32;
1167             wh32->dwFlags = wh16->dwFlags;
1168             wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1169         } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1170             /* initial map is: 16 => 32 */
1171             LPWAVEHDR           wh32 = (LPWAVEHDR)(dwParam1);
1172             SEGPTR              segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1173             LPWAVEHDR           wh16 = MapSL(segwh16);
1174
1175             dwParam1 = (DWORD)segwh16;
1176             wh16->dwFlags = wh32->dwFlags;
1177             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1178         }
1179         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1180         break;
1181     default:
1182         ERR("Unknown msg %u\n", uMsg);
1183     }
1184
1185     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1186 }
1187
1188 /* =================================
1189  *   W A V E  O U T  M A P P E R S
1190  * ================================= */
1191
1192 /**************************************************************************
1193  *                              MMDRV_WaveOut_Map16To32A        [internal]
1194  */
1195 static  WINMM_MapType   MMDRV_WaveOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1196 {
1197     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
1198
1199     switch (wMsg) {
1200     /* nothing to do */
1201     case WODM_BREAKLOOP:
1202     case WODM_CLOSE:
1203     case WODM_GETNUMDEVS:
1204     case WODM_PAUSE:
1205     case WODM_RESET:
1206     case WODM_RESTART:
1207     case WODM_SETPITCH:
1208     case WODM_SETPLAYBACKRATE:
1209     case WODM_SETVOLUME:
1210         ret = WINMM_MAP_OK;
1211         break;
1212
1213     case WODM_GETPITCH:
1214     case WODM_GETPLAYBACKRATE:
1215     case WODM_GETVOLUME:
1216     case WODM_OPEN:
1217         FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1218         break;
1219
1220     case WODM_GETDEVCAPS:
1221         {
1222             LPWAVEOUTCAPSA              woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1223             LPWAVEOUTCAPS16             woc16 = MapSL(*lpParam1);
1224
1225             if (woc32) {
1226                 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1227                 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1228                 *lpParam1 = (DWORD)woc32;
1229                 *lpParam2 = sizeof(WAVEOUTCAPSA);
1230
1231                 ret = WINMM_MAP_OKMEM;
1232             } else {
1233                 ret = WINMM_MAP_NOMEM;
1234             }
1235         }
1236         break;
1237     case WODM_GETPOS:
1238         {
1239             LPMMTIME            mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1240             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1241
1242             if (mmt32) {
1243                 *(LPMMTIME16*)mmt32 = mmt16;
1244                 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1245
1246                 mmt32->wType = mmt16->wType;
1247                 *lpParam1 = (DWORD)mmt32;
1248                 *lpParam2 = sizeof(MMTIME);
1249
1250                 ret = WINMM_MAP_OKMEM;
1251             } else {
1252                 ret = WINMM_MAP_NOMEM;
1253             }
1254         }
1255         break;
1256     case WODM_PREPARE:
1257         {
1258             LPWAVEHDR           wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1259             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1260
1261             if (wh32) {
1262                 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1263                 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1264                 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1265                 wh32->dwBufferLength = wh16->dwBufferLength;
1266                 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1267                 wh32->dwUser = wh16->dwUser;
1268                 wh32->dwFlags = wh16->dwFlags;
1269                 wh32->dwLoops = wh16->dwLoops;
1270                 /* FIXME: nothing on wh32->lpNext */
1271                 /* could link the wh32->lpNext at this level for memory house keeping */
1272                 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1273                 *lpParam1 = (DWORD)wh32;
1274                 *lpParam2 = sizeof(WAVEHDR);
1275
1276                 ret = WINMM_MAP_OKMEM;
1277             } else {
1278                 ret = WINMM_MAP_NOMEM;
1279             }
1280         }
1281         break;
1282     case WODM_UNPREPARE:
1283     case WODM_WRITE:
1284         {
1285             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1286             LPWAVEHDR           wh32 = (LPWAVEHDR)wh16->lpNext;
1287
1288             *lpParam1 = (DWORD)wh32;
1289             *lpParam2 = sizeof(WAVEHDR);
1290             /* dwBufferLength can be reduced between prepare & write */
1291             if (wMsg == WODM_WRITE && wh32->dwBufferLength < wh16->dwBufferLength) {
1292                 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1293                     wh32->dwBufferLength, wh16->dwBufferLength);
1294             } else
1295                 wh32->dwBufferLength = wh16->dwBufferLength;
1296             ret = WINMM_MAP_OKMEM;
1297         }
1298         break;
1299     case WODM_MAPPER_STATUS:
1300         *lpParam2 = (DWORD)MapSL(*lpParam2);
1301         ret = WINMM_MAP_OK;
1302         break;
1303     default:
1304         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1305         break;
1306     }
1307     return ret;
1308 }
1309
1310 /**************************************************************************
1311  *                              MMDRV_WaveOut_UnMap16To32A      [internal]
1312  */
1313 static  WINMM_MapType   MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
1314 {
1315     WINMM_MapType       ret = WINMM_MAP_MSGERROR;
1316
1317     switch (wMsg) {
1318     /* nothing to do */
1319     case WODM_BREAKLOOP:
1320     case WODM_CLOSE:
1321     case WODM_GETNUMDEVS:
1322     case WODM_PAUSE:
1323     case WODM_RESET:
1324     case WODM_RESTART:
1325     case WODM_SETPITCH:
1326     case WODM_SETPLAYBACKRATE:
1327     case WODM_SETVOLUME:
1328     case WODM_MAPPER_STATUS:
1329         ret = WINMM_MAP_OK;
1330         break;
1331
1332     case WODM_GETPITCH:
1333     case WODM_GETPLAYBACKRATE:
1334     case WODM_GETVOLUME:
1335     case WODM_OPEN:
1336         FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1337         break;
1338
1339     case WODM_GETDEVCAPS:
1340         {
1341             LPWAVEOUTCAPSA              woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1342             LPWAVEOUTCAPS16             woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1343
1344             woc16->wMid = woc32->wMid;
1345             woc16->wPid = woc32->wPid;
1346             woc16->vDriverVersion = woc32->vDriverVersion;
1347             strcpy(woc16->szPname, woc32->szPname);
1348             woc16->dwFormats = woc32->dwFormats;
1349             woc16->wChannels = woc32->wChannels;
1350             woc16->dwSupport = woc32->dwSupport;
1351             HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1352             ret = WINMM_MAP_OK;
1353         }
1354         break;
1355     case WODM_GETPOS:
1356         {
1357             LPMMTIME            mmt32 = (LPMMTIME)(*lpParam1);
1358             LPMMTIME16          mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1359
1360             MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1361             HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1362             ret = WINMM_MAP_OK;
1363         }
1364         break;
1365     case WODM_PREPARE:
1366     case WODM_UNPREPARE:
1367     case WODM_WRITE:
1368         {
1369             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
1370             LPWAVEHDR           wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1371
1372             assert(wh16->lpNext == wh32);
1373             wh16->dwBufferLength = wh32->dwBufferLength;
1374             wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1375             wh16->dwUser = wh32->dwUser;
1376             wh16->dwFlags = wh32->dwFlags;
1377             wh16->dwLoops = wh32->dwLoops;
1378
1379             if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1380                 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1381                 wh16->lpNext = 0;
1382             }
1383             ret = WINMM_MAP_OK;
1384         }
1385         break;
1386     default:
1387         FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1388         break;
1389     }
1390     return ret;
1391 }
1392
1393 /**************************************************************************
1394  *                              MMDRV_WaveOut_Map32ATo16        [internal]
1395  */
1396 static  WINMM_MapType   MMDRV_WaveOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1397 {
1398     WINMM_MapType       ret;
1399
1400     switch (wMsg) {
1401         /* nothing to do */
1402     case WODM_BREAKLOOP:
1403     case WODM_CLOSE:
1404     case WODM_GETNUMDEVS:
1405     case WODM_PAUSE:
1406     case WODM_RESET:
1407     case WODM_RESTART:
1408     case WODM_SETPITCH:
1409     case WODM_SETPLAYBACKRATE:
1410     case WODM_SETVOLUME:
1411         ret = WINMM_MAP_OK;
1412         break;
1413
1414     case WODM_GETDEVCAPS:
1415         {
1416             LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1417             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1418                                    sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1419
1420             if (ptr) {
1421                 *(LPWAVEOUTCAPSA*)ptr = woc32;
1422                 ret = WINMM_MAP_OKMEM;
1423             } else {
1424                 ret = WINMM_MAP_NOMEM;
1425             }
1426             *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSA);
1427             *lpParam2 = sizeof(WAVEOUTCAPS16);
1428         }
1429         break;
1430     case WODM_GETPITCH:
1431         FIXME("NIY: no conversion yet\n");
1432         ret = WINMM_MAP_MSGERROR;
1433         break;
1434     case WODM_GETPLAYBACKRATE:
1435         FIXME("NIY: no conversion yet\n");
1436         ret = WINMM_MAP_MSGERROR;
1437         break;
1438     case WODM_GETPOS:
1439         {
1440             LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1441             LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1442             LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1443
1444             if (ptr) {
1445                 *(LPMMTIME*)ptr = mmt32;
1446                 mmt16->wType = mmt32->wType;
1447                 ret = WINMM_MAP_OKMEM;
1448             } else {
1449                 ret = WINMM_MAP_NOMEM;
1450             }
1451             *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1452             *lpParam2 = sizeof(MMTIME16);
1453         }
1454         break;
1455     case WODM_GETVOLUME:
1456         FIXME("NIY: no conversion yet\n");
1457         ret = WINMM_MAP_MSGERROR;
1458         break;
1459     case WODM_OPEN:
1460         {
1461             LPWAVEOPENDESC              wod32 = (LPWAVEOPENDESC)*lpParam1;
1462             int                         sz = sizeof(WAVEFORMATEX);
1463             LPVOID                      ptr;
1464             LPWAVEOPENDESC16            wod16;
1465
1466             /* allocated data are mapped as follows:
1467                LPWAVEOPENDESC   ptr to orig lParam1
1468                DWORD            orig dwUser, which is a pointer to DWORD:driver dwInstance
1469                DWORD            dwUser passed to driver
1470                WAVEOPENDESC16   wod16: openDesc passed to driver
1471                WAVEFORMATEX     openDesc->lpFormat passed to driver
1472                xxx              extra bytes to WAVEFORMATEX
1473             */
1474             if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1475                 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1476                 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1477             }
1478
1479             ptr = HeapAlloc( GetProcessHeap(), 0,
1480                              sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1481
1482             if (ptr) {
1483                 SEGPTR seg_ptr = MapLS( ptr );
1484                 *(LPWAVEOPENDESC*)ptr = wod32;
1485                 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1486                 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1487
1488                 wod16->hWave = HWAVE_16(wod32->hWave);
1489                 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1490                 memcpy(wod16 + 1, wod32->lpFormat, sz);
1491
1492                 wod16->dwCallback = wod32->dwCallback;
1493                 wod16->dwInstance = wod32->dwInstance;
1494                 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1495                 wod16->dnDevNode = wod32->dnDevNode;
1496
1497                 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1498                 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1499
1500                 ret = WINMM_MAP_OKMEM;
1501             } else {
1502                 ret = WINMM_MAP_NOMEM;
1503             }
1504         }
1505         break;
1506     case WODM_PREPARE:
1507         {
1508             LPWAVEHDR           wh32 = (LPWAVEHDR)*lpParam1;
1509             LPWAVEHDR           wh16;
1510             LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1511                                     sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1512
1513             if (ptr) {
1514                 SEGPTR seg_ptr = MapLS( ptr );
1515                 *(LPWAVEHDR*)ptr = wh32;
1516                 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1517                 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1518                 /* data will be copied on WODM_WRITE */
1519                 wh16->dwBufferLength = wh32->dwBufferLength;
1520                 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1521                 wh16->dwUser = wh32->dwUser;
1522                 wh16->dwFlags = wh32->dwFlags;
1523                 wh16->dwLoops = wh32->dwLoops;
1524                 /* FIXME: nothing on wh32->lpNext */
1525                 /* could link the wh32->lpNext at this level for memory house keeping */
1526                 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1527                 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1528                       seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1529                       wh32->dwBufferLength, (DWORD)wh32->lpData);
1530                 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1531                 *lpParam2 = sizeof(WAVEHDR);
1532
1533                 ret = WINMM_MAP_OKMEM;
1534             } else {
1535                 ret = WINMM_MAP_NOMEM;
1536             }
1537         }
1538         break;
1539     case WODM_UNPREPARE:
1540     case WODM_WRITE:
1541         {
1542             LPWAVEHDR           wh32 = (LPWAVEHDR)(*lpParam1);
1543             LPWAVEHDR           wh16 = wh32->lpNext;
1544             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1545             SEGPTR seg_ptr = MapLS( ptr );
1546
1547             assert(*(LPWAVEHDR*)ptr == wh32);
1548
1549             TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1550                   seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1551                   wh32->dwBufferLength, (DWORD)wh32->lpData);
1552
1553             if (wMsg == WODM_WRITE)
1554                 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1555
1556             *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1557             *lpParam2 = sizeof(WAVEHDR);
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 %ld to %ld, 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_UnMap32ATo16      [internal]
1584  */
1585 static  WINMM_MapType   MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD 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(LPWAVEOUTCAPSA);
1607             LPWAVEOUTCAPSA              woc32 = *(LPWAVEOUTCAPSA*)ptr;
1608
1609             woc32->wMid = woc16->wMid;
1610             woc32->wPid = woc16->wPid;
1611             woc32->vDriverVersion = woc16->vDriverVersion;
1612             strcpy(woc32->szPname, woc16->szPname);
1613             woc32->dwFormats = woc16->dwFormats;
1614             woc32->wChannels = woc16->wChannels;
1615             woc32->dwSupport = woc16->dwSupport;
1616             UnMapLS( *lpParam1 );
1617             HeapFree( GetProcessHeap(), 0, ptr );
1618             ret = WINMM_MAP_OK;
1619         }
1620         break;
1621     case WODM_GETPITCH:
1622         FIXME("NIY: no conversion yet\n");
1623         ret = WINMM_MAP_MSGERROR;
1624         break;
1625     case WODM_GETPLAYBACKRATE:
1626         FIXME("NIY: no conversion yet\n");
1627         ret = WINMM_MAP_MSGERROR;
1628         break;
1629     case WODM_GETPOS:
1630         {
1631             LPMMTIME16          mmt16 = MapSL(*lpParam1);
1632             LPSTR               ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
1633             LPMMTIME            mmt32 = *(LPMMTIME*)ptr;
1634
1635             MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1636             UnMapLS( *lpParam1 );
1637             HeapFree( GetProcessHeap(), 0, ptr );
1638             ret = WINMM_MAP_OK;
1639         }
1640         break;
1641     case WODM_OPEN:
1642         {
1643             LPWAVEOPENDESC16            wod16 = MapSL(*lpParam1);
1644             LPSTR                       ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1645             LPWAVEOPENDESC              wod32 = *(LPWAVEOPENDESC*)ptr;
1646
1647             wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1648             **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1649             UnMapLS( *lpParam1 );
1650             HeapFree( GetProcessHeap(), 0, ptr );
1651             ret = WINMM_MAP_OK;
1652         }
1653         break;
1654     case WODM_PREPARE:
1655     case WODM_UNPREPARE:
1656     case WODM_WRITE:
1657         {
1658             LPWAVEHDR           wh16 = MapSL(*lpParam1);
1659             LPSTR               ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1660             LPWAVEHDR           wh32 = *(LPWAVEHDR*)ptr;
1661
1662             assert(wh32->lpNext == wh16);
1663             wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1664             wh32->dwUser = wh16->dwUser;
1665             wh32->dwFlags = wh16->dwFlags;
1666             wh32->dwLoops = wh16->dwLoops;
1667
1668             UnMapLS( *lpParam1 );
1669             if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1670                 HeapFree( GetProcessHeap(), 0, ptr );
1671                 wh32->lpNext = 0;
1672             }
1673             ret = WINMM_MAP_OK;
1674         }
1675         break;
1676     case WODM_GETVOLUME:
1677         FIXME("NIY: no conversion yet\n");
1678         ret = WINMM_MAP_MSGERROR;
1679         break;
1680     case DRVM_MAPPER_STATUS:
1681         {
1682             UnMapLS( *lpParam2 );
1683             ret = WINMM_MAP_OK;
1684         }
1685         break;
1686     default:
1687         FIXME("NIY: no conversion yet\n");
1688         ret = WINMM_MAP_MSGERROR;
1689         break;
1690     }
1691     return ret;
1692 }
1693
1694 /**************************************************************************
1695  *                              MMDRV_WaveOut_Callback          [internal]
1696  */
1697 static  void    CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1698 {
1699     LPWINE_MLD  mld = (LPWINE_MLD)dwInstance;
1700
1701     switch (uMsg) {
1702     case WOM_OPEN:
1703     case WOM_CLOSE:
1704         /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1705         break;
1706     case WOM_DONE:
1707         if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1708             /* initial map is: 32 => 16 */
1709             LPWAVEHDR           wh16 = MapSL(dwParam1);
1710             LPWAVEHDR           wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1711
1712             dwParam1 = (DWORD)wh32;
1713             wh32->dwFlags = wh16->dwFlags;
1714         } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1715             /* initial map is: 16 => 32 */
1716             LPWAVEHDR           wh32 = (LPWAVEHDR)(dwParam1);
1717             SEGPTR              segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1718             LPWAVEHDR           wh16 = MapSL(segwh16);
1719
1720             dwParam1 = (DWORD)segwh16;
1721             wh16->dwFlags = wh32->dwFlags;
1722         }
1723         /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1724         break;
1725     default:
1726         ERR("Unknown msg %u\n", uMsg);
1727     }
1728
1729     MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1730 }
1731
1732 /* =================================
1733  *  M A P P E R S   H A N D L I N G
1734  * ================================= */
1735
1736 static  LRESULT    MMDRV_CallMMDrvFunc16(FARPROC16 fp16, WORD dev, WORD msg, LONG instance,
1737                                  LONG lp1, LONG lp2)
1738 {
1739     WORD args[8];
1740     DWORD ret;
1741
1742     args[7] = dev;
1743     args[6] = msg;
1744     args[5] = HIWORD(instance);
1745     args[4] = LOWORD(instance);
1746     args[3] = HIWORD(lp1);
1747     args[2] = LOWORD(lp1);
1748     args[1] = HIWORD(lp2);
1749     args[0] = LOWORD(lp2);
1750     WOWCallback16Ex( (DWORD)fp16, WCB16_PASCAL, sizeof(args), args, &ret );
1751     return LOWORD(ret);
1752 }
1753
1754 /**************************************************************************
1755  *                              MMDRV_GetDescription16          [internal]
1756  */
1757 static  BOOL    MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
1758 {
1759     OFSTRUCT    ofs;
1760     HFILE       hFile;
1761     WORD        w;
1762     DWORD       dw;
1763     BOOL        ret = FALSE;
1764
1765     if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
1766         ERR("Can't open file %s (builtin driver ?)\n", fname);
1767         return FALSE;
1768     }
1769
1770 #define E(_x)   do {TRACE _x;goto theEnd;} while(0)
1771
1772     if (_lread(hFile, &w, 2) != 2)                      E(("Can't read sig\n"));
1773     if (w != ('Z' * 256 + 'M'))                         E(("Bad sig %04x\n", w));
1774     if (_llseek(hFile, 0x3C, SEEK_SET) < 0)             E(("Can't seek to ext header offset\n"));
1775     if (_lread(hFile, &dw, 4) != 4)                     E(("Can't read ext header offset\n"));
1776     if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0)        E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
1777     if (_lread(hFile, &dw, 4) != 4)                     E(("Can't read nr table offset\n"));
1778     if (_llseek(hFile, dw, SEEK_SET) < 0)               E(("Can't seek to nr table %lu\n", dw));
1779     if (_lread(hFile, buf, 1) != 1)                     E(("Can't read descr length\n"));
1780     buflen = min((int)(unsigned)(BYTE)buf[0], buflen - 1);
1781     if (_lread(hFile, buf, buflen) != buflen)           E(("Can't read descr (%d)\n", buflen));
1782     buf[buflen] = '\0';
1783     ret = TRUE;
1784     TRACE("Got '%s' [%d]\n", buf, buflen);
1785 theEnd:
1786     _lclose(hFile);
1787     return ret;
1788 }
1789
1790 /******************************************************************
1791  *              MMDRV_LoadMMDrvFunc16
1792  *
1793  */
1794 unsigned   MMDRV_LoadMMDrvFunc16(LPCSTR drvName, LPWINE_DRIVER d, 
1795                                  LPWINE_MM_DRIVER lpDrv)
1796 {        
1797     WINEMM_msgFunc16    func;
1798     unsigned            count = 0;
1799     char                buffer[128];
1800     /*
1801      * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
1802      * The beginning of the module description indicates the driver supports
1803      * waveform, auxiliary, and mixer devices. Use one of the following
1804      * device-type names, followed by a colon (:) to indicate the type of
1805      * device your driver supports. If the driver supports more than one
1806      * type of device, separate each device-type name with a comma (,).
1807      *
1808      * wave for waveform audio devices
1809      * wavemapper for wave mappers
1810      * midi for MIDI audio devices
1811      * midimapper for midi mappers
1812      * aux for auxiliary audio devices
1813      * mixer for mixer devices
1814      */
1815
1816     if (d->d.d16.hDriver16) {
1817         HMODULE16       hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
1818
1819 #define AA(_h,_w,_x,_y,_z)                                      \
1820     func = (WINEMM_msgFunc##_y) _z ((_h), #_x);                 \
1821     if (func != NULL)                                           \
1822         { lpDrv->parts[_w].u.fnMessage##_y = func; count++;     \
1823           TRACE("Got %d bit func '%s'\n", _y, #_x);         }
1824
1825 #define A(_x,_y)        AA(hMod16,_x,_y,16,GetProcAddress16)
1826         A(MMDRV_AUX,    auxMessage);
1827         A(MMDRV_MIXER,  mxdMessage);
1828         A(MMDRV_MIDIIN, midMessage);
1829         A(MMDRV_MIDIOUT,modMessage);
1830         A(MMDRV_WAVEIN, widMessage);
1831         A(MMDRV_WAVEOUT,wodMessage);
1832 #undef A
1833 #undef AA
1834     }
1835     if (TRACE_ON(winmm)) {
1836         if (MMDRV_GetDescription16(drvName, buffer, sizeof(buffer)))
1837             TRACE("%s => %s\n", drvName, buffer);
1838         else
1839             TRACE("%s => No description\n", drvName);
1840     }
1841
1842     return count;
1843 }
1844
1845 /* =================================
1846  *              M C I
1847  * ================================= */
1848
1849 /**************************************************************************
1850  *                      MCI_MapMsg16To32A                       [internal]
1851  */
1852 static WINMM_MapType    MCI_MapMsg16To32A(WORD uDevType, WORD wMsg, DWORD* lParam)
1853 {
1854     if (*lParam == 0)
1855         return WINMM_MAP_OK;
1856     /* FIXME: to add also (with seg/linear modifications to do):
1857      * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
1858      * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
1859      */
1860     switch (wMsg) {
1861         /* case MCI_CAPTURE */
1862     case MCI_CLOSE:
1863     case MCI_CLOSE_DRIVER:
1864     case MCI_CONFIGURE:
1865     case MCI_COPY:
1866     case MCI_CUE:
1867     case MCI_CUT:
1868     case MCI_DELETE:
1869     case MCI_FREEZE:
1870     case MCI_GETDEVCAPS:
1871         /* case MCI_INDEX: */
1872         /* case MCI_MARK: */
1873         /* case MCI_MONITOR: */
1874     case MCI_PASTE:
1875     case MCI_PAUSE:
1876     case MCI_PLAY:
1877     case MCI_PUT:
1878     case MCI_REALIZE:
1879     case MCI_RECORD:
1880     case MCI_RESUME:
1881     case MCI_SEEK:
1882     case MCI_SET:
1883         /* case MCI_SETTIMECODE:*/
1884         /* case MCI_SIGNAL:*/
1885     case MCI_SPIN:
1886     case MCI_STATUS:            /* FIXME: is wrong for digital video */
1887     case MCI_STEP:
1888     case MCI_STOP:
1889         /* case MCI_UNDO: */
1890     case MCI_UNFREEZE:
1891     case MCI_UPDATE:
1892     case MCI_WHERE:
1893         *lParam = (DWORD)MapSL(*lParam);
1894         return WINMM_MAP_OK;
1895     case MCI_WINDOW:
1896         /* in fact, I would also need the dwFlags... to see
1897          * which members of lParam are effectively used
1898          */
1899         *lParam = (DWORD)MapSL(*lParam);
1900         FIXME("Current mapping may be wrong\n");
1901         break;
1902     case MCI_BREAK:
1903         {
1904             LPMCI_BREAK_PARMS           mbp32 = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_BREAK_PARMS));
1905             LPMCI_BREAK_PARMS16         mbp16 = MapSL(*lParam);
1906
1907             if (mbp32) {
1908                 mbp32->dwCallback = mbp16->dwCallback;
1909                 mbp32->nVirtKey = mbp16->nVirtKey;
1910                 mbp32->hwndBreak = HWND_32(mbp16->hwndBreak);
1911             } else {
1912                 return WINMM_MAP_NOMEM;
1913             }
1914             *lParam = (DWORD)mbp32;
1915         }
1916         return WINMM_MAP_OKMEM;
1917     case MCI_ESCAPE:
1918         {
1919             LPMCI_VD_ESCAPE_PARMSA      mvep32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_VD_ESCAPE_PARMSA));
1920             LPMCI_VD_ESCAPE_PARMS16     mvep16  = MapSL(*lParam);
1921
1922             if (mvep32a) {
1923                 mvep32a->dwCallback       = mvep16->dwCallback;
1924                 mvep32a->lpstrCommand     = MapSL(mvep16->lpstrCommand);
1925             } else {
1926                 return WINMM_MAP_NOMEM;
1927             }
1928             *lParam = (DWORD)mvep32a;
1929         }
1930         return WINMM_MAP_OKMEM;
1931     case MCI_INFO:
1932         {
1933             LPMCI_INFO_PARMSA   mip32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_INFO_PARMSA));
1934             LPMCI_INFO_PARMS16  mip16  = MapSL(*lParam);
1935
1936             /* FIXME this is wrong if device is of type
1937              * MCI_DEVTYPE_DIGITAL_VIDEO, some members are not mapped
1938              */
1939             if (mip32a) {
1940                 mip32a->dwCallback  = mip16->dwCallback;
1941                 mip32a->lpstrReturn = MapSL(mip16->lpstrReturn);
1942                 mip32a->dwRetSize   = mip16->dwRetSize;
1943             } else {
1944                 return WINMM_MAP_NOMEM;
1945             }
1946             *lParam = (DWORD)mip32a;
1947         }
1948         return WINMM_MAP_OKMEM;
1949     case MCI_OPEN:
1950     case MCI_OPEN_DRIVER:
1951         {
1952             LPMCI_OPEN_PARMSA   mop32a = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_OPEN_PARMSA) + 2 * sizeof(DWORD));
1953             LPMCI_OPEN_PARMS16  mop16  = MapSL(*lParam);
1954
1955             if (mop32a) {
1956                 *(LPMCI_OPEN_PARMS16*)(mop32a) = mop16;
1957                 mop32a = (LPMCI_OPEN_PARMSA)((char*)mop32a + sizeof(LPMCI_OPEN_PARMS16));
1958                 mop32a->dwCallback       = mop16->dwCallback;
1959                 mop32a->wDeviceID        = mop16->wDeviceID;
1960                 mop32a->lpstrDeviceType  = MapSL(mop16->lpstrDeviceType);
1961                 mop32a->lpstrElementName = MapSL(mop16->lpstrElementName);
1962                 mop32a->lpstrAlias       = MapSL(mop16->lpstrAlias);
1963                 /* copy extended information if any...
1964                  * FIXME: this may seg fault if initial structure does not contain them and
1965                  * the reads after msip16 fail under LDT limits...
1966                  * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
1967                  * should not take care of extended parameters, and should be used by MCI_Open
1968                  * to fetch uDevType. When, this is known, the mapping for sending the
1969                  * MCI_OPEN_DRIVER shall be done depending on uDevType.
1970                  */
1971                 memcpy(mop32a + 1, mop16 + 1, 2 * sizeof(DWORD));
1972             } else {
1973                 return WINMM_MAP_NOMEM;
1974             }
1975             *lParam = (DWORD)mop32a;
1976         }
1977         return WINMM_MAP_OKMEM;
1978     case MCI_SYSINFO:
1979         {
1980             LPMCI_SYSINFO_PARMSA        msip32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_SYSINFO_PARMSA));
1981             LPMCI_SYSINFO_PARMS16       msip16  = MapSL(*lParam);
1982
1983             if (msip32a) {
1984                 msip32a->dwCallback       = msip16->dwCallback;
1985                 msip32a->lpstrReturn      = MapSL(msip16->lpstrReturn);
1986                 msip32a->dwRetSize        = msip16->dwRetSize;
1987                 msip32a->dwNumber         = msip16->dwNumber;
1988                 msip32a->wDeviceType      = msip16->wDeviceType;
1989             } else {
1990                 return WINMM_MAP_NOMEM;
1991             }
1992             *lParam = (DWORD)msip32a;
1993         }
1994         return WINMM_MAP_OKMEM;
1995     case DRV_LOAD:
1996     case DRV_ENABLE:
1997     case DRV_OPEN:
1998     case DRV_CLOSE:
1999     case DRV_DISABLE:
2000     case DRV_FREE:
2001     case DRV_CONFIGURE:
2002     case DRV_QUERYCONFIGURE:
2003     case DRV_INSTALL:
2004     case DRV_REMOVE:
2005     case DRV_EXITSESSION:
2006     case DRV_EXITAPPLICATION:
2007     case DRV_POWER:
2008         FIXME("This is a hack\n");
2009         return WINMM_MAP_OK;
2010
2011     default:
2012         WARN("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2013     }
2014     return WINMM_MAP_MSGERROR;
2015 }
2016
2017 /**************************************************************************
2018  *                      MCI_UnMapMsg16To32A                     [internal]
2019  */
2020 static  WINMM_MapType   MCI_UnMapMsg16To32A(WORD uDevType, WORD wMsg, DWORD lParam)
2021 {
2022     switch (wMsg) {
2023         /* case MCI_CAPTURE */
2024     case MCI_CLOSE:
2025     case MCI_CLOSE_DRIVER:
2026     case MCI_CONFIGURE:
2027     case MCI_COPY:
2028     case MCI_CUE:
2029     case MCI_CUT:
2030     case MCI_DELETE:
2031     case MCI_FREEZE:
2032     case MCI_GETDEVCAPS:
2033         /* case MCI_INDEX: */
2034         /* case MCI_MARK: */
2035         /* case MCI_MONITOR: */
2036     case MCI_PASTE:
2037     case MCI_PAUSE:
2038     case MCI_PLAY:
2039     case MCI_PUT:
2040     case MCI_REALIZE:
2041     case MCI_RECORD:
2042     case MCI_RESUME:
2043     case MCI_SEEK:
2044     case MCI_SET:
2045         /* case MCI_SETTIMECODE:*/
2046         /* case MCI_SIGNAL:*/
2047     case MCI_SPIN:
2048     case MCI_STATUS:
2049     case MCI_STEP:
2050     case MCI_STOP:
2051         /* case MCI_UNDO: */
2052     case MCI_UNFREEZE:
2053     case MCI_UPDATE:
2054     case MCI_WHERE:
2055         return WINMM_MAP_OK;
2056
2057     case MCI_WINDOW:
2058         /* FIXME ?? see Map function */
2059         return WINMM_MAP_OK;
2060
2061     case MCI_BREAK:
2062     case MCI_ESCAPE:
2063     case MCI_INFO:
2064     case MCI_SYSINFO:
2065         HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2066         return WINMM_MAP_OK;
2067     case MCI_OPEN:
2068     case MCI_OPEN_DRIVER:
2069         if (lParam) {
2070             LPMCI_OPEN_PARMSA   mop32a = (LPMCI_OPEN_PARMSA)lParam;
2071             LPMCI_OPEN_PARMS16  mop16  = *(LPMCI_OPEN_PARMS16*)((char*)mop32a - sizeof(LPMCI_OPEN_PARMS16));
2072
2073             mop16->wDeviceID = mop32a->wDeviceID;
2074             if (!HeapFree(GetProcessHeap(), 0, (LPVOID)(lParam - sizeof(LPMCI_OPEN_PARMS16))))
2075                 FIXME("bad free line=%d\n", __LINE__);
2076         }
2077         return WINMM_MAP_OK;
2078     case DRV_LOAD:
2079     case DRV_ENABLE:
2080     case DRV_OPEN:
2081     case DRV_CLOSE:
2082     case DRV_DISABLE:
2083     case DRV_FREE:
2084     case DRV_CONFIGURE:
2085     case DRV_QUERYCONFIGURE:
2086     case DRV_INSTALL:
2087     case DRV_REMOVE:
2088     case DRV_EXITSESSION:
2089     case DRV_EXITAPPLICATION:
2090     case DRV_POWER:
2091         FIXME("This is a hack\n");
2092         return WINMM_MAP_OK;
2093     default:
2094         FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2095     }
2096     return WINMM_MAP_MSGERROR;
2097 }
2098
2099 /*
2100  * 0000 stop
2101  * 0001 squeeze   signed 4 bytes to 2 bytes     *( LPINT16)D = ( INT16)*( LPINT16)S; D += 2;     S += 4
2102  * 0010 squeeze unsigned 4 bytes to 2 bytes     *(LPUINT16)D = (UINT16)*(LPUINT16)S; D += 2;     S += 4
2103  * 0100
2104  * 0101
2105  * 0110 zero 4 bytes                            *(DWORD)D = 0                        D += 4;     S += 4
2106  * 0111 copy string                             *(LPSTR*)D = seg dup(*(LPSTR*)S)     D += 4;     S += 4
2107  * 1xxx copy xxx + 1 bytes                      memcpy(D, S, xxx + 1);               D += xxx+1; S += xxx+1
2108  */
2109
2110 /**************************************************************************
2111  *                      MCI_MsgMapper32To16_Create              [internal]
2112  *
2113  * Helper for MCI_MapMsg32ATo16.
2114  * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit
2115  * segmented pointer.
2116  * map contains a list of action to be performed for the mapping (see list
2117  * above)
2118  * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area.
2119  */
2120 static  WINMM_MapType   MCI_MsgMapper32To16_Create(void** ptr, int size16, DWORD map, BOOLEAN keep)
2121 {
2122     void*       lp = HeapAlloc( GetProcessHeap(), 0, (keep ? sizeof(void**) : 0) + size16 );
2123     LPBYTE      p16, p32;
2124
2125     if (!lp) {
2126         return WINMM_MAP_NOMEM;
2127     }
2128     p32 = (LPBYTE)(*ptr);
2129     if (keep) {
2130         *(void**)lp = *ptr;
2131         p16 = (LPBYTE)lp + sizeof(void**);
2132         *ptr = (char*)MapLS(lp) + sizeof(void**);
2133     } else {
2134         p16 = lp;
2135         *ptr = (void*)MapLS(lp);
2136     }
2137
2138     if (map == 0) {
2139         memcpy(p16, p32, size16);
2140     } else {
2141         unsigned        nibble;
2142         unsigned        sz;
2143
2144         while (map & 0xF) {
2145             nibble = map & 0xF;
2146             if (nibble & 0x8) {
2147                 sz = (nibble & 7) + 1;
2148                 memcpy(p16, p32, sz);
2149                 p16 += sz;
2150                 p32 += sz;
2151                 size16 -= sz;   /* DEBUG only */
2152             } else {
2153                 switch (nibble) {
2154                 case 0x1:
2155                     *(LPINT16)p16 = *(LPINT)p32;
2156                     p16 += sizeof(INT16);
2157                     p32 += sizeof(INT);
2158                     size16 -= sizeof(INT16);
2159                     break;
2160                 case 0x2:
2161                     *(LPUINT16)p16 = *(LPUINT)p32;
2162                     p16 += sizeof(UINT16);
2163                     p32 += sizeof(UINT);
2164                     size16 -= sizeof(UINT16);
2165                     break;
2166                 case 0x6:
2167                     *(LPDWORD)p16 = 0;
2168                     p16 += sizeof(DWORD);
2169                     p32 += sizeof(DWORD);
2170                     size16 -= sizeof(DWORD);
2171                     break;
2172                 case 0x7:
2173                     *(SEGPTR *)p16 = MapLS( *(LPSTR *)p32 );
2174                     p16 += sizeof(SEGPTR);
2175                     p32 += sizeof(LPSTR);
2176                     size16 -= sizeof(SEGPTR);
2177                     break;
2178                 default:
2179                     FIXME("Unknown nibble for mapping (%x)\n", nibble);
2180                 }
2181             }
2182             map >>= 4;
2183         }
2184         if (size16 != 0) /* DEBUG only */
2185             FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2186     }
2187     return WINMM_MAP_OKMEM;
2188 }
2189
2190 /**************************************************************************
2191  *                      MCI_MsgMapper32To16_Destroy             [internal]
2192  *
2193  * Helper for MCI_UnMapMsg32ATo16.
2194  */
2195 static  WINMM_MapType   MCI_MsgMapper32To16_Destroy(void* ptr, int size16, DWORD map, BOOLEAN kept)
2196 {
2197     if (ptr) {
2198         void*           msg16 = MapSL((SEGPTR)ptr);
2199         void*           alloc;
2200         LPBYTE          p32, p16;
2201         unsigned        nibble;
2202
2203         UnMapLS( (SEGPTR)ptr );
2204         if (kept) {
2205             alloc = (char*)msg16 - sizeof(void**);
2206             p32 = *(void**)alloc;
2207             p16 = msg16;
2208
2209             if (map == 0) {
2210                 memcpy(p32, p16, size16);
2211             } else {
2212                 while (map & 0xF) {
2213                     nibble = map & 0xF;
2214                     if (nibble & 0x8) {
2215                         memcpy(p32, p16, (nibble & 7) + 1);
2216                         p16 += (nibble & 7) + 1;
2217                         p32 += (nibble & 7) + 1;
2218                         size16 -= (nibble & 7) + 1;
2219                     } else {
2220                         switch (nibble) {
2221                         case 0x1:
2222                             *(LPINT)p32 = *(LPINT16)p16;
2223                             p16 += sizeof(INT16);
2224                             p32 += sizeof(INT);
2225                             size16 -= sizeof(INT16);
2226                             break;
2227                         case 0x2:
2228                             *(LPUINT)p32 = *(LPUINT16)p16;
2229                             p16 += sizeof(UINT16);
2230                             p32 += sizeof(UINT);
2231                             size16 -= sizeof(UINT16);
2232                             break;
2233                         case 0x6:
2234                             p16 += sizeof(UINT);
2235                             p32 += sizeof(UINT);
2236                             size16 -= sizeof(UINT);
2237                             break;
2238                         case 0x7:
2239                             UnMapLS( *(SEGPTR *)p16 );
2240                             p16 += sizeof(SEGPTR);
2241                             p32 += sizeof(char*);
2242                             size16 -= sizeof(SEGPTR);
2243                             break;
2244                         default:
2245                             FIXME("Unknown nibble for mapping (%x)\n", nibble);
2246                         }
2247                     }
2248                     map >>= 4;
2249                 }
2250                 if (size16 != 0) /* DEBUG only */
2251                     FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2252             }
2253         } else {
2254             alloc = msg16;
2255         }
2256
2257         HeapFree( GetProcessHeap(), 0, alloc );
2258     }
2259     return WINMM_MAP_OK;
2260 }
2261
2262 /**************************************************************************
2263  *                      MCI_MapMsg32ATo16                       [internal]
2264  *
2265  * Map a 32-A bit MCI message to a 16 bit MCI message.
2266  */
2267 static  WINMM_MapType   MCI_MapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD* lParam)
2268 {
2269     int         size;
2270     BOOLEAN     keep = FALSE;
2271     DWORD       map = 0;
2272
2273     if (*lParam == 0)
2274         return WINMM_MAP_OK;
2275
2276     /* FIXME: to add also (with seg/linear modifications to do):
2277      * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
2278      * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
2279      */
2280     switch (wMsg) {
2281     case MCI_BREAK:
2282         size = sizeof(MCI_BREAK_PARMS);
2283         break;
2284         /* case MCI_CAPTURE */
2285     case MCI_CLOSE:
2286     case MCI_CLOSE_DRIVER:
2287     case MCI_CONFIGURE:
2288         size = sizeof(MCI_GENERIC_PARMS);
2289         break;
2290         /* case MCI_COPY: */
2291     case MCI_CUE:
2292         switch (uDevType) {
2293         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_CUE_PARMS);       break;
2294         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_CUE_PARMS);     break;*/        FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2295         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2296         }
2297         break;
2298         /* case MCI_CUT:*/
2299     case MCI_DELETE:
2300         switch (uDevType) {
2301         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_DELETE_PARMS16);  map = 0x0F1111FB;       break;
2302         case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_DELETE_PARMS);   break;
2303         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2304         }
2305         break;
2306         /* case MCI_ESCAPE: */
2307     case MCI_FREEZE:
2308         switch (uDevType) {
2309         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_FREEZE_PARMS);    map = 0x0001111B;       break;
2310         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS);     map = 0x0001111B;       break;
2311         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2312         }
2313         break;
2314     case MCI_GETDEVCAPS:
2315         keep = TRUE;
2316         size = sizeof(MCI_GETDEVCAPS_PARMS);
2317         break;
2318         /* case MCI_INDEX: */
2319     case MCI_INFO:
2320         {
2321             LPMCI_INFO_PARMSA   mip32a = (LPMCI_INFO_PARMSA)(*lParam);
2322             LPMCI_INFO_PARMS16  mip16;
2323
2324             switch (uDevType) {
2325             case MCI_DEVTYPE_DIGITAL_VIDEO:     size = sizeof(MCI_DGV_INFO_PARMS16);    break;
2326             default:                            size = sizeof(MCI_INFO_PARMS16);        break;
2327             }
2328             mip16 = HeapAlloc( GetProcessHeap(), 0, size);
2329             if (mip16)
2330             {
2331                 mip16->dwCallback  = mip32a->dwCallback;
2332                 mip16->lpstrReturn = MapLS( mip32a->lpstrReturn );
2333                 mip16->dwRetSize   = mip32a->dwRetSize;
2334                 if (uDevType == MCI_DEVTYPE_DIGITAL_VIDEO) {
2335                     ((LPMCI_DGV_INFO_PARMS16)mip16)->dwItem = ((LPMCI_DGV_INFO_PARMSA)mip32a)->dwItem;
2336                 }
2337             } else {
2338                 return WINMM_MAP_NOMEM;
2339             }
2340             *lParam = MapLS(mip16);
2341         }
2342         return WINMM_MAP_OKMEM;
2343         /* case MCI_MARK: */
2344         /* case MCI_MONITOR: */
2345     case MCI_OPEN:
2346     case MCI_OPEN_DRIVER:
2347         {
2348             LPMCI_OPEN_PARMSA   mop32a = (LPMCI_OPEN_PARMSA)(*lParam);
2349             char* ptr = HeapAlloc( GetProcessHeap(), 0,
2350                                    sizeof(LPMCI_OPEN_PARMSA) + sizeof(MCI_OPEN_PARMS16) + 2 * sizeof(DWORD));
2351             LPMCI_OPEN_PARMS16  mop16;
2352
2353
2354             if (ptr) {
2355                 *(LPMCI_OPEN_PARMSA*)(ptr) = mop32a;
2356                 mop16 = (LPMCI_OPEN_PARMS16)(ptr + sizeof(LPMCI_OPEN_PARMSA));
2357                 mop16->dwCallback       = mop32a->dwCallback;
2358                 mop16->wDeviceID        = mop32a->wDeviceID;
2359                 if (dwFlags & MCI_OPEN_TYPE) {
2360                     if (dwFlags & MCI_OPEN_TYPE_ID) {
2361                         /* dword "transparent" value */
2362                         mop16->lpstrDeviceType = (SEGPTR)mop32a->lpstrDeviceType;
2363                     } else {
2364                         /* string */
2365                         mop16->lpstrDeviceType = MapLS( mop32a->lpstrDeviceType );
2366                     }
2367                 } else {
2368                     /* nuthin' */
2369                     mop16->lpstrDeviceType = 0;
2370                 }
2371                 if (dwFlags & MCI_OPEN_ELEMENT) {
2372                     if (dwFlags & MCI_OPEN_ELEMENT_ID) {
2373                         mop16->lpstrElementName = (SEGPTR)mop32a->lpstrElementName;
2374                     } else {
2375                         mop16->lpstrElementName = MapLS( mop32a->lpstrElementName );
2376                     }
2377                 } else {
2378                     mop16->lpstrElementName = 0;
2379                 }
2380                 if (dwFlags & MCI_OPEN_ALIAS) {
2381                     mop16->lpstrAlias = MapLS( mop32a->lpstrAlias );
2382                 } else {
2383                     mop16->lpstrAlias = 0;
2384                 }
2385                 /* copy extended information if any...
2386                  * FIXME: this may seg fault if initial structure does not contain them and
2387                  * the reads after msip16 fail under LDT limits...
2388                  * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
2389                  * should not take care of extended parameters, and should be used by MCI_Open
2390                  * to fetch uDevType. When, this is known, the mapping for sending the
2391                  * MCI_OPEN_DRIVER shall be done depending on uDevType.
2392                  */
2393                 memcpy(mop16 + 1, mop32a + 1, 2 * sizeof(DWORD));
2394             } else {
2395                 return WINMM_MAP_NOMEM;
2396             }
2397             *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_PARMSA);
2398         }
2399         return WINMM_MAP_OKMEM;
2400         /* case MCI_PASTE:*/
2401     case MCI_PAUSE:
2402         size = sizeof(MCI_GENERIC_PARMS);
2403         break;
2404     case MCI_PLAY:
2405         size = sizeof(MCI_PLAY_PARMS);
2406         break;
2407     case MCI_PUT:
2408         switch (uDevType) {
2409         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16);    map = 0x0001111B;       break;
2410         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS);     map = 0x0001111B;       break;
2411         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2412         }
2413         break;
2414     case MCI_REALIZE:
2415         size = sizeof(MCI_GENERIC_PARMS);
2416         break;
2417     case MCI_RECORD:
2418         switch (uDevType) {
2419         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECORD_PARMS16);  map = 0x0F1111FB;       break;
2420         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_RECORD_PARMS);  break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2421         default:                        size = sizeof(MCI_RECORD_PARMS);        break;
2422         }
2423         break;
2424     case MCI_RESUME:
2425         size = sizeof(MCI_GENERIC_PARMS);
2426         break;
2427     case MCI_SEEK:
2428         switch (uDevType) {
2429         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_SEEK_PARMS);    break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2430         default:                        size = sizeof(MCI_SEEK_PARMS);          break;
2431         }
2432         break;
2433     case MCI_SET:
2434         switch (uDevType) {
2435         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SET_PARMS);       break;
2436         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_SET_PARMS);     break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2437         case MCI_DEVTYPE_SEQUENCER:     size = sizeof(MCI_SEQ_SET_PARMS);       break;
2438         /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned,
2439          * so not doing anything should work...
2440          */
2441         case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_SET_PARMS);      break;
2442         default:                        size = sizeof(MCI_SET_PARMS);           break;
2443         }
2444         break;
2445     case MCI_SETAUDIO:
2446         switch (uDevType) {
2447         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SETAUDIO_PARMS16);map = 0x0000077FF;      break;
2448         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_SETAUDIO_PARMS);        break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2449         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2450         }
2451         break;
2452         /* case MCI_SETTIMECODE:*/
2453         /* case MCI_SIGNAL:*/
2454     case MCI_SPIN:
2455         size = sizeof(MCI_SET_PARMS);
2456         break;
2457     case MCI_STATUS:
2458         keep = TRUE;
2459         switch (uDevType) {
2460         /* FIXME:
2461          * don't know if buffer for value is the one passed through lpstrDevice
2462          * or is provided by MCI driver.
2463          * Assuming solution 2: provided by MCI driver, so zeroing on entry
2464          */
2465         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16);  map = 0x0B6FF;          break;
2466         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_STATUS_PARMS);  break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2467         default:                        size = sizeof(MCI_STATUS_PARMS);        break;
2468         }
2469         break;
2470     case MCI_STEP:
2471         switch (uDevType) {
2472         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STEP_PARMS);      break;
2473         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_STEP_PARMS);    break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2474         case MCI_DEVTYPE_VIDEODISC:     size = sizeof(MCI_VD_STEP_PARMS);       break;
2475         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2476         }
2477         break;
2478     case MCI_STOP:
2479         size = sizeof(MCI_SET_PARMS);
2480         break;
2481     case MCI_SYSINFO:
2482         {
2483             LPMCI_SYSINFO_PARMSA  msip32a = (LPMCI_SYSINFO_PARMSA)(*lParam);
2484             LPMCI_SYSINFO_PARMS16 msip16;
2485             char* ptr = HeapAlloc( GetProcessHeap(), 0,
2486                                    sizeof(LPMCI_SYSINFO_PARMSA) + sizeof(MCI_SYSINFO_PARMS16) );
2487
2488             if (ptr) {
2489                 *(LPMCI_SYSINFO_PARMSA*)(ptr) = msip32a;
2490                 msip16 = (LPMCI_SYSINFO_PARMS16)(ptr + sizeof(LPMCI_SYSINFO_PARMSA));
2491
2492                 msip16->dwCallback       = msip32a->dwCallback;
2493                 msip16->lpstrReturn      = MapLS( msip32a->lpstrReturn );
2494                 msip16->dwRetSize        = msip32a->dwRetSize;
2495                 msip16->dwNumber         = msip32a->dwNumber;
2496                 msip16->wDeviceType      = msip32a->wDeviceType;
2497             } else {
2498                 return WINMM_MAP_NOMEM;
2499             }
2500             *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_SYSINFO_PARMSA);
2501         }
2502         return WINMM_MAP_OKMEM;
2503         /* case MCI_UNDO: */
2504     case MCI_UNFREEZE:
2505         switch (uDevType) {
2506         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16);    map = 0x0001111B;       break;
2507         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS16);   map = 0x0001111B;       break;
2508         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2509         }
2510         break;
2511     case MCI_UPDATE:
2512         switch (uDevType) {
2513         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_UPDATE_PARMS16);  map = 0x000B1111B;      break;
2514         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2515         }
2516         break;
2517     case MCI_WHERE:
2518         switch (uDevType) {
2519         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16);    map = 0x0001111B;       keep = TRUE;    break;
2520         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS16);   map = 0x0001111B;       keep = TRUE;    break;
2521         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2522         }
2523         break;
2524     case MCI_WINDOW:
2525         switch (uDevType) {
2526         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16);  if (dwFlags & MCI_DGV_WINDOW_TEXT)  map = 0x7FB;        break;
2527         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7FB;        break;
2528         default:                        size = sizeof(MCI_GENERIC_PARMS);       break;
2529         }
2530         break;
2531     case DRV_OPEN:
2532         {
2533             LPMCI_OPEN_DRIVER_PARMSA  modp32a = (LPMCI_OPEN_DRIVER_PARMSA)(*lParam);
2534             LPMCI_OPEN_DRIVER_PARMS16 modp16;
2535             char *ptr = HeapAlloc( GetProcessHeap(), 0,
2536                                   sizeof(LPMCI_OPEN_DRIVER_PARMSA) + sizeof(MCI_OPEN_DRIVER_PARMS16));
2537
2538             if (ptr) {
2539                 *(LPMCI_OPEN_DRIVER_PARMSA*)(ptr) = modp32a;
2540                 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSA));
2541                 modp16->wDeviceID = modp32a->wDeviceID;
2542                 modp16->lpstrParams = MapLS( modp32a->lpstrParams );
2543                 /* other fields are gonna be filled by the driver, don't copy them */
2544             } else {
2545                 return WINMM_MAP_NOMEM;
2546             }
2547             *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_DRIVER_PARMSA);
2548         }
2549         return WINMM_MAP_OKMEM;
2550     case DRV_LOAD:
2551     case DRV_ENABLE:
2552     case DRV_CLOSE:
2553     case DRV_DISABLE:
2554     case DRV_FREE:
2555     case DRV_CONFIGURE:
2556     case DRV_QUERYCONFIGURE:
2557     case DRV_INSTALL:
2558     case DRV_REMOVE:
2559     case DRV_EXITSESSION:
2560     case DRV_EXITAPPLICATION:
2561     case DRV_POWER:
2562         return WINMM_MAP_OK;
2563
2564     default:
2565         WARN("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2566         return WINMM_MAP_MSGERROR;
2567     }
2568     return MCI_MsgMapper32To16_Create((void**)lParam, size, map, keep);
2569 }
2570
2571 /**************************************************************************
2572  *                      MCI_UnMapMsg32ATo16                     [internal]
2573  */
2574 static  WINMM_MapType   MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD lParam)
2575 {
2576     int         size = 0;
2577     BOOLEAN     kept = FALSE;   /* there is no need to compute size when kept is FALSE */
2578     DWORD       map = 0;
2579
2580     switch (wMsg) {
2581     case MCI_BREAK:
2582         break;
2583         /* case MCI_CAPTURE */
2584     case MCI_CLOSE:
2585     case MCI_CLOSE_DRIVER:
2586     case MCI_CONFIGURE:
2587         break;
2588         /* case MCI_COPY: */
2589     case MCI_CUE:
2590         break;
2591         /* case MCI_CUT: */
2592     case MCI_DELETE:
2593         break;
2594         /* case MCI_ESCAPE: */
2595     case MCI_FREEZE:
2596         break;
2597     case MCI_GETDEVCAPS:
2598         kept = TRUE;
2599         size = sizeof(MCI_GETDEVCAPS_PARMS);
2600         break;
2601         /* case MCI_INDEX: */
2602     case MCI_INFO:
2603         {
2604             LPMCI_INFO_PARMS16 mip16  = (LPMCI_INFO_PARMS16)MapSL(lParam);
2605             UnMapLS( lParam );
2606             UnMapLS( mip16->lpstrReturn );
2607             HeapFree( GetProcessHeap(), 0, mip16 );
2608         }
2609         return WINMM_MAP_OK;
2610         /* case MCI_MARK: */
2611         /* case MCI_MONITOR: */
2612     case MCI_OPEN:
2613     case MCI_OPEN_DRIVER:
2614         if (lParam) {
2615             LPMCI_OPEN_PARMS16  mop16  = (LPMCI_OPEN_PARMS16)MapSL(lParam);
2616             LPMCI_OPEN_PARMSA   mop32a = *(LPMCI_OPEN_PARMSA*)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSA));
2617             UnMapLS( lParam );
2618             mop32a->wDeviceID = mop16->wDeviceID;
2619             if ((dwFlags & MCI_OPEN_TYPE) && !(dwFlags & MCI_OPEN_TYPE_ID))
2620                 UnMapLS( mop16->lpstrDeviceType );
2621             if ((dwFlags & MCI_OPEN_ELEMENT) && !(dwFlags & MCI_OPEN_ELEMENT_ID))
2622                 UnMapLS( mop16->lpstrElementName );
2623             if (dwFlags & MCI_OPEN_ALIAS)
2624                 UnMapLS( mop16->lpstrAlias );
2625             HeapFree( GetProcessHeap(), 0, (char*)mop16 - sizeof(LPMCI_OPEN_PARMSA) );
2626         }
2627         return WINMM_MAP_OK;
2628         /* case MCI_PASTE:*/
2629     case MCI_PAUSE:
2630         break;
2631     case MCI_PLAY:
2632         break;
2633     case MCI_PUT:
2634         break;
2635     case MCI_REALIZE:
2636         break;
2637     case MCI_RECORD:
2638         break;
2639     case MCI_RESUME:
2640         break;
2641     case MCI_SEEK:
2642         break;
2643     case MCI_SET:
2644         break;
2645     case MCI_SETAUDIO:
2646         switch (uDevType) {
2647         case MCI_DEVTYPE_DIGITAL_VIDEO: map = 0x0000077FF;      break;
2648         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_SETAUDIO_PARMS);        break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2649         }
2650         break;
2651         /* case MCI_SETTIMECODE:*/
2652         /* case MCI_SIGNAL:*/
2653     case MCI_SPIN:
2654         break;
2655     case MCI_STATUS:
2656         kept = TRUE;
2657         switch (uDevType) {
2658         case MCI_DEVTYPE_DIGITAL_VIDEO:
2659         if (lParam) {
2660             LPMCI_DGV_STATUS_PARMS16    mdsp16  = (LPMCI_DGV_STATUS_PARMS16)MapSL(lParam);
2661             LPMCI_DGV_STATUS_PARMSA     mdsp32a = *(LPMCI_DGV_STATUS_PARMSA*)((char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA));
2662
2663             UnMapLS( lParam );
2664             if (mdsp16) {
2665                 mdsp32a->dwReturn = mdsp16->dwReturn;
2666                 if (dwFlags & MCI_DGV_STATUS_DISKSPACE) {
2667                     TRACE("MCI_STATUS (DGV) lpstrDrive=%08lx\n", mdsp16->lpstrDrive);
2668                     TRACE("MCI_STATUS (DGV) lpstrDrive=%s\n", (LPSTR)MapSL(mdsp16->lpstrDrive));
2669                     UnMapLS( mdsp16->lpstrDrive );
2670                 }
2671                 HeapFree( GetProcessHeap(), 0, (char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA) );
2672             } else {
2673                 return WINMM_MAP_NOMEM;
2674             }
2675         }
2676         return WINMM_MAP_OKMEM;
2677         case MCI_DEVTYPE_VCR:           /*size = sizeof(MCI_VCR_STATUS_PARMS);  break;*/FIXME("NIY vcr\n");     return WINMM_MAP_NOMEM;
2678         default:                        size = sizeof(MCI_STATUS_PARMS);        break;
2679         }
2680         break;
2681     case MCI_STEP:
2682         break;
2683     case MCI_STOP:
2684         break;
2685     case MCI_SYSINFO:
2686         if (lParam) {
2687             LPMCI_SYSINFO_PARMS16       msip16  = (LPMCI_SYSINFO_PARMS16)MapSL(lParam);
2688             LPMCI_SYSINFO_PARMSA        msip32a = *(LPMCI_SYSINFO_PARMSA*)((char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA));
2689
2690             UnMapLS( lParam );
2691             if (msip16) {
2692                 msip16->dwCallback = msip32a->dwCallback;
2693                 UnMapLS( msip16->lpstrReturn );
2694                 HeapFree( GetProcessHeap(), 0, (char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA) );
2695             } else {
2696                 return WINMM_MAP_NOMEM;
2697             }
2698         }
2699         return WINMM_MAP_OKMEM;
2700         /* case MCI_UNDO: */
2701     case MCI_UNFREEZE:
2702         break;
2703     case MCI_UPDATE:
2704         break;
2705     case MCI_WHERE:
2706         switch (uDevType) {
2707         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16);    map = 0x0001111B;       kept = TRUE;    break;
2708         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_RECT_PARMS16);   map = 0x0001111B;       kept = TRUE;    break;
2709         default:                        break;
2710         }
2711         break;
2712     case MCI_WINDOW:
2713         switch (uDevType) {
2714         case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16);  if (dwFlags & MCI_DGV_WINDOW_TEXT)  map = 0x7666;       break;
2715         case MCI_DEVTYPE_OVERLAY:       size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7666;       break;
2716         default:                        break;
2717         }
2718         /* FIXME: see map function */
2719         break;
2720
2721     case DRV_OPEN:
2722         if (lParam) {
2723             LPMCI_OPEN_DRIVER_PARMS16   modp16  = (LPMCI_OPEN_DRIVER_PARMS16)MapSL(lParam);
2724             LPMCI_OPEN_DRIVER_PARMSA    modp32a = *(LPMCI_OPEN_DRIVER_PARMSA*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA));
2725
2726             UnMapLS( lParam );
2727             modp32a->wCustomCommandTable = modp16->wCustomCommandTable;
2728             modp32a->wType = modp16->wType;
2729             UnMapLS( modp16->lpstrParams );
2730             HeapFree( GetProcessHeap(), 0, (char *)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA) );
2731         }
2732         return WINMM_MAP_OK;
2733     case DRV_LOAD:
2734     case DRV_ENABLE:
2735     case DRV_CLOSE:
2736     case DRV_DISABLE:
2737     case DRV_FREE:
2738     case DRV_CONFIGURE:
2739     case DRV_QUERYCONFIGURE:
2740     case DRV_INSTALL:
2741     case DRV_REMOVE:
2742     case DRV_EXITSESSION:
2743     case DRV_EXITAPPLICATION:
2744     case DRV_POWER:
2745         FIXME("This is a hack\n");
2746         return WINMM_MAP_OK;
2747     default:
2748         FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2749         return WINMM_MAP_MSGERROR;
2750     }
2751     return MCI_MsgMapper32To16_Destroy((void*)lParam, size, map, kept);
2752 }
2753
2754 void    MMDRV_Init16(void)
2755 {
2756 #define A(_x,_y) MMDRV_InstallMap(_x, \
2757 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
2758 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
2759 MMDRV_##_y##_Callback)
2760     A(MMDRV_AUX,        Aux);
2761     A(MMDRV_MIXER,      Mixer);
2762     A(MMDRV_MIDIIN,     MidiIn);
2763     A(MMDRV_MIDIOUT,    MidiOut);
2764     A(MMDRV_WAVEIN,     WaveIn);
2765     A(MMDRV_WAVEOUT,    WaveOut);
2766 #undef A
2767
2768     pFnCallMMDrvFunc16 = MMDRV_CallMMDrvFunc16;
2769     pFnLoadMMDrvFunc16 = MMDRV_LoadMMDrvFunc16;
2770
2771     pFnMciMapMsg16To32A   = MCI_MapMsg16To32A;
2772     pFnMciUnMapMsg16To32A = MCI_UnMapMsg16To32A;
2773     pFnMciMapMsg32ATo16   = MCI_MapMsg32ATo16;
2774     pFnMciUnMapMsg32ATo16 = MCI_UnMapMsg32ATo16;
2775 }