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 LPMIDIHDR mh16
= MapSL(segmh16
);
124 *dwParam1
= (DWORD
)segmh16
;
125 mh16
->dwFlags
= mh32
->dwFlags
;
126 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
127 if (mh16
->reserved
>= sizeof(MIDIHDR
))
128 mh16
->dwOffset
= mh32
->dwOffset
;
132 ERR("Unknown msg %u\n", uMsg
);
136 /* =================================
137 * M I D I O U T M A P P E R S
138 * ================================= */
140 /**************************************************************************
141 * MMSYSTDRV_MidiOut_Map16To32W [internal]
143 static MMSYSTEM_MapType
MMSYSTDRV_MidiOut_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
145 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
148 case MODM_GETNUMDEVS
:
152 ret
= MMSYSTEM_MAP_OK
;
158 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
161 case MODM_GETDEVCAPS
:
163 LPMIDIOUTCAPSW moc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16
) + sizeof(MIDIOUTCAPSW
));
164 LPMIDIOUTCAPS16 moc16
= MapSL(*lpParam1
);
167 *(LPMIDIOUTCAPS16
*)moc32
= moc16
;
168 moc32
= (LPMIDIOUTCAPSW
)((LPSTR
)moc32
+ sizeof(LPMIDIOUTCAPS16
));
169 *lpParam1
= (DWORD
)moc32
;
170 *lpParam2
= sizeof(MIDIOUTCAPSW
);
172 ret
= MMSYSTEM_MAP_OKMEM
;
174 ret
= MMSYSTEM_MAP_NOMEM
;
180 LPMIDIHDR mh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
));
181 LPMIDIHDR mh16
= MapSL(*lpParam1
);
184 *(LPMIDIHDR
*)mh32
= (LPMIDIHDR
)*lpParam1
;
185 mh32
= (LPMIDIHDR
)((LPSTR
)mh32
+ sizeof(LPMIDIHDR
));
186 mh32
->lpData
= MapSL((SEGPTR
)mh16
->lpData
);
187 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
188 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
189 mh32
->dwUser
= mh16
->dwUser
;
190 mh32
->dwFlags
= mh16
->dwFlags
;
191 /* FIXME: nothing on mh32->lpNext */
192 /* could link the mh32->lpNext at this level for memory house keeping */
193 mh32
->dwOffset
= (*lpParam2
>= sizeof(MIDIHDR
)) ? mh16
->dwOffset
: 0;
194 mh16
->lpNext
= mh32
; /* for reuse in unprepare and write */
195 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
196 mh16
->reserved
= *lpParam2
;
197 *lpParam1
= (DWORD
)mh32
;
198 *lpParam2
= sizeof(MIDIHDR
);
200 ret
= MMSYSTEM_MAP_OKMEM
;
202 ret
= MMSYSTEM_MAP_NOMEM
;
209 LPMIDIHDR mh16
= MapSL(*lpParam1
);
210 LPMIDIHDR mh32
= mh16
->lpNext
;
212 *lpParam1
= (DWORD
)mh32
;
213 *lpParam2
= sizeof(MIDIHDR
);
214 /* dwBufferLength can be reduced between prepare & write */
215 if (wMsg
== MODM_LONGDATA
&& mh32
->dwBufferLength
< mh16
->dwBufferLength
) {
216 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
217 mh32
->dwBufferLength
, mh16
->dwBufferLength
);
219 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
220 ret
= MMSYSTEM_MAP_OKMEM
;
224 case MODM_CACHEPATCHES
:
225 case MODM_CACHEDRUMPATCHES
:
227 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
233 /**************************************************************************
234 * MMSYSTDRV_MidiOut_UnMap16To32W [internal]
236 static MMSYSTEM_MapType
MMSYSTDRV_MidiOut_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
238 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
241 case MODM_GETNUMDEVS
:
245 ret
= MMSYSTEM_MAP_OK
;
251 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
254 case MODM_GETDEVCAPS
:
256 LPMIDIOUTCAPSW moc32
= (LPMIDIOUTCAPSW
)(*lpParam1
);
257 LPMIDIOUTCAPS16 moc16
= *(LPMIDIOUTCAPS16
*)((LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
259 moc16
->wMid
= moc32
->wMid
;
260 moc16
->wPid
= moc32
->wPid
;
261 moc16
->vDriverVersion
= moc32
->vDriverVersion
;
262 WideCharToMultiByte( CP_ACP
, 0, moc32
->szPname
, -1, moc16
->szPname
,
263 sizeof(moc16
->szPname
), NULL
, NULL
);
264 moc16
->wTechnology
= moc32
->wTechnology
;
265 moc16
->wVoices
= moc32
->wVoices
;
266 moc16
->wNotes
= moc32
->wNotes
;
267 moc16
->wChannelMask
= moc32
->wChannelMask
;
268 moc16
->dwSupport
= moc32
->dwSupport
;
269 HeapFree(GetProcessHeap(), 0, (LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
270 ret
= MMSYSTEM_MAP_OK
;
277 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
278 LPMIDIHDR mh16
= MapSL(*(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
)));
280 assert(mh16
->lpNext
== mh32
);
281 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
282 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
283 mh16
->dwUser
= mh32
->dwUser
;
284 mh16
->dwFlags
= mh32
->dwFlags
;
285 if (mh16
->reserved
>= sizeof(MIDIHDR
))
286 mh16
->dwOffset
= mh32
->dwOffset
;
288 if (wMsg
== MODM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
289 HeapFree(GetProcessHeap(), 0, (LPSTR
)mh32
- sizeof(LPMIDIHDR
));
292 ret
= MMSYSTEM_MAP_OK
;
296 case MODM_CACHEPATCHES
:
297 case MODM_CACHEDRUMPATCHES
:
299 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
305 /******************************************************************
306 * MMSYSTDRV_MidiOut_MapCB
308 static void MMSYSTDRV_MidiOut_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
313 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
317 /* initial map is: 16 => 32 */
318 LPMIDIHDR mh32
= (LPMIDIHDR
)(*dwParam1
);
319 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
320 LPMIDIHDR mh16
= MapSL(segmh16
);
322 *dwParam1
= (DWORD
)segmh16
;
323 mh16
->dwFlags
= mh32
->dwFlags
;
324 if (mh16
->reserved
>= sizeof(MIDIHDR
))
325 mh16
->dwOffset
= mh32
->dwOffset
;
330 /* FIXME: would require to recreate a 16bit MIDIHDR here */
331 *dwParam1
= *dwParam2
= 0;
334 ERR("Unknown msg %u\n", uMsg
);
338 /* =================================
339 * W A V E I N M A P P E R S
340 * ================================= */
342 /**************************************************************************
343 * MMSYSTDRV_WaveIn_Map16To32W [internal]
345 static MMSYSTEM_MapType
MMSYSTDRV_WaveIn_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
347 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
350 case WIDM_GETNUMDEVS
:
354 ret
= MMSYSTEM_MAP_OK
;
358 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
360 case WIDM_GETDEVCAPS
:
362 LPWAVEINCAPSW wic32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16
) + sizeof(WAVEINCAPSW
));
363 LPWAVEINCAPS16 wic16
= MapSL(*lpParam1
);
366 *(LPWAVEINCAPS16
*)wic32
= wic16
;
367 wic32
= (LPWAVEINCAPSW
)((LPSTR
)wic32
+ sizeof(LPWAVEINCAPS16
));
368 *lpParam1
= (DWORD
)wic32
;
369 *lpParam2
= sizeof(WAVEINCAPSW
);
371 ret
= MMSYSTEM_MAP_OKMEM
;
373 ret
= MMSYSTEM_MAP_NOMEM
;
379 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
380 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
383 *(LPMMTIME16
*)mmt32
= mmt16
;
384 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
386 mmt32
->wType
= mmt16
->wType
;
387 *lpParam1
= (DWORD
)mmt32
;
388 *lpParam2
= sizeof(MMTIME
);
390 ret
= MMSYSTEM_MAP_OKMEM
;
392 ret
= MMSYSTEM_MAP_NOMEM
;
398 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
399 LPWAVEHDR wh16
= MapSL(*lpParam1
);
402 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
403 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
404 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
405 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
406 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
407 wh32
->dwUser
= wh16
->dwUser
;
408 wh32
->dwFlags
= wh16
->dwFlags
;
409 wh32
->dwLoops
= wh16
->dwLoops
;
410 /* FIXME: nothing on wh32->lpNext */
411 /* could link the wh32->lpNext at this level for memory house keeping */
412 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
413 *lpParam1
= (DWORD
)wh32
;
414 *lpParam2
= sizeof(WAVEHDR
);
416 ret
= MMSYSTEM_MAP_OKMEM
;
418 ret
= MMSYSTEM_MAP_NOMEM
;
425 LPWAVEHDR wh16
= MapSL(*lpParam1
);
426 LPWAVEHDR wh32
= wh16
->lpNext
;
428 *lpParam1
= (DWORD
)wh32
;
429 *lpParam2
= sizeof(WAVEHDR
);
430 /* dwBufferLength can be reduced between prepare & write */
431 if (wMsg
== WIDM_ADDBUFFER
&& wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
432 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
433 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
435 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
436 ret
= MMSYSTEM_MAP_OKMEM
;
439 case WIDM_MAPPER_STATUS
:
440 /* just a single DWORD */
441 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
442 ret
= MMSYSTEM_MAP_OK
;
445 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
451 /**************************************************************************
452 * MMSYSTDRV_WaveIn_UnMap16To32W [internal]
454 static MMSYSTEM_MapType
MMSYSTDRV_WaveIn_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
456 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
459 case WIDM_GETNUMDEVS
:
463 case WIDM_MAPPER_STATUS
:
464 ret
= MMSYSTEM_MAP_OK
;
468 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
470 case WIDM_GETDEVCAPS
:
472 LPWAVEINCAPSW wic32
= (LPWAVEINCAPSW
)(*lpParam1
);
473 LPWAVEINCAPS16 wic16
= *(LPWAVEINCAPS16
*)((LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
475 wic16
->wMid
= wic32
->wMid
;
476 wic16
->wPid
= wic32
->wPid
;
477 wic16
->vDriverVersion
= wic32
->vDriverVersion
;
478 WideCharToMultiByte( CP_ACP
, 0, wic32
->szPname
, -1, wic16
->szPname
,
479 sizeof(wic16
->szPname
), NULL
, NULL
);
480 wic16
->dwFormats
= wic32
->dwFormats
;
481 wic16
->wChannels
= wic32
->wChannels
;
482 HeapFree(GetProcessHeap(), 0, (LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
483 ret
= MMSYSTEM_MAP_OK
;
488 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
489 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
491 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
492 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
493 ret
= MMSYSTEM_MAP_OK
;
500 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
501 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
503 assert(wh16
->lpNext
== wh32
);
504 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
505 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
506 wh16
->dwUser
= wh32
->dwUser
;
507 wh16
->dwFlags
= wh32
->dwFlags
;
508 wh16
->dwLoops
= wh32
->dwLoops
;
510 if (wMsg
== WIDM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
511 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
514 ret
= MMSYSTEM_MAP_OK
;
518 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
524 /**************************************************************************
525 * MMSYSTDRV_WaveIn_MapCB [internal]
527 static void MMSYSTDRV_WaveIn_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
532 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
536 /* initial map is: 16 => 32 */
537 LPWAVEHDR wh32
= (LPWAVEHDR
)(*dwParam1
);
538 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
539 LPWAVEHDR wh16
= MapSL(segwh16
);
541 *dwParam1
= (DWORD
)segwh16
;
542 wh16
->dwFlags
= wh32
->dwFlags
;
543 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
547 ERR("Unknown msg %u\n", uMsg
);
551 /* =================================
552 * W A V E O U T M A P P E R S
553 * ================================= */
555 /**************************************************************************
556 * MMSYSTDRV_WaveOut_Map16To32W [internal]
558 static MMSYSTEM_MapType
MMSYSTDRV_WaveOut_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
560 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
566 case WODM_GETNUMDEVS
:
571 case WODM_SETPLAYBACKRATE
:
573 ret
= MMSYSTEM_MAP_OK
;
577 case WODM_GETPLAYBACKRATE
:
580 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
583 case WODM_GETDEVCAPS
:
585 LPWAVEOUTCAPSW woc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16
) + sizeof(WAVEOUTCAPSW
));
586 LPWAVEOUTCAPS16 woc16
= MapSL(*lpParam1
);
589 *(LPWAVEOUTCAPS16
*)woc32
= woc16
;
590 woc32
= (LPWAVEOUTCAPSW
)((LPSTR
)woc32
+ sizeof(LPWAVEOUTCAPS16
));
591 *lpParam1
= (DWORD
)woc32
;
592 *lpParam2
= sizeof(WAVEOUTCAPSW
);
594 ret
= MMSYSTEM_MAP_OKMEM
;
596 ret
= MMSYSTEM_MAP_NOMEM
;
602 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
603 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
606 *(LPMMTIME16
*)mmt32
= mmt16
;
607 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
609 mmt32
->wType
= mmt16
->wType
;
610 *lpParam1
= (DWORD
)mmt32
;
611 *lpParam2
= sizeof(MMTIME
);
613 ret
= MMSYSTEM_MAP_OKMEM
;
615 ret
= MMSYSTEM_MAP_NOMEM
;
621 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
622 LPWAVEHDR wh16
= MapSL(*lpParam1
);
625 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
626 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
627 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
628 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
629 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
630 wh32
->dwUser
= wh16
->dwUser
;
631 wh32
->dwFlags
= wh16
->dwFlags
;
632 wh32
->dwLoops
= wh16
->dwLoops
;
633 /* FIXME: nothing on wh32->lpNext */
634 /* could link the wh32->lpNext at this level for memory house keeping */
635 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
636 *lpParam1
= (DWORD
)wh32
;
637 *lpParam2
= sizeof(WAVEHDR
);
639 ret
= MMSYSTEM_MAP_OKMEM
;
641 ret
= MMSYSTEM_MAP_NOMEM
;
648 LPWAVEHDR wh16
= MapSL(*lpParam1
);
649 LPWAVEHDR wh32
= wh16
->lpNext
;
651 *lpParam1
= (DWORD
)wh32
;
652 *lpParam2
= sizeof(WAVEHDR
);
653 /* dwBufferLength can be reduced between prepare & write */
654 if (wMsg
== WODM_WRITE
&& wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
655 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
656 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
658 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
659 ret
= MMSYSTEM_MAP_OKMEM
;
662 case WODM_MAPPER_STATUS
:
663 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
664 ret
= MMSYSTEM_MAP_OK
;
667 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
673 /**************************************************************************
674 * MMSYSTDRV_WaveOut_UnMap16To32W [internal]
676 static MMSYSTEM_MapType
MMSYSTDRV_WaveOut_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
678 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
684 case WODM_GETNUMDEVS
:
689 case WODM_SETPLAYBACKRATE
:
691 case WODM_MAPPER_STATUS
:
692 ret
= MMSYSTEM_MAP_OK
;
696 case WODM_GETPLAYBACKRATE
:
699 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
702 case WODM_GETDEVCAPS
:
704 LPWAVEOUTCAPSW woc32
= (LPWAVEOUTCAPSW
)(*lpParam1
);
705 LPWAVEOUTCAPS16 woc16
= *(LPWAVEOUTCAPS16
*)((LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
707 woc16
->wMid
= woc32
->wMid
;
708 woc16
->wPid
= woc32
->wPid
;
709 woc16
->vDriverVersion
= woc32
->vDriverVersion
;
710 WideCharToMultiByte( CP_ACP
, 0, woc32
->szPname
, -1, woc16
->szPname
,
711 sizeof(woc16
->szPname
), NULL
, NULL
);
712 woc16
->dwFormats
= woc32
->dwFormats
;
713 woc16
->wChannels
= woc32
->wChannels
;
714 woc16
->dwSupport
= woc32
->dwSupport
;
715 HeapFree(GetProcessHeap(), 0, (LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
716 ret
= MMSYSTEM_MAP_OK
;
721 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
722 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
724 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
725 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
726 ret
= MMSYSTEM_MAP_OK
;
733 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
734 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
736 assert(wh16
->lpNext
== wh32
);
737 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
738 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
739 wh16
->dwUser
= wh32
->dwUser
;
740 wh16
->dwFlags
= wh32
->dwFlags
;
741 wh16
->dwLoops
= wh32
->dwLoops
;
743 if (wMsg
== WODM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
744 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
747 ret
= MMSYSTEM_MAP_OK
;
751 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
757 /**************************************************************************
758 * MMDRV_WaveOut_Callback [internal]
760 static void MMSYSTDRV_WaveOut_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
765 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
769 /* initial map is: 16 => 32 */
770 LPWAVEHDR wh32
= (LPWAVEHDR
)(*dwParam1
);
771 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
772 LPWAVEHDR wh16
= MapSL(segwh16
);
774 *dwParam1
= (DWORD
)segwh16
;
775 wh16
->dwFlags
= wh32
->dwFlags
;
779 ERR("Unknown msg %u\n", uMsg
);
783 /* ###################################################
784 * # DRIVER THUNKING #
785 * ###################################################
787 typedef MMSYSTEM_MapType (*MMSYSTDRV_MAPMSG
)(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
);
788 typedef MMSYSTEM_MapType (*MMSYSTDRV_UNMAPMSG
)(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT ret
);
789 typedef void (*MMSYSTDRV_MAPCB
)(DWORD wMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
);
791 #include <pshpack1.h>
792 #define MMSYSTDRV_MAX_THUNKS 32
794 static struct mmsystdrv_thunk
796 BYTE popl_eax
; /* popl %eax (return address) */
797 BYTE pushl_this
; /* pushl this (this very thunk) */
798 struct mmsystdrv_thunk
* this;
799 BYTE pushl_eax
; /* pushl %eax */
800 BYTE jmp
; /* ljmp MMDRV_Callback3216 */
802 DWORD callback
; /* callback value (function, window, event...) */
803 DWORD flags
; /* flags to control callback value (CALLBACK_???) */
804 void* hMmdrv
; /* Handle to 32bit mmdrv object */
805 enum MMSYSTEM_DriverType kind
;
810 static struct MMSYSTDRV_Type
812 MMSYSTDRV_MAPMSG mapmsg16to32W
;
813 MMSYSTDRV_UNMAPMSG unmapmsg16to32W
;
814 MMSYSTDRV_MAPCB mapcb
;
815 } MMSYSTEM_DriversType
[MMSYSTDRV_MAX
] =
817 {MMSYSTDRV_Mixer_Map16To32W
, MMSYSTDRV_Mixer_UnMap16To32W
, MMSYSTDRV_Mixer_MapCB
},
818 {MMSYSTDRV_MidiIn_Map16To32W
, MMSYSTDRV_MidiIn_UnMap16To32W
, MMSYSTDRV_MidiIn_MapCB
},
819 {MMSYSTDRV_MidiOut_Map16To32W
, MMSYSTDRV_MidiOut_UnMap16To32W
, MMSYSTDRV_MidiOut_MapCB
},
820 {MMSYSTDRV_WaveIn_Map16To32W
, MMSYSTDRV_WaveIn_UnMap16To32W
, MMSYSTDRV_WaveIn_MapCB
},
821 {MMSYSTDRV_WaveOut_Map16To32W
, MMSYSTDRV_WaveOut_UnMap16To32W
, MMSYSTDRV_WaveOut_MapCB
},
824 /******************************************************************
825 * MMSYSTDRV_Callback3216
828 static LRESULT CALLBACK
MMSYSTDRV_Callback3216(struct mmsystdrv_thunk
* thunk
, HDRVR hDev
,
829 DWORD wMsg
, DWORD_PTR dwUser
, DWORD_PTR dwParam1
,
834 assert(thunk
->kind
< MMSYSTDRV_MAX
);
835 assert(MMSYSTEM_DriversType
[thunk
->kind
].mapcb
);
837 MMSYSTEM_DriversType
[thunk
->kind
].mapcb(wMsg
, &dwUser
, &dwParam1
, &dwParam2
);
839 switch (thunk
->flags
& CALLBACK_TYPEMASK
) {
843 case CALLBACK_WINDOW
:
844 TRACE("Window(%04X) handle=%p!\n", thunk
->callback
, hDev
);
845 PostMessageA((HWND
)thunk
->callback
, wMsg
, (WPARAM
)hDev
, dwParam1
);
847 case CALLBACK_TASK
: /* aka CALLBACK_THREAD */
848 TRACE("Task(%04x) !\n", thunk
->callback
);
849 PostThreadMessageA(thunk
->callback
, wMsg
, (WPARAM
)hDev
, dwParam1
);
851 case CALLBACK_FUNCTION
:
852 /* 16 bit func, call it */
853 TRACE("Function (16 bit) %x!\n", thunk
->callback
);
855 args
[7] = HDRVR_16(hDev
);
857 args
[5] = HIWORD(dwUser
);
858 args
[4] = LOWORD(dwUser
);
859 args
[3] = HIWORD(dwParam1
);
860 args
[2] = LOWORD(dwParam1
);
861 args
[1] = HIWORD(dwParam2
);
862 args
[0] = LOWORD(dwParam2
);
863 return WOWCallback16Ex(thunk
->callback
, WCB16_PASCAL
, sizeof(args
), args
, NULL
);
865 TRACE("Event(%08x) !\n", thunk
->callback
);
866 SetEvent((HANDLE
)thunk
->callback
);
869 WARN("Unknown callback type %x\n", thunk
->flags
& CALLBACK_TYPEMASK
);
876 /******************************************************************
880 struct mmsystdrv_thunk
* MMSYSTDRV_AddThunk(DWORD callback
, DWORD flags
, enum MMSYSTEM_DriverType kind
)
882 struct mmsystdrv_thunk
* thunk
;
884 EnterCriticalSection(&mmdrv_cs
);
885 if (!MMSYSTDRV_Thunks
)
887 MMSYSTDRV_Thunks
= VirtualAlloc(NULL
, MMSYSTDRV_MAX_THUNKS
* sizeof(*MMSYSTDRV_Thunks
),
888 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
889 if (!MMSYSTDRV_Thunks
)
891 LeaveCriticalSection(&mmdrv_cs
);
894 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
896 thunk
->popl_eax
= 0x58; /* popl %eax */
897 thunk
->pushl_this
= 0x68; /* pushl this */
899 thunk
->pushl_eax
= 0x50; /* pushl %eax */
900 thunk
->jmp
= 0xe9; /* jmp MMDRV_Callback3216 */
901 thunk
->callback3216
= (char *)MMSYSTDRV_Callback3216
- (char *)(&thunk
->callback3216
+ 1);
903 thunk
->flags
= CALLBACK_NULL
;
904 thunk
->hMmdrv
= NULL
;
905 thunk
->kind
= MMSYSTDRV_MAX
;
908 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
910 if (thunk
->callback
== 0 && thunk
->hMmdrv
== NULL
)
912 thunk
->callback
= callback
;
913 thunk
->flags
= flags
;
914 thunk
->hMmdrv
= NULL
;
916 LeaveCriticalSection(&mmdrv_cs
);
920 LeaveCriticalSection(&mmdrv_cs
);
921 FIXME("Out of mmdrv-thunks. Bump MMDRV_MAX_THUNKS\n");
925 /******************************************************************
926 * MMSYSTDRV_FindHandle
928 * Must be called with lock set
930 static void* MMSYSTDRV_FindHandle(void* h
)
932 struct mmsystdrv_thunk
* thunk
;
934 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
936 if (thunk
->hMmdrv
== h
)
938 if (thunk
->kind
>= MMSYSTDRV_MAX
) FIXME("Kind isn't properly initialized %x\n", thunk
->kind
);
945 /******************************************************************
946 * MMSYSTDRV_SetHandle
949 void MMSYSTDRV_SetHandle(struct mmsystdrv_thunk
* thunk
, void* h
)
951 if (MMSYSTDRV_FindHandle(h
)) FIXME("Already has a thunk for this handle %p!!!\n", h
);
955 /******************************************************************
956 * MMSYSTDRV_DeleteThunk
958 void MMSYSTDRV_DeleteThunk(struct mmsystdrv_thunk
* thunk
)
961 thunk
->flags
= CALLBACK_NULL
;
962 thunk
->hMmdrv
= NULL
;
963 thunk
->kind
= MMSYSTDRV_MAX
;
966 /******************************************************************
967 * MMSYSTDRV_CloseHandle
969 void MMSYSTDRV_CloseHandle(void* h
)
971 struct mmsystdrv_thunk
* thunk
;
973 EnterCriticalSection(&mmdrv_cs
);
974 if ((thunk
= MMSYSTDRV_FindHandle(h
)))
976 MMSYSTDRV_DeleteThunk(thunk
);
978 LeaveCriticalSection(&mmdrv_cs
);
981 /******************************************************************
984 DWORD
MMSYSTDRV_Message(void* h
, UINT msg
, DWORD_PTR param1
, DWORD_PTR param2
)
986 struct mmsystdrv_thunk
* thunk
= MMSYSTDRV_FindHandle(h
);
987 struct MMSYSTDRV_Type
* drvtype
;
988 MMSYSTEM_MapType map
;
991 if (!thunk
) return MMSYSERR_INVALHANDLE
;
992 drvtype
= &MMSYSTEM_DriversType
[thunk
->kind
];
994 map
= drvtype
->mapmsg16to32W(msg
, ¶m1
, ¶m2
);
996 case MMSYSTEM_MAP_NOMEM
:
997 ret
= MMSYSERR_NOMEM
;
999 case MMSYSTEM_MAP_MSGERROR
:
1000 FIXME("NIY: no conversion yet 16->32 kind=%u msg=%u\n", thunk
->kind
, msg
);
1001 ret
= MMSYSERR_ERROR
;
1003 case MMSYSTEM_MAP_OK
:
1004 case MMSYSTEM_MAP_OKMEM
:
1005 TRACE("Calling message(msg=%u p1=0x%08lx p2=0x%08lx)\n",
1006 msg
, param1
, param2
);
1007 switch (thunk
->kind
)
1009 case MMSYSTDRV_MIXER
: ret
= mixerMessage (h
, msg
, param1
, param2
); break;
1010 case MMSYSTDRV_MIDIIN
:
1013 case MIDM_ADDBUFFER
: ret
= midiInAddBuffer(h
, (LPMIDIHDR
)param1
, param2
); break;
1014 case MIDM_PREPARE
: ret
= midiInPrepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
1015 case MIDM_UNPREPARE
: ret
= midiInUnprepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
1016 default: ret
= midiInMessage(h
, msg
, param1
, param2
); break;
1019 case MMSYSTDRV_MIDIOUT
:
1022 case MODM_PREPARE
: ret
= midiOutPrepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
1023 case MODM_UNPREPARE
: ret
= midiOutUnprepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
1024 case MODM_LONGDATA
: ret
= midiOutLongMsg(h
, (LPMIDIHDR
)param1
, param2
); break;
1025 default: ret
= midiOutMessage(h
, msg
, param1
, param2
); break;
1028 case MMSYSTDRV_WAVEIN
:
1031 case WIDM_ADDBUFFER
: ret
= waveInAddBuffer(h
, (LPWAVEHDR
)param1
, param2
); break;
1032 case WIDM_PREPARE
: ret
= waveInPrepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1033 case WIDM_UNPREPARE
: ret
= waveInUnprepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1034 default: ret
= waveInMessage(h
, msg
, param1
, param2
); break;
1037 case MMSYSTDRV_WAVEOUT
:
1040 case WODM_PREPARE
: ret
= waveOutPrepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1041 case WODM_UNPREPARE
: ret
= waveOutUnprepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1042 case WODM_WRITE
: ret
= waveOutWrite(h
, (LPWAVEHDR
)param1
, param2
); break;
1043 default: ret
= waveOutMessage(h
, msg
, param1
, param2
); break;
1046 default: ret
= MMSYSERR_INVALHANDLE
; break; /* should never be reached */
1048 if (map
== MMSYSTEM_MAP_OKMEM
)
1049 drvtype
->unmapmsg16to32W(msg
, ¶m1
, ¶m2
, ret
);
1053 ret
= MMSYSERR_NOTSUPPORTED
;