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 %lx\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;