2 * MMSYSTEM MCI and low level mapping functions
4 * Copyright 1999 Eric Pouech
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/winbase16.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(winmm
);
36 /* =================================
38 * ================================= */
40 /* =================================
41 * M I X E R M A P P E R S
42 * ================================= */
44 /**************************************************************************
45 * MMSYSTDRV_Mixer_Map16To32W [internal]
47 static MMSYSTEM_MapType
MMSYSTDRV_Mixer_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
49 return MMSYSTEM_MAP_MSGERROR
;
52 /**************************************************************************
53 * MMSYSTDRV_Mixer_UnMap16To32W [internal]
55 static MMSYSTEM_MapType
MMSYSTDRV_Mixer_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
59 UINT ret
= mixerGetDevCapsA(devid
, &micA
, sizeof(micA
));
61 if (ret
== MMSYSERR_NOERROR
) {
62 mixcaps
->wMid
= micA
.wMid
;
63 mixcaps
->wPid
= micA
.wPid
;
64 mixcaps
->vDriverVersion
= micA
.vDriverVersion
;
65 strcpy(mixcaps
->szPname
, micA
.szPname
);
66 mixcaps
->fdwSupport
= micA
.fdwSupport
;
67 mixcaps
->cDestinations
= micA
.cDestinations
;
71 return MMSYSTEM_MAP_MSGERROR
;
74 /**************************************************************************
75 * MMSYSTDRV_Mixer_MapCB
77 static void MMSYSTDRV_Mixer_MapCB(DWORD uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
82 /* =================================
83 * M I D I I N M A P P E R S
84 * ================================= */
86 /**************************************************************************
87 * MMSYSTDRV_MidiIn_Map16To32W [internal]
89 static MMSYSTEM_MapType
MMSYSTDRV_MidiIn_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
91 return MMSYSTEM_MAP_MSGERROR
;
94 /**************************************************************************
95 * MMSYSTDRV_MidiIn_UnMap16To32W [internal]
97 static MMSYSTEM_MapType
MMSYSTDRV_MidiIn_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
99 return MMSYSTEM_MAP_MSGERROR
;
102 /**************************************************************************
103 * MMSYSTDRV_MidiIn_MapCB [internal]
105 static void MMSYSTDRV_MidiIn_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
110 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
115 /* dwParam1 & dwParam2 are data, nothing to do */
120 LPMIDIHDR mh32
= (LPMIDIHDR
)(*dwParam1
);
121 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
122 LPMIDIHDR16 mh16
= MapSL(segmh16
);
124 *dwParam1
= (DWORD
)segmh16
;
125 mh16
->dwFlags
= mh32
->dwFlags
;
126 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
130 ERR("Unknown msg %u\n", uMsg
);
134 /* =================================
135 * M I D I O U T M A P P E R S
136 * ================================= */
138 /**************************************************************************
139 * MMSYSTDRV_MidiOut_Map16To32W [internal]
141 static MMSYSTEM_MapType
MMSYSTDRV_MidiOut_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
143 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
146 case MODM_GETNUMDEVS
:
150 ret
= MMSYSTEM_MAP_OK
;
156 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
159 case MODM_GETDEVCAPS
:
161 LPMIDIOUTCAPSW moc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16
) + sizeof(MIDIOUTCAPSW
));
162 LPMIDIOUTCAPS16 moc16
= MapSL(*lpParam1
);
165 *(LPMIDIOUTCAPS16
*)moc32
= moc16
;
166 moc32
= (LPMIDIOUTCAPSW
)((LPSTR
)moc32
+ sizeof(LPMIDIOUTCAPS16
));
167 *lpParam1
= (DWORD
)moc32
;
168 *lpParam2
= sizeof(MIDIOUTCAPSW
);
170 ret
= MMSYSTEM_MAP_OKMEM
;
172 ret
= MMSYSTEM_MAP_NOMEM
;
178 LPMIDIHDR mh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
));
179 LPMIDIHDR16 mh16
= MapSL(*lpParam1
);
182 *(LPMIDIHDR
*)mh32
= (LPMIDIHDR
)*lpParam1
;
183 mh32
= (LPMIDIHDR
)((LPSTR
)mh32
+ sizeof(LPMIDIHDR
));
184 mh32
->lpData
= MapSL((SEGPTR
)mh16
->lpData
);
185 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
186 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
187 mh32
->dwUser
= mh16
->dwUser
;
188 mh32
->dwFlags
= mh16
->dwFlags
;
189 mh16
->lpNext
= (MIDIHDR16
*)mh32
; /* for reuse in unprepare and write */
190 *lpParam1
= (DWORD
)mh32
;
191 *lpParam2
= offsetof(MIDIHDR
,dwOffset
); /* old size, without dwOffset */
193 ret
= MMSYSTEM_MAP_OKMEM
;
195 ret
= MMSYSTEM_MAP_NOMEM
;
202 LPMIDIHDR16 mh16
= MapSL(*lpParam1
);
203 LPMIDIHDR mh32
= (MIDIHDR
*)mh16
->lpNext
;
205 *lpParam1
= (DWORD
)mh32
;
206 *lpParam2
= offsetof(MIDIHDR
,dwOffset
);
207 /* dwBufferLength can be reduced between prepare & write */
208 if (wMsg
== MODM_LONGDATA
&& mh32
->dwBufferLength
< mh16
->dwBufferLength
) {
209 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
210 mh32
->dwBufferLength
, mh16
->dwBufferLength
);
212 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
213 ret
= MMSYSTEM_MAP_OKMEM
;
217 case MODM_CACHEPATCHES
:
218 case MODM_CACHEDRUMPATCHES
:
220 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
226 /**************************************************************************
227 * MMSYSTDRV_MidiOut_UnMap16To32W [internal]
229 static MMSYSTEM_MapType
MMSYSTDRV_MidiOut_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
231 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
234 case MODM_GETNUMDEVS
:
238 ret
= MMSYSTEM_MAP_OK
;
244 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
247 case MODM_GETDEVCAPS
:
249 LPMIDIOUTCAPSW moc32
= (LPMIDIOUTCAPSW
)(*lpParam1
);
250 LPMIDIOUTCAPS16 moc16
= *(LPMIDIOUTCAPS16
*)((LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
252 moc16
->wMid
= moc32
->wMid
;
253 moc16
->wPid
= moc32
->wPid
;
254 moc16
->vDriverVersion
= moc32
->vDriverVersion
;
255 WideCharToMultiByte( CP_ACP
, 0, moc32
->szPname
, -1, moc16
->szPname
,
256 sizeof(moc16
->szPname
), NULL
, NULL
);
257 moc16
->wTechnology
= moc32
->wTechnology
;
258 moc16
->wVoices
= moc32
->wVoices
;
259 moc16
->wNotes
= moc32
->wNotes
;
260 moc16
->wChannelMask
= moc32
->wChannelMask
;
261 moc16
->dwSupport
= moc32
->dwSupport
;
262 HeapFree(GetProcessHeap(), 0, (LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
263 ret
= MMSYSTEM_MAP_OK
;
270 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
271 LPMIDIHDR16 mh16
= MapSL(*(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
)));
273 assert((MIDIHDR
*)mh16
->lpNext
== mh32
);
274 mh16
->dwFlags
= mh32
->dwFlags
;
276 if (wMsg
== MODM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
277 HeapFree(GetProcessHeap(), 0, (LPSTR
)mh32
- sizeof(LPMIDIHDR
));
280 ret
= MMSYSTEM_MAP_OK
;
284 case MODM_CACHEPATCHES
:
285 case MODM_CACHEDRUMPATCHES
:
287 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
293 /******************************************************************
294 * MMSYSTDRV_MidiOut_MapCB
296 static void MMSYSTDRV_MidiOut_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
301 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
304 /* MIDIHDR.dwOffset exists since Win 32 only */
305 FIXME("MOM_POSITIONCB/MEVT_F_CALLBACK wants MIDIHDR.dwOffset in 16 bit code\n");
309 /* initial map is: 16 => 32 */
310 LPMIDIHDR mh32
= (LPMIDIHDR
)(*dwParam1
);
311 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
312 LPMIDIHDR16 mh16
= MapSL(segmh16
);
314 *dwParam1
= (DWORD
)segmh16
;
315 mh16
->dwFlags
= mh32
->dwFlags
;
319 ERR("Unknown msg %u\n", uMsg
);
323 /* =================================
324 * W A V E I N M A P P E R S
325 * ================================= */
327 /**************************************************************************
328 * MMSYSTDRV_WaveIn_Map16To32W [internal]
330 static MMSYSTEM_MapType
MMSYSTDRV_WaveIn_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
332 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
335 case WIDM_GETNUMDEVS
:
339 ret
= MMSYSTEM_MAP_OK
;
343 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
345 case WIDM_GETDEVCAPS
:
347 LPWAVEINCAPSW wic32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16
) + sizeof(WAVEINCAPSW
));
348 LPWAVEINCAPS16 wic16
= MapSL(*lpParam1
);
351 *(LPWAVEINCAPS16
*)wic32
= wic16
;
352 wic32
= (LPWAVEINCAPSW
)((LPSTR
)wic32
+ sizeof(LPWAVEINCAPS16
));
353 *lpParam1
= (DWORD
)wic32
;
354 *lpParam2
= sizeof(WAVEINCAPSW
);
356 ret
= MMSYSTEM_MAP_OKMEM
;
358 ret
= MMSYSTEM_MAP_NOMEM
;
364 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
365 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
368 *(LPMMTIME16
*)mmt32
= mmt16
;
369 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
371 mmt32
->wType
= mmt16
->wType
;
372 *lpParam1
= (DWORD
)mmt32
;
373 *lpParam2
= sizeof(MMTIME
);
375 ret
= MMSYSTEM_MAP_OKMEM
;
377 ret
= MMSYSTEM_MAP_NOMEM
;
383 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
384 LPWAVEHDR wh16
= MapSL(*lpParam1
);
387 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
388 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
389 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
390 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
391 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
392 wh32
->dwUser
= wh16
->dwUser
;
393 wh32
->dwFlags
= wh16
->dwFlags
;
394 wh32
->dwLoops
= wh16
->dwLoops
;
395 /* FIXME: nothing on wh32->lpNext */
396 /* could link the wh32->lpNext at this level for memory house keeping */
397 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
398 *lpParam1
= (DWORD
)wh32
;
399 *lpParam2
= sizeof(WAVEHDR
);
401 ret
= MMSYSTEM_MAP_OKMEM
;
403 ret
= MMSYSTEM_MAP_NOMEM
;
410 LPWAVEHDR wh16
= MapSL(*lpParam1
);
411 LPWAVEHDR wh32
= wh16
->lpNext
;
413 *lpParam1
= (DWORD
)wh32
;
414 *lpParam2
= sizeof(WAVEHDR
);
415 /* dwBufferLength can be reduced between prepare & write */
416 if (wMsg
== WIDM_ADDBUFFER
&& wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
417 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
418 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
420 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
421 ret
= MMSYSTEM_MAP_OKMEM
;
424 case WIDM_MAPPER_STATUS
:
425 /* just a single DWORD */
426 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
427 ret
= MMSYSTEM_MAP_OK
;
430 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
436 /**************************************************************************
437 * MMSYSTDRV_WaveIn_UnMap16To32W [internal]
439 static MMSYSTEM_MapType
MMSYSTDRV_WaveIn_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
441 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
444 case WIDM_GETNUMDEVS
:
448 case WIDM_MAPPER_STATUS
:
449 ret
= MMSYSTEM_MAP_OK
;
453 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
455 case WIDM_GETDEVCAPS
:
457 LPWAVEINCAPSW wic32
= (LPWAVEINCAPSW
)(*lpParam1
);
458 LPWAVEINCAPS16 wic16
= *(LPWAVEINCAPS16
*)((LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
460 wic16
->wMid
= wic32
->wMid
;
461 wic16
->wPid
= wic32
->wPid
;
462 wic16
->vDriverVersion
= wic32
->vDriverVersion
;
463 WideCharToMultiByte( CP_ACP
, 0, wic32
->szPname
, -1, wic16
->szPname
,
464 sizeof(wic16
->szPname
), NULL
, NULL
);
465 wic16
->dwFormats
= wic32
->dwFormats
;
466 wic16
->wChannels
= wic32
->wChannels
;
467 HeapFree(GetProcessHeap(), 0, (LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
468 ret
= MMSYSTEM_MAP_OK
;
473 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
474 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
476 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
477 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
478 ret
= MMSYSTEM_MAP_OK
;
485 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
486 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
488 assert(wh16
->lpNext
== wh32
);
489 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
490 wh16
->dwFlags
= wh32
->dwFlags
;
492 if (wMsg
== WIDM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
493 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
496 ret
= MMSYSTEM_MAP_OK
;
500 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
506 /**************************************************************************
507 * MMSYSTDRV_WaveIn_MapCB [internal]
509 static void MMSYSTDRV_WaveIn_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
514 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
518 /* initial map is: 16 => 32 */
519 LPWAVEHDR wh32
= (LPWAVEHDR
)(*dwParam1
);
520 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
521 LPWAVEHDR wh16
= MapSL(segwh16
);
523 *dwParam1
= (DWORD
)segwh16
;
524 wh16
->dwFlags
= wh32
->dwFlags
;
525 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
529 ERR("Unknown msg %u\n", uMsg
);
533 /* =================================
534 * W A V E O U T M A P P E R S
535 * ================================= */
537 /**************************************************************************
538 * MMSYSTDRV_WaveOut_Map16To32W [internal]
540 static MMSYSTEM_MapType
MMSYSTDRV_WaveOut_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
542 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
548 case WODM_GETNUMDEVS
:
553 case WODM_SETPLAYBACKRATE
:
555 ret
= MMSYSTEM_MAP_OK
;
559 case WODM_GETPLAYBACKRATE
:
562 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
565 case WODM_GETDEVCAPS
:
567 LPWAVEOUTCAPSW woc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16
) + sizeof(WAVEOUTCAPSW
));
568 LPWAVEOUTCAPS16 woc16
= MapSL(*lpParam1
);
571 *(LPWAVEOUTCAPS16
*)woc32
= woc16
;
572 woc32
= (LPWAVEOUTCAPSW
)((LPSTR
)woc32
+ sizeof(LPWAVEOUTCAPS16
));
573 *lpParam1
= (DWORD
)woc32
;
574 *lpParam2
= sizeof(WAVEOUTCAPSW
);
576 ret
= MMSYSTEM_MAP_OKMEM
;
578 ret
= MMSYSTEM_MAP_NOMEM
;
584 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
585 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
588 *(LPMMTIME16
*)mmt32
= mmt16
;
589 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
591 mmt32
->wType
= mmt16
->wType
;
592 *lpParam1
= (DWORD
)mmt32
;
593 *lpParam2
= sizeof(MMTIME
);
595 ret
= MMSYSTEM_MAP_OKMEM
;
597 ret
= MMSYSTEM_MAP_NOMEM
;
603 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
604 LPWAVEHDR wh16
= MapSL(*lpParam1
);
607 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
608 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
609 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
610 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
611 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
612 wh32
->dwUser
= wh16
->dwUser
;
613 wh32
->dwFlags
= wh16
->dwFlags
;
614 wh32
->dwLoops
= wh16
->dwLoops
;
615 /* FIXME: nothing on wh32->lpNext */
616 /* could link the wh32->lpNext at this level for memory house keeping */
617 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
618 *lpParam1
= (DWORD
)wh32
;
619 *lpParam2
= sizeof(WAVEHDR
);
621 ret
= MMSYSTEM_MAP_OKMEM
;
623 ret
= MMSYSTEM_MAP_NOMEM
;
630 LPWAVEHDR wh16
= MapSL(*lpParam1
);
631 LPWAVEHDR wh32
= wh16
->lpNext
;
633 *lpParam1
= (DWORD
)wh32
;
634 *lpParam2
= sizeof(WAVEHDR
);
635 /* dwBufferLength can be reduced between prepare & write */
636 if (wMsg
== WODM_WRITE
&& wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
637 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
638 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
640 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
641 ret
= MMSYSTEM_MAP_OKMEM
;
644 case WODM_MAPPER_STATUS
:
645 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
646 ret
= MMSYSTEM_MAP_OK
;
649 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
655 /**************************************************************************
656 * MMSYSTDRV_WaveOut_UnMap16To32W [internal]
658 static MMSYSTEM_MapType
MMSYSTDRV_WaveOut_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
660 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
666 case WODM_GETNUMDEVS
:
671 case WODM_SETPLAYBACKRATE
:
673 case WODM_MAPPER_STATUS
:
674 ret
= MMSYSTEM_MAP_OK
;
678 case WODM_GETPLAYBACKRATE
:
681 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
684 case WODM_GETDEVCAPS
:
686 LPWAVEOUTCAPSW woc32
= (LPWAVEOUTCAPSW
)(*lpParam1
);
687 LPWAVEOUTCAPS16 woc16
= *(LPWAVEOUTCAPS16
*)((LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
689 woc16
->wMid
= woc32
->wMid
;
690 woc16
->wPid
= woc32
->wPid
;
691 woc16
->vDriverVersion
= woc32
->vDriverVersion
;
692 WideCharToMultiByte( CP_ACP
, 0, woc32
->szPname
, -1, woc16
->szPname
,
693 sizeof(woc16
->szPname
), NULL
, NULL
);
694 woc16
->dwFormats
= woc32
->dwFormats
;
695 woc16
->wChannels
= woc32
->wChannels
;
696 woc16
->dwSupport
= woc32
->dwSupport
;
697 HeapFree(GetProcessHeap(), 0, (LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
698 ret
= MMSYSTEM_MAP_OK
;
703 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
704 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
706 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
707 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
708 ret
= MMSYSTEM_MAP_OK
;
715 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
716 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
718 assert(wh16
->lpNext
== wh32
);
719 wh16
->dwFlags
= wh32
->dwFlags
;
721 if (wMsg
== WODM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
722 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
725 ret
= MMSYSTEM_MAP_OK
;
729 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
735 /**************************************************************************
736 * MMDRV_WaveOut_Callback [internal]
738 static void MMSYSTDRV_WaveOut_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
743 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
747 /* initial map is: 16 => 32 */
748 LPWAVEHDR wh32
= (LPWAVEHDR
)(*dwParam1
);
749 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
750 LPWAVEHDR wh16
= MapSL(segwh16
);
752 *dwParam1
= (DWORD
)segwh16
;
753 wh16
->dwFlags
= wh32
->dwFlags
;
757 ERR("Unknown msg %u\n", uMsg
);
761 /* ###################################################
762 * # DRIVER THUNKING #
763 * ###################################################
765 typedef MMSYSTEM_MapType (*MMSYSTDRV_MAPMSG
)(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
);
766 typedef MMSYSTEM_MapType (*MMSYSTDRV_UNMAPMSG
)(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT ret
);
767 typedef void (*MMSYSTDRV_MAPCB
)(DWORD wMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
);
769 #include <pshpack1.h>
770 #define MMSYSTDRV_MAX_THUNKS 32
772 static struct mmsystdrv_thunk
774 BYTE popl_eax
; /* popl %eax (return address) */
775 BYTE pushl_this
; /* pushl this (this very thunk) */
776 struct mmsystdrv_thunk
* this;
777 BYTE pushl_eax
; /* pushl %eax */
778 BYTE jmp
; /* ljmp MMDRV_Callback3216 */
780 DWORD callback
; /* callback value (function, window, event...) */
781 DWORD flags
; /* flags to control callback value (CALLBACK_???) */
782 void* hMmdrv
; /* Handle to 32bit mmdrv object */
783 enum MMSYSTEM_DriverType kind
;
788 static struct MMSYSTDRV_Type
790 MMSYSTDRV_MAPMSG mapmsg16to32W
;
791 MMSYSTDRV_UNMAPMSG unmapmsg16to32W
;
792 MMSYSTDRV_MAPCB mapcb
;
793 } MMSYSTEM_DriversType
[MMSYSTDRV_MAX
] =
795 {MMSYSTDRV_Mixer_Map16To32W
, MMSYSTDRV_Mixer_UnMap16To32W
, MMSYSTDRV_Mixer_MapCB
},
796 {MMSYSTDRV_MidiIn_Map16To32W
, MMSYSTDRV_MidiIn_UnMap16To32W
, MMSYSTDRV_MidiIn_MapCB
},
797 {MMSYSTDRV_MidiOut_Map16To32W
, MMSYSTDRV_MidiOut_UnMap16To32W
, MMSYSTDRV_MidiOut_MapCB
},
798 {MMSYSTDRV_WaveIn_Map16To32W
, MMSYSTDRV_WaveIn_UnMap16To32W
, MMSYSTDRV_WaveIn_MapCB
},
799 {MMSYSTDRV_WaveOut_Map16To32W
, MMSYSTDRV_WaveOut_UnMap16To32W
, MMSYSTDRV_WaveOut_MapCB
},
802 /******************************************************************
803 * MMSYSTDRV_Callback3216
806 static LRESULT CALLBACK
MMSYSTDRV_Callback3216(struct mmsystdrv_thunk
* thunk
, HDRVR hDev
,
807 DWORD wMsg
, DWORD_PTR dwUser
, DWORD_PTR dwParam1
,
812 assert(thunk
->kind
< MMSYSTDRV_MAX
);
813 assert(MMSYSTEM_DriversType
[thunk
->kind
].mapcb
);
815 MMSYSTEM_DriversType
[thunk
->kind
].mapcb(wMsg
, &dwUser
, &dwParam1
, &dwParam2
);
817 switch (thunk
->flags
& CALLBACK_TYPEMASK
) {
821 case CALLBACK_WINDOW
:
822 TRACE("Window(%04X) handle=%p!\n", thunk
->callback
, hDev
);
823 PostMessageA((HWND
)thunk
->callback
, wMsg
, (WPARAM
)hDev
, dwParam1
);
825 case CALLBACK_TASK
: /* aka CALLBACK_THREAD */
826 TRACE("Task(%04x) !\n", thunk
->callback
);
827 PostThreadMessageA(thunk
->callback
, wMsg
, (WPARAM
)hDev
, dwParam1
);
829 case CALLBACK_FUNCTION
:
830 /* 16 bit func, call it */
831 TRACE("Function (16 bit) %x!\n", thunk
->callback
);
833 args
[7] = HDRVR_16(hDev
);
835 args
[5] = HIWORD(dwUser
);
836 args
[4] = LOWORD(dwUser
);
837 args
[3] = HIWORD(dwParam1
);
838 args
[2] = LOWORD(dwParam1
);
839 args
[1] = HIWORD(dwParam2
);
840 args
[0] = LOWORD(dwParam2
);
841 return WOWCallback16Ex(thunk
->callback
, WCB16_PASCAL
, sizeof(args
), args
, NULL
);
843 TRACE("Event(%08x) !\n", thunk
->callback
);
844 SetEvent((HANDLE
)thunk
->callback
);
847 WARN("Unknown callback type %x\n", thunk
->flags
& CALLBACK_TYPEMASK
);
854 /******************************************************************
858 struct mmsystdrv_thunk
* MMSYSTDRV_AddThunk(DWORD callback
, DWORD flags
, enum MMSYSTEM_DriverType kind
)
860 struct mmsystdrv_thunk
* thunk
;
862 EnterCriticalSection(&mmdrv_cs
);
863 if (!MMSYSTDRV_Thunks
)
865 MMSYSTDRV_Thunks
= VirtualAlloc(NULL
, MMSYSTDRV_MAX_THUNKS
* sizeof(*MMSYSTDRV_Thunks
),
866 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
867 if (!MMSYSTDRV_Thunks
)
869 LeaveCriticalSection(&mmdrv_cs
);
872 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
874 thunk
->popl_eax
= 0x58; /* popl %eax */
875 thunk
->pushl_this
= 0x68; /* pushl this */
877 thunk
->pushl_eax
= 0x50; /* pushl %eax */
878 thunk
->jmp
= 0xe9; /* jmp MMDRV_Callback3216 */
879 thunk
->callback3216
= (char *)MMSYSTDRV_Callback3216
- (char *)(&thunk
->callback3216
+ 1);
881 thunk
->flags
= CALLBACK_NULL
;
882 thunk
->hMmdrv
= NULL
;
883 thunk
->kind
= MMSYSTDRV_MAX
;
886 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
888 if (thunk
->callback
== 0 && thunk
->hMmdrv
== NULL
)
890 thunk
->callback
= callback
;
891 thunk
->flags
= flags
;
892 thunk
->hMmdrv
= NULL
;
894 LeaveCriticalSection(&mmdrv_cs
);
898 LeaveCriticalSection(&mmdrv_cs
);
899 FIXME("Out of mmdrv-thunks. Bump MMDRV_MAX_THUNKS\n");
903 /******************************************************************
904 * MMSYSTDRV_FindHandle
906 * Must be called with lock set
908 static void* MMSYSTDRV_FindHandle(void* h
)
910 struct mmsystdrv_thunk
* thunk
;
912 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
914 if (thunk
->hMmdrv
== h
)
916 if (thunk
->kind
>= MMSYSTDRV_MAX
) FIXME("Kind isn't properly initialized %x\n", thunk
->kind
);
923 /******************************************************************
924 * MMSYSTDRV_SetHandle
927 void MMSYSTDRV_SetHandle(struct mmsystdrv_thunk
* thunk
, void* h
)
929 if (MMSYSTDRV_FindHandle(h
)) FIXME("Already has a thunk for this handle %p!!!\n", h
);
933 /******************************************************************
934 * MMSYSTDRV_DeleteThunk
936 void MMSYSTDRV_DeleteThunk(struct mmsystdrv_thunk
* thunk
)
939 thunk
->flags
= CALLBACK_NULL
;
940 thunk
->hMmdrv
= NULL
;
941 thunk
->kind
= MMSYSTDRV_MAX
;
944 /******************************************************************
945 * MMSYSTDRV_CloseHandle
947 void MMSYSTDRV_CloseHandle(void* h
)
949 struct mmsystdrv_thunk
* thunk
;
951 EnterCriticalSection(&mmdrv_cs
);
952 if ((thunk
= MMSYSTDRV_FindHandle(h
)))
954 MMSYSTDRV_DeleteThunk(thunk
);
956 LeaveCriticalSection(&mmdrv_cs
);
959 /******************************************************************
962 DWORD
MMSYSTDRV_Message(void* h
, UINT msg
, DWORD_PTR param1
, DWORD_PTR param2
)
964 struct mmsystdrv_thunk
* thunk
= MMSYSTDRV_FindHandle(h
);
965 struct MMSYSTDRV_Type
* drvtype
;
966 MMSYSTEM_MapType map
;
969 if (!thunk
) return MMSYSERR_INVALHANDLE
;
970 drvtype
= &MMSYSTEM_DriversType
[thunk
->kind
];
972 map
= drvtype
->mapmsg16to32W(msg
, ¶m1
, ¶m2
);
974 case MMSYSTEM_MAP_NOMEM
:
975 ret
= MMSYSERR_NOMEM
;
977 case MMSYSTEM_MAP_MSGERROR
:
978 FIXME("NIY: no conversion yet 16->32 kind=%u msg=%u\n", thunk
->kind
, msg
);
979 ret
= MMSYSERR_ERROR
;
981 case MMSYSTEM_MAP_OK
:
982 case MMSYSTEM_MAP_OKMEM
:
983 TRACE("Calling message(msg=%u p1=0x%08lx p2=0x%08lx)\n",
984 msg
, param1
, param2
);
987 case MMSYSTDRV_MIXER
: ret
= mixerMessage (h
, msg
, param1
, param2
); break;
988 case MMSYSTDRV_MIDIIN
:
991 case MIDM_ADDBUFFER
: ret
= midiInAddBuffer(h
, (LPMIDIHDR
)param1
, param2
); break;
992 case MIDM_PREPARE
: ret
= midiInPrepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
993 case MIDM_UNPREPARE
: ret
= midiInUnprepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
994 default: ret
= midiInMessage(h
, msg
, param1
, param2
); break;
997 case MMSYSTDRV_MIDIOUT
:
1000 case MODM_PREPARE
: ret
= midiOutPrepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
1001 case MODM_UNPREPARE
: ret
= midiOutUnprepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
1002 case MODM_LONGDATA
: ret
= midiOutLongMsg(h
, (LPMIDIHDR
)param1
, param2
); break;
1003 default: ret
= midiOutMessage(h
, msg
, param1
, param2
); break;
1006 case MMSYSTDRV_WAVEIN
:
1009 case WIDM_ADDBUFFER
: ret
= waveInAddBuffer(h
, (LPWAVEHDR
)param1
, param2
); break;
1010 case WIDM_PREPARE
: ret
= waveInPrepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1011 case WIDM_UNPREPARE
: ret
= waveInUnprepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1012 default: ret
= waveInMessage(h
, msg
, param1
, param2
); break;
1015 case MMSYSTDRV_WAVEOUT
:
1018 case WODM_PREPARE
: ret
= waveOutPrepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1019 case WODM_UNPREPARE
: ret
= waveOutUnprepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1020 case WODM_WRITE
: ret
= waveOutWrite(h
, (LPWAVEHDR
)param1
, param2
); break;
1021 default: ret
= waveOutMessage(h
, msg
, param1
, param2
); break;
1024 default: ret
= MMSYSERR_INVALHANDLE
; break; /* should never be reached */
1026 if (map
== MMSYSTEM_MAP_OKMEM
)
1027 drvtype
->unmapmsg16to32W(msg
, ¶m1
, ¶m2
, ret
);
1031 ret
= MMSYSERR_NOTSUPPORTED
;