Release 1.1.37.
[wine/gsoc-2012-control.git] / dlls / mmsystem.dll16 / message16.c
blobce25b9cd714267e97ba217df9cf027b73dedc092
1 /*
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
21 #include <string.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #include "wine/winbase16.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wownt32.h"
29 #include "winemm16.h"
30 #include "digitalv.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(winmm);
35 /* =================================
36 * A U X M A P P E R S
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)
56 #if 0
57 MIXERCAPSA micA;
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;
68 return ret;
69 #endif
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)
78 FIXME("NIY\n");
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)
106 switch (uMsg) {
107 case MIM_OPEN:
108 case MIM_CLOSE:
109 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
111 case MIM_DATA:
112 case MIM_MOREDATA:
113 case MIM_ERROR:
114 /* dwParam1 & dwParam2 are data, nothing to do */
115 break;
116 case MIM_LONGDATA:
117 case MIM_LONGERROR:
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;
129 break;
130 default:
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;
146 switch (wMsg) {
147 case MODM_GETNUMDEVS:
148 case MODM_DATA:
149 case MODM_RESET:
150 case MODM_SETVOLUME:
151 ret = MMSYSTEM_MAP_OK;
152 break;
154 case MODM_OPEN:
155 case MODM_CLOSE:
156 case MODM_GETVOLUME:
157 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
158 break;
160 case MODM_GETDEVCAPS:
162 LPMIDIOUTCAPSW moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSW));
163 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
165 if (moc32) {
166 *(LPMIDIOUTCAPS16*)moc32 = moc16;
167 moc32 = (LPMIDIOUTCAPSW)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
168 *lpParam1 = (DWORD)moc32;
169 *lpParam2 = sizeof(MIDIOUTCAPSW);
171 ret = MMSYSTEM_MAP_OKMEM;
172 } else {
173 ret = MMSYSTEM_MAP_NOMEM;
176 break;
177 case MODM_PREPARE:
179 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
180 LPMIDIHDR mh16 = MapSL(*lpParam1);
182 if (mh32) {
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;
200 } else {
201 ret = MMSYSTEM_MAP_NOMEM;
204 break;
205 case MODM_UNPREPARE:
206 case MODM_LONGDATA:
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);
217 } else
218 mh32->dwBufferLength = mh16->dwBufferLength;
219 ret = MMSYSTEM_MAP_OKMEM;
221 break;
223 case MODM_CACHEPATCHES:
224 case MODM_CACHEDRUMPATCHES:
225 default:
226 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
227 break;
229 return ret;
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;
239 switch (wMsg) {
240 case MODM_GETNUMDEVS:
241 case MODM_DATA:
242 case MODM_RESET:
243 case MODM_SETVOLUME:
244 ret = MMSYSTEM_MAP_OK;
245 break;
247 case MODM_OPEN:
248 case MODM_CLOSE:
249 case MODM_GETVOLUME:
250 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
251 break;
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;
271 break;
272 case MODM_PREPARE:
273 case MODM_UNPREPARE:
274 case MODM_LONGDATA:
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));
289 mh16->lpNext = 0;
291 ret = MMSYSTEM_MAP_OK;
293 break;
295 case MODM_CACHEPATCHES:
296 case MODM_CACHEDRUMPATCHES:
297 default:
298 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
299 break;
301 return ret;
304 /******************************************************************
305 * MMSYSTDRV_MidiOut_MapCB
307 static void MMSYSTDRV_MidiOut_MapCB(UINT uMsg, DWORD_PTR* dwUser, DWORD_PTR* dwParam1, DWORD_PTR* dwParam2)
309 switch (uMsg) {
310 case MOM_OPEN:
311 case MOM_CLOSE:
312 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
313 break;
314 case MOM_DONE:
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;
326 break;
327 case MOM_POSITIONCB:
328 FIXME("NIY\n");
329 /* FIXME: would require to recreate a 16bit MIDIHDR here */
330 *dwParam1 = *dwParam2 = 0;
331 break;
332 default:
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;
348 switch (wMsg) {
349 case WIDM_GETNUMDEVS:
350 case WIDM_RESET:
351 case WIDM_START:
352 case WIDM_STOP:
353 ret = MMSYSTEM_MAP_OK;
354 break;
355 case WIDM_OPEN:
356 case WIDM_CLOSE:
357 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
358 break;
359 case WIDM_GETDEVCAPS:
361 LPWAVEINCAPSW wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSW));
362 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
364 if (wic32) {
365 *(LPWAVEINCAPS16*)wic32 = wic16;
366 wic32 = (LPWAVEINCAPSW)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
367 *lpParam1 = (DWORD)wic32;
368 *lpParam2 = sizeof(WAVEINCAPSW);
370 ret = MMSYSTEM_MAP_OKMEM;
371 } else {
372 ret = MMSYSTEM_MAP_NOMEM;
375 break;
376 case WIDM_GETPOS:
378 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
379 LPMMTIME16 mmt16 = MapSL(*lpParam1);
381 if (mmt32) {
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;
390 } else {
391 ret = MMSYSTEM_MAP_NOMEM;
394 break;
395 case WIDM_PREPARE:
397 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
398 LPWAVEHDR wh16 = MapSL(*lpParam1);
400 if (wh32) {
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;
416 } else {
417 ret = MMSYSTEM_MAP_NOMEM;
420 break;
421 case WIDM_ADDBUFFER:
422 case WIDM_UNPREPARE:
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);
433 } else
434 wh32->dwBufferLength = wh16->dwBufferLength;
435 ret = MMSYSTEM_MAP_OKMEM;
437 break;
438 case WIDM_MAPPER_STATUS:
439 /* just a single DWORD */
440 *lpParam2 = (DWORD)MapSL(*lpParam2);
441 ret = MMSYSTEM_MAP_OK;
442 break;
443 default:
444 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
445 break;
447 return ret;
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;
457 switch (wMsg) {
458 case WIDM_GETNUMDEVS:
459 case WIDM_RESET:
460 case WIDM_START:
461 case WIDM_STOP:
462 case WIDM_MAPPER_STATUS:
463 ret = MMSYSTEM_MAP_OK;
464 break;
465 case WIDM_OPEN:
466 case WIDM_CLOSE:
467 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
468 break;
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;
484 break;
485 case WIDM_GETPOS:
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;
494 break;
495 case WIDM_ADDBUFFER:
496 case WIDM_PREPARE:
497 case WIDM_UNPREPARE:
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));
511 wh16->lpNext = 0;
513 ret = MMSYSTEM_MAP_OK;
515 break;
516 default:
517 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
518 break;
520 return ret;
523 /**************************************************************************
524 * MMSYSTDRV_WaveIn_MapCB [internal]
526 static void MMSYSTDRV_WaveIn_MapCB(UINT uMsg, DWORD_PTR* dwUser, DWORD_PTR* dwParam1, DWORD_PTR* dwParam2)
528 switch (uMsg) {
529 case WIM_OPEN:
530 case WIM_CLOSE:
531 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
532 break;
533 case WIM_DATA:
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;
544 break;
545 default:
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;
561 switch (wMsg) {
562 /* nothing to do */
563 case WODM_BREAKLOOP:
564 case WODM_CLOSE:
565 case WODM_GETNUMDEVS:
566 case WODM_PAUSE:
567 case WODM_RESET:
568 case WODM_RESTART:
569 case WODM_SETPITCH:
570 case WODM_SETPLAYBACKRATE:
571 case WODM_SETVOLUME:
572 ret = MMSYSTEM_MAP_OK;
573 break;
575 case WODM_GETPITCH:
576 case WODM_GETPLAYBACKRATE:
577 case WODM_GETVOLUME:
578 case WODM_OPEN:
579 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
580 break;
582 case WODM_GETDEVCAPS:
584 LPWAVEOUTCAPSW woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSW));
585 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
587 if (woc32) {
588 *(LPWAVEOUTCAPS16*)woc32 = woc16;
589 woc32 = (LPWAVEOUTCAPSW)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
590 *lpParam1 = (DWORD)woc32;
591 *lpParam2 = sizeof(WAVEOUTCAPSW);
593 ret = MMSYSTEM_MAP_OKMEM;
594 } else {
595 ret = MMSYSTEM_MAP_NOMEM;
598 break;
599 case WODM_GETPOS:
601 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
602 LPMMTIME16 mmt16 = MapSL(*lpParam1);
604 if (mmt32) {
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;
613 } else {
614 ret = MMSYSTEM_MAP_NOMEM;
617 break;
618 case WODM_PREPARE:
620 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
621 LPWAVEHDR wh16 = MapSL(*lpParam1);
623 if (wh32) {
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;
639 } else {
640 ret = MMSYSTEM_MAP_NOMEM;
643 break;
644 case WODM_UNPREPARE:
645 case WODM_WRITE:
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);
656 } else
657 wh32->dwBufferLength = wh16->dwBufferLength;
658 ret = MMSYSTEM_MAP_OKMEM;
660 break;
661 case WODM_MAPPER_STATUS:
662 *lpParam2 = (DWORD)MapSL(*lpParam2);
663 ret = MMSYSTEM_MAP_OK;
664 break;
665 default:
666 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
667 break;
669 return ret;
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;
679 switch (wMsg) {
680 /* nothing to do */
681 case WODM_BREAKLOOP:
682 case WODM_CLOSE:
683 case WODM_GETNUMDEVS:
684 case WODM_PAUSE:
685 case WODM_RESET:
686 case WODM_RESTART:
687 case WODM_SETPITCH:
688 case WODM_SETPLAYBACKRATE:
689 case WODM_SETVOLUME:
690 case WODM_MAPPER_STATUS:
691 ret = MMSYSTEM_MAP_OK;
692 break;
694 case WODM_GETPITCH:
695 case WODM_GETPLAYBACKRATE:
696 case WODM_GETVOLUME:
697 case WODM_OPEN:
698 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
699 break;
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;
717 break;
718 case WODM_GETPOS:
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;
727 break;
728 case WODM_PREPARE:
729 case WODM_UNPREPARE:
730 case WODM_WRITE:
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));
744 wh16->lpNext = 0;
746 ret = MMSYSTEM_MAP_OK;
748 break;
749 default:
750 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
751 break;
753 return ret;
756 /**************************************************************************
757 * MMDRV_WaveOut_Callback [internal]
759 static void MMSYSTDRV_WaveOut_MapCB(UINT uMsg, DWORD_PTR* dwUser, DWORD_PTR* dwParam1, DWORD_PTR* dwParam2)
761 switch (uMsg) {
762 case WOM_OPEN:
763 case WOM_CLOSE:
764 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
765 break;
766 case WOM_DONE:
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;
776 break;
777 default:
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 */
800 DWORD callback;
801 DWORD pfn16; /* 16bit callback function */
802 void* hMmdrv; /* Handle to 32bit mmdrv object */
803 enum MMSYSTEM_DriverType kind;
804 } *MMSYSTDRV_Thunks;
806 #include <poppack.h>
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,
828 DWORD_PTR dwParam2)
830 WORD args[8];
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);
841 args[6] = wMsg;
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 /******************************************************************
852 * MMSYSTDRV_AddThunk
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);
867 return NULL;
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 */
873 thunk->this = thunk;
874 thunk->pushl_eax = 0x50; /* pushl %eax */
875 thunk->jmp = 0xe9; /* jmp MMDRV_Callback3216 */
876 thunk->callback = (char *)MMSYSTDRV_Callback3216 - (char *)(&thunk->callback + 1);
877 thunk->pfn16 = 0;
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;
888 thunk->kind = kind;
889 LeaveCriticalSection(&mmdrv_cs);
890 return thunk;
893 LeaveCriticalSection(&mmdrv_cs);
894 FIXME("Out of mmdrv-thunks. Bump MMDRV_MAX_THUNKS\n");
895 return NULL;
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);
912 return thunk;
915 return NULL;
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);
925 thunk->hMmdrv = h;
928 /******************************************************************
929 * MMSYSTDRV_DeleteThunk
931 void MMSYSTDRV_DeleteThunk(struct mmsystdrv_thunk* thunk)
933 thunk->pfn16 = 0;
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 /******************************************************************
954 * MMSYSTDRV_Message
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;
961 DWORD ret;
963 if (!thunk) return MMSYSERR_INVALHANDLE;
964 drvtype = &MMSYSTEM_DriversType[thunk->kind];
966 map = drvtype->mapmsg16to32W(msg, &param1, &param2);
967 switch (map) {
968 case MMSYSTEM_MAP_NOMEM:
969 ret = MMSYSERR_NOMEM;
970 break;
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;
974 break;
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);
979 switch (thunk->kind)
981 case MMSYSTDRV_MIXER: ret = mixerMessage (h, msg, param1, param2); break;
982 case MMSYSTDRV_MIDIIN:
983 switch (msg)
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;
990 break;
991 case MMSYSTDRV_MIDIOUT:
992 switch (msg)
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;
999 break;
1000 case MMSYSTDRV_WAVEIN:
1001 switch (msg)
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;
1008 break;
1009 case MMSYSTDRV_WAVEOUT:
1010 switch (msg)
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;
1017 break;
1018 default: ret = MMSYSERR_INVALHANDLE; break; /* should never be reached */
1020 if (map == MMSYSTEM_MAP_OKMEM)
1021 drvtype->unmapmsg16to32W(msg, &param1, &param2, ret);
1022 break;
1023 default:
1024 FIXME("NIY\n");
1025 ret = MMSYSERR_NOTSUPPORTED;
1026 break;
1028 return ret;