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