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;