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