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