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"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(winmm
);
35 /* =================================
37 * ================================= */
39 /* =================================
40 * M I X E R M A P P E R S
41 * ================================= */
43 /**************************************************************************
44 * MMSYSTDRV_Mixer_Map16To32W [internal]
46 static MMSYSTEM_MapType
MMSYSTDRV_Mixer_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
48 return MMSYSTEM_MAP_MSGERROR
;
51 /**************************************************************************
52 * MMSYSTDRV_Mixer_UnMap16To32W [internal]
54 static MMSYSTEM_MapType
MMSYSTDRV_Mixer_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
58 UINT ret
= mixerGetDevCapsA(devid
, &micA
, sizeof(micA
));
60 if (ret
== MMSYSERR_NOERROR
) {
61 mixcaps
->wMid
= micA
.wMid
;
62 mixcaps
->wPid
= micA
.wPid
;
63 mixcaps
->vDriverVersion
= micA
.vDriverVersion
;
64 strcpy(mixcaps
->szPname
, micA
.szPname
);
65 mixcaps
->fdwSupport
= micA
.fdwSupport
;
66 mixcaps
->cDestinations
= micA
.cDestinations
;
70 return MMSYSTEM_MAP_MSGERROR
;
73 /**************************************************************************
74 * MMSYSTDRV_Mixer_MapCB
76 static void MMSYSTDRV_Mixer_MapCB(DWORD uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
81 /* =================================
82 * M I D I I N M A P P E R S
83 * ================================= */
85 /**************************************************************************
86 * MMSYSTDRV_MidiIn_Map16To32W [internal]
88 static MMSYSTEM_MapType
MMSYSTDRV_MidiIn_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
90 return MMSYSTEM_MAP_MSGERROR
;
93 /**************************************************************************
94 * MMSYSTDRV_MidiIn_UnMap16To32W [internal]
96 static MMSYSTEM_MapType
MMSYSTDRV_MidiIn_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
98 return MMSYSTEM_MAP_MSGERROR
;
101 /**************************************************************************
102 * MMSYSTDRV_MidiIn_MapCB [internal]
104 static void MMSYSTDRV_MidiIn_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
109 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
114 /* dwParam1 & dwParam2 are data, nothing to do */
119 LPMIDIHDR mh32
= (LPMIDIHDR
)(*dwParam1
);
120 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
121 LPMIDIHDR mh16
= MapSL(segmh16
);
123 *dwParam1
= (DWORD
)segmh16
;
124 mh16
->dwFlags
= mh32
->dwFlags
;
125 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
126 if (mh16
->reserved
>= sizeof(MIDIHDR
))
127 mh16
->dwOffset
= mh32
->dwOffset
;
131 ERR("Unknown msg %u\n", uMsg
);
135 /* =================================
136 * M I D I O U T M A P P E R S
137 * ================================= */
139 /**************************************************************************
140 * MMSYSTDRV_MidiOut_Map16To32W [internal]
142 static MMSYSTEM_MapType
MMSYSTDRV_MidiOut_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
144 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
147 case MODM_GETNUMDEVS
:
151 ret
= MMSYSTEM_MAP_OK
;
157 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
160 case MODM_GETDEVCAPS
:
162 LPMIDIOUTCAPSW moc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16
) + sizeof(MIDIOUTCAPSW
));
163 LPMIDIOUTCAPS16 moc16
= MapSL(*lpParam1
);
166 *(LPMIDIOUTCAPS16
*)moc32
= moc16
;
167 moc32
= (LPMIDIOUTCAPSW
)((LPSTR
)moc32
+ sizeof(LPMIDIOUTCAPS16
));
168 *lpParam1
= (DWORD
)moc32
;
169 *lpParam2
= sizeof(MIDIOUTCAPSW
);
171 ret
= MMSYSTEM_MAP_OKMEM
;
173 ret
= MMSYSTEM_MAP_NOMEM
;
179 LPMIDIHDR mh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
));
180 LPMIDIHDR mh16
= MapSL(*lpParam1
);
183 *(LPMIDIHDR
*)mh32
= (LPMIDIHDR
)*lpParam1
;
184 mh32
= (LPMIDIHDR
)((LPSTR
)mh32
+ sizeof(LPMIDIHDR
));
185 mh32
->lpData
= MapSL((SEGPTR
)mh16
->lpData
);
186 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
187 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
188 mh32
->dwUser
= mh16
->dwUser
;
189 mh32
->dwFlags
= mh16
->dwFlags
;
190 /* FIXME: nothing on mh32->lpNext */
191 /* could link the mh32->lpNext at this level for memory house keeping */
192 mh32
->dwOffset
= (*lpParam2
>= sizeof(MIDIHDR
)) ? mh16
->dwOffset
: 0;
193 mh16
->lpNext
= mh32
; /* for reuse in unprepare and write */
194 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
195 mh16
->reserved
= *lpParam2
;
196 *lpParam1
= (DWORD
)mh32
;
197 *lpParam2
= sizeof(MIDIHDR
);
199 ret
= MMSYSTEM_MAP_OKMEM
;
201 ret
= MMSYSTEM_MAP_NOMEM
;
208 LPMIDIHDR mh16
= MapSL(*lpParam1
);
209 LPMIDIHDR mh32
= mh16
->lpNext
;
211 *lpParam1
= (DWORD
)mh32
;
212 *lpParam2
= sizeof(MIDIHDR
);
213 /* dwBufferLength can be reduced between prepare & write */
214 if (wMsg
== MODM_LONGDATA
&& mh32
->dwBufferLength
< mh16
->dwBufferLength
) {
215 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
216 mh32
->dwBufferLength
, mh16
->dwBufferLength
);
218 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
219 ret
= MMSYSTEM_MAP_OKMEM
;
223 case MODM_CACHEPATCHES
:
224 case MODM_CACHEDRUMPATCHES
:
226 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
232 /**************************************************************************
233 * MMSYSTDRV_MidiOut_UnMap16To32W [internal]
235 static MMSYSTEM_MapType
MMSYSTDRV_MidiOut_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
237 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
240 case MODM_GETNUMDEVS
:
244 ret
= MMSYSTEM_MAP_OK
;
250 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
253 case MODM_GETDEVCAPS
:
255 LPMIDIOUTCAPSW moc32
= (LPMIDIOUTCAPSW
)(*lpParam1
);
256 LPMIDIOUTCAPS16 moc16
= *(LPMIDIOUTCAPS16
*)((LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
258 moc16
->wMid
= moc32
->wMid
;
259 moc16
->wPid
= moc32
->wPid
;
260 moc16
->vDriverVersion
= moc32
->vDriverVersion
;
261 WideCharToMultiByte( CP_ACP
, 0, moc32
->szPname
, -1, moc16
->szPname
,
262 sizeof(moc16
->szPname
), NULL
, NULL
);
263 moc16
->wTechnology
= moc32
->wTechnology
;
264 moc16
->wVoices
= moc32
->wVoices
;
265 moc16
->wNotes
= moc32
->wNotes
;
266 moc16
->wChannelMask
= moc32
->wChannelMask
;
267 moc16
->dwSupport
= moc32
->dwSupport
;
268 HeapFree(GetProcessHeap(), 0, (LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
269 ret
= MMSYSTEM_MAP_OK
;
276 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
277 LPMIDIHDR mh16
= MapSL(*(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
)));
279 assert(mh16
->lpNext
== mh32
);
280 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
281 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
282 mh16
->dwUser
= mh32
->dwUser
;
283 mh16
->dwFlags
= mh32
->dwFlags
;
284 if (mh16
->reserved
>= sizeof(MIDIHDR
))
285 mh16
->dwOffset
= mh32
->dwOffset
;
287 if (wMsg
== MODM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
288 HeapFree(GetProcessHeap(), 0, (LPSTR
)mh32
- sizeof(LPMIDIHDR
));
291 ret
= MMSYSTEM_MAP_OK
;
295 case MODM_CACHEPATCHES
:
296 case MODM_CACHEDRUMPATCHES
:
298 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
304 /******************************************************************
305 * MMSYSTDRV_MidiOut_MapCB
307 static void MMSYSTDRV_MidiOut_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
312 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
316 /* initial map is: 16 => 32 */
317 LPMIDIHDR mh32
= (LPMIDIHDR
)(*dwParam1
);
318 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
319 LPMIDIHDR mh16
= MapSL(segmh16
);
321 *dwParam1
= (DWORD
)segmh16
;
322 mh16
->dwFlags
= mh32
->dwFlags
;
323 if (mh16
->reserved
>= sizeof(MIDIHDR
))
324 mh16
->dwOffset
= mh32
->dwOffset
;
329 /* FIXME: would require to recreate a 16bit MIDIHDR here */
330 *dwParam1
= *dwParam2
= 0;
333 ERR("Unknown msg %u\n", uMsg
);
337 /* =================================
338 * W A V E I N M A P P E R S
339 * ================================= */
341 /**************************************************************************
342 * MMSYSTDRV_WaveIn_Map16To32W [internal]
344 static MMSYSTEM_MapType
MMSYSTDRV_WaveIn_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
346 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
349 case WIDM_GETNUMDEVS
:
353 ret
= MMSYSTEM_MAP_OK
;
357 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
359 case WIDM_GETDEVCAPS
:
361 LPWAVEINCAPSW wic32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16
) + sizeof(WAVEINCAPSW
));
362 LPWAVEINCAPS16 wic16
= MapSL(*lpParam1
);
365 *(LPWAVEINCAPS16
*)wic32
= wic16
;
366 wic32
= (LPWAVEINCAPSW
)((LPSTR
)wic32
+ sizeof(LPWAVEINCAPS16
));
367 *lpParam1
= (DWORD
)wic32
;
368 *lpParam2
= sizeof(WAVEINCAPSW
);
370 ret
= MMSYSTEM_MAP_OKMEM
;
372 ret
= MMSYSTEM_MAP_NOMEM
;
378 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
379 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
382 *(LPMMTIME16
*)mmt32
= mmt16
;
383 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
385 mmt32
->wType
= mmt16
->wType
;
386 *lpParam1
= (DWORD
)mmt32
;
387 *lpParam2
= sizeof(MMTIME
);
389 ret
= MMSYSTEM_MAP_OKMEM
;
391 ret
= MMSYSTEM_MAP_NOMEM
;
397 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
398 LPWAVEHDR wh16
= MapSL(*lpParam1
);
401 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
402 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
403 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
404 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
405 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
406 wh32
->dwUser
= wh16
->dwUser
;
407 wh32
->dwFlags
= wh16
->dwFlags
;
408 wh32
->dwLoops
= wh16
->dwLoops
;
409 /* FIXME: nothing on wh32->lpNext */
410 /* could link the wh32->lpNext at this level for memory house keeping */
411 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
412 *lpParam1
= (DWORD
)wh32
;
413 *lpParam2
= sizeof(WAVEHDR
);
415 ret
= MMSYSTEM_MAP_OKMEM
;
417 ret
= MMSYSTEM_MAP_NOMEM
;
424 LPWAVEHDR wh16
= MapSL(*lpParam1
);
425 LPWAVEHDR wh32
= wh16
->lpNext
;
427 *lpParam1
= (DWORD
)wh32
;
428 *lpParam2
= sizeof(WAVEHDR
);
429 /* dwBufferLength can be reduced between prepare & write */
430 if (wMsg
== WIDM_ADDBUFFER
&& wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
431 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
432 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
434 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
435 ret
= MMSYSTEM_MAP_OKMEM
;
438 case WIDM_MAPPER_STATUS
:
439 /* just a single DWORD */
440 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
441 ret
= MMSYSTEM_MAP_OK
;
444 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
450 /**************************************************************************
451 * MMSYSTDRV_WaveIn_UnMap16To32W [internal]
453 static MMSYSTEM_MapType
MMSYSTDRV_WaveIn_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
455 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
458 case WIDM_GETNUMDEVS
:
462 case WIDM_MAPPER_STATUS
:
463 ret
= MMSYSTEM_MAP_OK
;
467 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
469 case WIDM_GETDEVCAPS
:
471 LPWAVEINCAPSW wic32
= (LPWAVEINCAPSW
)(*lpParam1
);
472 LPWAVEINCAPS16 wic16
= *(LPWAVEINCAPS16
*)((LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
474 wic16
->wMid
= wic32
->wMid
;
475 wic16
->wPid
= wic32
->wPid
;
476 wic16
->vDriverVersion
= wic32
->vDriverVersion
;
477 WideCharToMultiByte( CP_ACP
, 0, wic32
->szPname
, -1, wic16
->szPname
,
478 sizeof(wic16
->szPname
), NULL
, NULL
);
479 wic16
->dwFormats
= wic32
->dwFormats
;
480 wic16
->wChannels
= wic32
->wChannels
;
481 HeapFree(GetProcessHeap(), 0, (LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
482 ret
= MMSYSTEM_MAP_OK
;
487 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
488 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
490 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
491 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
492 ret
= MMSYSTEM_MAP_OK
;
499 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
500 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
502 assert(wh16
->lpNext
== wh32
);
503 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
504 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
505 wh16
->dwUser
= wh32
->dwUser
;
506 wh16
->dwFlags
= wh32
->dwFlags
;
507 wh16
->dwLoops
= wh32
->dwLoops
;
509 if (wMsg
== WIDM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
510 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
513 ret
= MMSYSTEM_MAP_OK
;
517 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
523 /**************************************************************************
524 * MMSYSTDRV_WaveIn_MapCB [internal]
526 static void MMSYSTDRV_WaveIn_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
531 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
535 /* initial map is: 16 => 32 */
536 LPWAVEHDR wh32
= (LPWAVEHDR
)(*dwParam1
);
537 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
538 LPWAVEHDR wh16
= MapSL(segwh16
);
540 *dwParam1
= (DWORD
)segwh16
;
541 wh16
->dwFlags
= wh32
->dwFlags
;
542 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
546 ERR("Unknown msg %u\n", uMsg
);
550 /* =================================
551 * W A V E O U T M A P P E R S
552 * ================================= */
554 /**************************************************************************
555 * MMSYSTDRV_WaveOut_Map16To32W [internal]
557 static MMSYSTEM_MapType
MMSYSTDRV_WaveOut_Map16To32W (UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
)
559 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
565 case WODM_GETNUMDEVS
:
570 case WODM_SETPLAYBACKRATE
:
572 ret
= MMSYSTEM_MAP_OK
;
576 case WODM_GETPLAYBACKRATE
:
579 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
582 case WODM_GETDEVCAPS
:
584 LPWAVEOUTCAPSW woc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16
) + sizeof(WAVEOUTCAPSW
));
585 LPWAVEOUTCAPS16 woc16
= MapSL(*lpParam1
);
588 *(LPWAVEOUTCAPS16
*)woc32
= woc16
;
589 woc32
= (LPWAVEOUTCAPSW
)((LPSTR
)woc32
+ sizeof(LPWAVEOUTCAPS16
));
590 *lpParam1
= (DWORD
)woc32
;
591 *lpParam2
= sizeof(WAVEOUTCAPSW
);
593 ret
= MMSYSTEM_MAP_OKMEM
;
595 ret
= MMSYSTEM_MAP_NOMEM
;
601 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
602 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
605 *(LPMMTIME16
*)mmt32
= mmt16
;
606 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
608 mmt32
->wType
= mmt16
->wType
;
609 *lpParam1
= (DWORD
)mmt32
;
610 *lpParam2
= sizeof(MMTIME
);
612 ret
= MMSYSTEM_MAP_OKMEM
;
614 ret
= MMSYSTEM_MAP_NOMEM
;
620 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
621 LPWAVEHDR wh16
= MapSL(*lpParam1
);
624 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
625 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
626 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
627 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
628 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
629 wh32
->dwUser
= wh16
->dwUser
;
630 wh32
->dwFlags
= wh16
->dwFlags
;
631 wh32
->dwLoops
= wh16
->dwLoops
;
632 /* FIXME: nothing on wh32->lpNext */
633 /* could link the wh32->lpNext at this level for memory house keeping */
634 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
635 *lpParam1
= (DWORD
)wh32
;
636 *lpParam2
= sizeof(WAVEHDR
);
638 ret
= MMSYSTEM_MAP_OKMEM
;
640 ret
= MMSYSTEM_MAP_NOMEM
;
647 LPWAVEHDR wh16
= MapSL(*lpParam1
);
648 LPWAVEHDR wh32
= wh16
->lpNext
;
650 *lpParam1
= (DWORD
)wh32
;
651 *lpParam2
= sizeof(WAVEHDR
);
652 /* dwBufferLength can be reduced between prepare & write */
653 if (wMsg
== WODM_WRITE
&& wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
654 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
655 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
657 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
658 ret
= MMSYSTEM_MAP_OKMEM
;
661 case WODM_MAPPER_STATUS
:
662 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
663 ret
= MMSYSTEM_MAP_OK
;
666 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
672 /**************************************************************************
673 * MMSYSTDRV_WaveOut_UnMap16To32W [internal]
675 static MMSYSTEM_MapType
MMSYSTDRV_WaveOut_UnMap16To32W(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT fn_ret
)
677 MMSYSTEM_MapType ret
= MMSYSTEM_MAP_MSGERROR
;
683 case WODM_GETNUMDEVS
:
688 case WODM_SETPLAYBACKRATE
:
690 case WODM_MAPPER_STATUS
:
691 ret
= MMSYSTEM_MAP_OK
;
695 case WODM_GETPLAYBACKRATE
:
698 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
701 case WODM_GETDEVCAPS
:
703 LPWAVEOUTCAPSW woc32
= (LPWAVEOUTCAPSW
)(*lpParam1
);
704 LPWAVEOUTCAPS16 woc16
= *(LPWAVEOUTCAPS16
*)((LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
706 woc16
->wMid
= woc32
->wMid
;
707 woc16
->wPid
= woc32
->wPid
;
708 woc16
->vDriverVersion
= woc32
->vDriverVersion
;
709 WideCharToMultiByte( CP_ACP
, 0, woc32
->szPname
, -1, woc16
->szPname
,
710 sizeof(woc16
->szPname
), NULL
, NULL
);
711 woc16
->dwFormats
= woc32
->dwFormats
;
712 woc16
->wChannels
= woc32
->wChannels
;
713 woc16
->dwSupport
= woc32
->dwSupport
;
714 HeapFree(GetProcessHeap(), 0, (LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
715 ret
= MMSYSTEM_MAP_OK
;
720 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
721 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
723 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
724 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
725 ret
= MMSYSTEM_MAP_OK
;
732 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
733 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
735 assert(wh16
->lpNext
== wh32
);
736 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
737 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
738 wh16
->dwUser
= wh32
->dwUser
;
739 wh16
->dwFlags
= wh32
->dwFlags
;
740 wh16
->dwLoops
= wh32
->dwLoops
;
742 if (wMsg
== WODM_UNPREPARE
&& fn_ret
== MMSYSERR_NOERROR
) {
743 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
746 ret
= MMSYSTEM_MAP_OK
;
750 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
756 /**************************************************************************
757 * MMDRV_WaveOut_Callback [internal]
759 static void MMSYSTDRV_WaveOut_MapCB(UINT uMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
)
764 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
768 /* initial map is: 16 => 32 */
769 LPWAVEHDR wh32
= (LPWAVEHDR
)(*dwParam1
);
770 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
771 LPWAVEHDR wh16
= MapSL(segwh16
);
773 *dwParam1
= (DWORD
)segwh16
;
774 wh16
->dwFlags
= wh32
->dwFlags
;
778 ERR("Unknown msg %u\n", uMsg
);
782 /* ###################################################
783 * # DRIVER THUNKING #
784 * ###################################################
786 typedef MMSYSTEM_MapType (*MMSYSTDRV_MAPMSG
)(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
);
787 typedef MMSYSTEM_MapType (*MMSYSTDRV_UNMAPMSG
)(UINT wMsg
, DWORD_PTR
* lpParam1
, DWORD_PTR
* lpParam2
, MMRESULT ret
);
788 typedef void (*MMSYSTDRV_MAPCB
)(DWORD wMsg
, DWORD_PTR
* dwUser
, DWORD_PTR
* dwParam1
, DWORD_PTR
* dwParam2
);
790 #include <pshpack1.h>
791 #define MMSYSTDRV_MAX_THUNKS 32
793 static struct mmsystdrv_thunk
795 BYTE popl_eax
; /* popl %eax (return address) */
796 BYTE pushl_this
; /* pushl this (this very thunk) */
797 struct mmsystdrv_thunk
* this;
798 BYTE pushl_eax
; /* pushl %eax */
799 BYTE jmp
; /* ljmp MMDRV_Callback1632 */
801 DWORD pfn16
; /* 16bit callback function */
802 void* hMmdrv
; /* Handle to 32bit mmdrv object */
803 enum MMSYSTEM_DriverType kind
;
808 static struct MMSYSTDRV_Type
810 MMSYSTDRV_MAPMSG mapmsg16to32W
;
811 MMSYSTDRV_UNMAPMSG unmapmsg16to32W
;
812 MMSYSTDRV_MAPCB mapcb
;
813 } MMSYSTEM_DriversType
[MMSYSTDRV_MAX
] =
815 {MMSYSTDRV_Mixer_Map16To32W
, MMSYSTDRV_Mixer_UnMap16To32W
, MMSYSTDRV_Mixer_MapCB
},
816 {MMSYSTDRV_MidiIn_Map16To32W
, MMSYSTDRV_MidiIn_UnMap16To32W
, MMSYSTDRV_MidiIn_MapCB
},
817 {MMSYSTDRV_MidiOut_Map16To32W
, MMSYSTDRV_MidiOut_UnMap16To32W
, MMSYSTDRV_MidiOut_MapCB
},
818 {MMSYSTDRV_WaveIn_Map16To32W
, MMSYSTDRV_WaveIn_UnMap16To32W
, MMSYSTDRV_WaveIn_MapCB
},
819 {MMSYSTDRV_WaveOut_Map16To32W
, MMSYSTDRV_WaveOut_UnMap16To32W
, MMSYSTDRV_WaveOut_MapCB
},
822 /******************************************************************
823 * MMSYSTDRV_Callback3216
826 static LRESULT CALLBACK
MMSYSTDRV_Callback3216(struct mmsystdrv_thunk
* thunk
, HDRVR hDev
,
827 DWORD wMsg
, DWORD_PTR dwUser
, DWORD_PTR dwParam1
,
832 assert(thunk
->kind
< MMSYSTDRV_MAX
);
833 assert(MMSYSTEM_DriversType
[thunk
->kind
].mapcb
);
835 MMSYSTEM_DriversType
[thunk
->kind
].mapcb(wMsg
, &dwUser
, &dwParam1
, &dwParam2
);
837 /* 16 bit func, call it */
838 TRACE("Function (16 bit) %x!\n", thunk
->pfn16
);
840 args
[7] = HDRVR_16(hDev
);
842 args
[5] = HIWORD(dwUser
);
843 args
[4] = LOWORD(dwUser
);
844 args
[3] = HIWORD(dwParam1
);
845 args
[2] = LOWORD(dwParam1
);
846 args
[1] = HIWORD(dwParam2
);
847 args
[0] = LOWORD(dwParam2
);
848 return WOWCallback16Ex(thunk
->pfn16
, WCB16_PASCAL
, sizeof(args
), args
, NULL
);
851 /******************************************************************
855 struct mmsystdrv_thunk
* MMSYSTDRV_AddThunk(DWORD pfn16
, enum MMSYSTEM_DriverType kind
)
857 struct mmsystdrv_thunk
* thunk
;
859 EnterCriticalSection(&mmdrv_cs
);
860 if (!MMSYSTDRV_Thunks
)
862 MMSYSTDRV_Thunks
= VirtualAlloc(NULL
, MMSYSTDRV_MAX_THUNKS
* sizeof(*MMSYSTDRV_Thunks
),
863 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
864 if (!MMSYSTDRV_Thunks
)
866 LeaveCriticalSection(&mmdrv_cs
);
869 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
871 thunk
->popl_eax
= 0x58; /* popl %eax */
872 thunk
->pushl_this
= 0x68; /* pushl this */
874 thunk
->pushl_eax
= 0x50; /* pushl %eax */
875 thunk
->jmp
= 0xe9; /* jmp MMDRV_Callback3216 */
876 thunk
->callback
= (char *)MMSYSTDRV_Callback3216
- (char *)(&thunk
->callback
+ 1);
878 thunk
->hMmdrv
= NULL
;
879 thunk
->kind
= MMSYSTDRV_MAX
;
882 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
884 if (thunk
->pfn16
== 0 && thunk
->hMmdrv
== NULL
)
886 thunk
->pfn16
= pfn16
;
887 thunk
->hMmdrv
= NULL
;
889 LeaveCriticalSection(&mmdrv_cs
);
893 LeaveCriticalSection(&mmdrv_cs
);
894 FIXME("Out of mmdrv-thunks. Bump MMDRV_MAX_THUNKS\n");
898 /******************************************************************
899 * MMSYSTDRV_FindHandle
901 * Must be called with lock set
903 static void* MMSYSTDRV_FindHandle(void* h
)
905 struct mmsystdrv_thunk
* thunk
;
907 for (thunk
= MMSYSTDRV_Thunks
; thunk
< &MMSYSTDRV_Thunks
[MMSYSTDRV_MAX_THUNKS
]; thunk
++)
909 if (thunk
->hMmdrv
== h
)
911 if (thunk
->kind
>= MMSYSTDRV_MAX
) FIXME("Kind isn't properly initialized %x\n", thunk
->kind
);
918 /******************************************************************
919 * MMSYSTDRV_SetHandle
922 void MMSYSTDRV_SetHandle(struct mmsystdrv_thunk
* thunk
, void* h
)
924 if (MMSYSTDRV_FindHandle(h
)) FIXME("Already has a thunk for this handle %p!!!\n", h
);
928 /******************************************************************
929 * MMSYSTDRV_DeleteThunk
931 void MMSYSTDRV_DeleteThunk(struct mmsystdrv_thunk
* thunk
)
934 thunk
->hMmdrv
= NULL
;
935 thunk
->kind
= MMSYSTDRV_MAX
;
938 /******************************************************************
939 * MMSYSTDRV_CloseHandle
941 void MMSYSTDRV_CloseHandle(void* h
)
943 struct mmsystdrv_thunk
* thunk
;
945 EnterCriticalSection(&mmdrv_cs
);
946 if ((thunk
= MMSYSTDRV_FindHandle(h
)))
948 MMSYSTDRV_DeleteThunk(thunk
);
950 LeaveCriticalSection(&mmdrv_cs
);
953 /******************************************************************
956 DWORD
MMSYSTDRV_Message(void* h
, UINT msg
, DWORD_PTR param1
, DWORD_PTR param2
)
958 struct mmsystdrv_thunk
* thunk
= MMSYSTDRV_FindHandle(h
);
959 struct MMSYSTDRV_Type
* drvtype
;
960 MMSYSTEM_MapType map
;
963 if (!thunk
) return MMSYSERR_INVALHANDLE
;
964 drvtype
= &MMSYSTEM_DriversType
[thunk
->kind
];
966 map
= drvtype
->mapmsg16to32W(msg
, ¶m1
, ¶m2
);
968 case MMSYSTEM_MAP_NOMEM
:
969 ret
= MMSYSERR_NOMEM
;
971 case MMSYSTEM_MAP_MSGERROR
:
972 FIXME("NIY: no conversion yet 16->32 kind=%u msg=%u\n", thunk
->kind
, msg
);
973 ret
= MMSYSERR_ERROR
;
975 case MMSYSTEM_MAP_OK
:
976 case MMSYSTEM_MAP_OKMEM
:
977 TRACE("Calling message(msg=%u p1=0x%08lx p2=0x%08lx)\n",
978 msg
, param1
, param2
);
981 case MMSYSTDRV_MIXER
: ret
= mixerMessage (h
, msg
, param1
, param2
); break;
982 case MMSYSTDRV_MIDIIN
:
985 case MIDM_ADDBUFFER
: ret
= midiInAddBuffer(h
, (LPMIDIHDR
)param1
, param2
); break;
986 case MIDM_PREPARE
: ret
= midiInPrepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
987 case MIDM_UNPREPARE
: ret
= midiInUnprepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
988 default: ret
= midiInMessage(h
, msg
, param1
, param2
); break;
991 case MMSYSTDRV_MIDIOUT
:
994 case MODM_PREPARE
: ret
= midiOutPrepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
995 case MODM_UNPREPARE
: ret
= midiOutUnprepareHeader(h
, (LPMIDIHDR
)param1
, param2
); break;
996 case MODM_LONGDATA
: ret
= midiOutLongMsg(h
, (LPMIDIHDR
)param1
, param2
); break;
997 default: ret
= midiOutMessage(h
, msg
, param1
, param2
); break;
1000 case MMSYSTDRV_WAVEIN
:
1003 case WIDM_ADDBUFFER
: ret
= waveInAddBuffer(h
, (LPWAVEHDR
)param1
, param2
); break;
1004 case WIDM_PREPARE
: ret
= waveInPrepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1005 case WIDM_UNPREPARE
: ret
= waveInUnprepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1006 default: ret
= waveInMessage(h
, msg
, param1
, param2
); break;
1009 case MMSYSTDRV_WAVEOUT
:
1012 case WODM_PREPARE
: ret
= waveOutPrepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1013 case WODM_UNPREPARE
: ret
= waveOutUnprepareHeader(h
, (LPWAVEHDR
)param1
, param2
); break;
1014 case WODM_WRITE
: ret
= waveOutWrite(h
, (LPWAVEHDR
)param1
, param2
); break;
1015 default: ret
= waveOutMessage(h
, msg
, param1
, param2
); break;
1018 default: ret
= MMSYSERR_INVALHANDLE
; break; /* should never be reached */
1020 if (map
== MMSYSTEM_MAP_OKMEM
)
1021 drvtype
->unmapmsg16to32W(msg
, ¶m1
, ¶m2
, ret
);
1025 ret
= MMSYSERR_NOTSUPPORTED
;