push 8b07bf1f08b23b9893a622b47d2be359556765b1
[wine/hacks.git] / dlls / winmm / message16.c
blob0bbc14afc50b8134f30414328b50708a1e3bfa5d
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 "winemm.h"
30 #include "winemm16.h"
31 #include "digitalv.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(winmm);
36 /**************************************************************************
37 * MMDRV_Callback [internal]
39 static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
41 TRACE("CB (*%08lx)(%p %08x %08lx %08lx %08lx\n",
42 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
44 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION)
46 WORD args[8];
47 /* 16 bit func, call it */
48 TRACE("Function (16 bit) !\n");
50 args[7] = HDRVR_16(hDev);
51 args[6] = uMsg;
52 args[5] = HIWORD(mld->dwClientInstance);
53 args[4] = LOWORD(mld->dwClientInstance);
54 args[3] = HIWORD(dwParam1);
55 args[2] = LOWORD(dwParam1);
56 args[1] = HIWORD(dwParam2);
57 args[0] = LOWORD(dwParam2);
58 WOWCallback16Ex( mld->dwCallback, WCB16_PASCAL, sizeof(args), args, NULL );
59 } else {
60 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
61 mld->dwClientInstance, dwParam1, dwParam2);
65 /* =================================
66 * A U X M A P P E R S
67 * ================================= */
69 /**************************************************************************
70 * MMDRV_Aux_Map16To32W [internal]
72 static WINMM_MapType MMDRV_Aux_Map16To32W (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
74 return WINMM_MAP_MSGERROR;
77 /**************************************************************************
78 * MMDRV_Aux_UnMap16To32W [internal]
80 static WINMM_MapType MMDRV_Aux_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
82 return WINMM_MAP_MSGERROR;
85 /**************************************************************************
86 * MMDRV_Aux_Map32WTo16 [internal]
88 static WINMM_MapType MMDRV_Aux_Map32WTo16 (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
90 return WINMM_MAP_MSGERROR;
93 /**************************************************************************
94 * MMDRV_Aux_UnMap32WTo16 [internal]
96 static WINMM_MapType MMDRV_Aux_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
98 #if 0
99 case AUXDM_GETDEVCAPS:
100 lpCaps->wMid = ac16.wMid;
101 lpCaps->wPid = ac16.wPid;
102 lpCaps->vDriverVersion = ac16.vDriverVersion;
103 strcpy(lpCaps->szPname, ac16.szPname);
104 lpCaps->wTechnology = ac16.wTechnology;
105 lpCaps->dwSupport = ac16.dwSupport;
106 #endif
107 return WINMM_MAP_MSGERROR;
110 /**************************************************************************
111 * MMDRV_Aux_Callback [internal]
113 static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
115 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
117 FIXME("NIY\n");
118 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
121 /* =================================
122 * M I X E R M A P P E R S
123 * ================================= */
125 /**************************************************************************
126 * xMMDRV_Mixer_Map16To32W [internal]
128 static WINMM_MapType MMDRV_Mixer_Map16To32W (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
130 return WINMM_MAP_MSGERROR;
133 /**************************************************************************
134 * MMDRV_Mixer_UnMap16To32W [internal]
136 static WINMM_MapType MMDRV_Mixer_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
138 #if 0
139 MIXERCAPSA micA;
140 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
142 if (ret == MMSYSERR_NOERROR) {
143 mixcaps->wMid = micA.wMid;
144 mixcaps->wPid = micA.wPid;
145 mixcaps->vDriverVersion = micA.vDriverVersion;
146 strcpy(mixcaps->szPname, micA.szPname);
147 mixcaps->fdwSupport = micA.fdwSupport;
148 mixcaps->cDestinations = micA.cDestinations;
150 return ret;
151 #endif
152 return WINMM_MAP_MSGERROR;
155 /**************************************************************************
156 * MMDRV_Mixer_Map32WTo16 [internal]
158 static WINMM_MapType MMDRV_Mixer_Map32WTo16 (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
160 return WINMM_MAP_MSGERROR;
163 /**************************************************************************
164 * MMDRV_Mixer_UnMap32WTo16 [internal]
166 static WINMM_MapType MMDRV_Mixer_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
168 return WINMM_MAP_MSGERROR;
171 /**************************************************************************
172 * MMDRV_Mixer_Callback [internal]
174 static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
176 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
178 FIXME("NIY\n");
179 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
182 /* =================================
183 * M I D I I N M A P P E R S
184 * ================================= */
186 /**************************************************************************
187 * MMDRV_MidiIn_Map16To32W [internal]
189 static WINMM_MapType MMDRV_MidiIn_Map16To32W (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
191 return WINMM_MAP_MSGERROR;
194 /**************************************************************************
195 * MMDRV_MidiIn_UnMap16To32W [internal]
197 static WINMM_MapType MMDRV_MidiIn_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
199 return WINMM_MAP_MSGERROR;
202 /**************************************************************************
203 * MMDRV_MidiIn_Map32WTo16 [internal]
205 static WINMM_MapType MMDRV_MidiIn_Map32WTo16 (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
207 return WINMM_MAP_MSGERROR;
210 /**************************************************************************
211 * MMDRV_MidiIn_UnMap32WTo16 [internal]
213 static WINMM_MapType MMDRV_MidiIn_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
215 return WINMM_MAP_MSGERROR;
218 /**************************************************************************
219 * MMDRV_MidiIn_Callback [internal]
221 static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
223 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
225 switch (uMsg) {
226 case MIM_OPEN:
227 case MIM_CLOSE:
228 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
230 case MIM_DATA:
231 case MIM_MOREDATA:
232 case MIM_ERROR:
233 /* dwParam1 & dwParam2 are data, nothing to do */
234 break;
235 case MIM_LONGDATA:
236 case MIM_LONGERROR:
237 /* dwParam1 points to a MidiHdr, work to be done !!! */
238 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
239 /* initial map is: 32 => 16 */
240 LPMIDIHDR mh16 = MapSL(dwParam1);
241 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
243 dwParam1 = (DWORD)mh32;
244 mh32->dwFlags = mh16->dwFlags;
245 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
246 if (mh32->reserved >= sizeof(MIDIHDR))
247 mh32->dwOffset = mh16->dwOffset;
248 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
249 /* initial map is: 16 => 32 */
250 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
251 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
252 LPMIDIHDR mh16 = MapSL(segmh16);
254 dwParam1 = (DWORD)segmh16;
255 mh16->dwFlags = mh32->dwFlags;
256 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
257 if (mh16->reserved >= sizeof(MIDIHDR))
258 mh16->dwOffset = mh32->dwOffset;
260 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
261 break;
262 /* case MOM_POSITIONCB: */
263 default:
264 ERR("Unknown msg %u\n", uMsg);
267 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
270 /* =================================
271 * M I D I O U T M A P P E R S
272 * ================================= */
274 /**************************************************************************
275 * MMDRV_MidiOut_Map16To32W [internal]
277 static WINMM_MapType MMDRV_MidiOut_Map16To32W (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
279 WINMM_MapType ret = WINMM_MAP_MSGERROR;
281 switch (wMsg) {
282 case MODM_GETNUMDEVS:
283 case MODM_DATA:
284 case MODM_RESET:
285 case MODM_SETVOLUME:
286 ret = WINMM_MAP_OK;
287 break;
289 case MODM_OPEN:
290 case MODM_CLOSE:
291 case MODM_GETVOLUME:
292 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
293 break;
295 case MODM_GETDEVCAPS:
297 LPMIDIOUTCAPSW moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSW));
298 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
300 if (moc32) {
301 *(LPMIDIOUTCAPS16*)moc32 = moc16;
302 moc32 = (LPMIDIOUTCAPSW)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
303 *lpParam1 = (DWORD)moc32;
304 *lpParam2 = sizeof(MIDIOUTCAPSW);
306 ret = WINMM_MAP_OKMEM;
307 } else {
308 ret = WINMM_MAP_NOMEM;
311 break;
312 case MODM_PREPARE:
314 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
315 LPMIDIHDR mh16 = MapSL(*lpParam1);
317 if (mh32) {
318 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
319 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
320 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
321 mh32->dwBufferLength = mh16->dwBufferLength;
322 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
323 mh32->dwUser = mh16->dwUser;
324 mh32->dwFlags = mh16->dwFlags;
325 /* FIXME: nothing on mh32->lpNext */
326 /* could link the mh32->lpNext at this level for memory house keeping */
327 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh16->dwOffset : 0;
328 mh16->lpNext = mh32; /* for reuse in unprepare and write */
329 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
330 mh16->reserved = *lpParam2;
331 *lpParam1 = (DWORD)mh32;
332 *lpParam2 = sizeof(MIDIHDR);
334 ret = WINMM_MAP_OKMEM;
335 } else {
336 ret = WINMM_MAP_NOMEM;
339 break;
340 case MODM_UNPREPARE:
341 case MODM_LONGDATA:
343 LPMIDIHDR mh16 = MapSL(*lpParam1);
344 LPMIDIHDR mh32 = mh16->lpNext;
346 *lpParam1 = (DWORD)mh32;
347 *lpParam2 = sizeof(MIDIHDR);
348 /* dwBufferLength can be reduced between prepare & write */
349 if (wMsg == MODM_LONGDATA && mh32->dwBufferLength < mh16->dwBufferLength) {
350 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
351 mh32->dwBufferLength, mh16->dwBufferLength);
352 } else
353 mh32->dwBufferLength = mh16->dwBufferLength;
354 ret = WINMM_MAP_OKMEM;
356 break;
358 case MODM_CACHEPATCHES:
359 case MODM_CACHEDRUMPATCHES:
360 default:
361 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
362 break;
364 return ret;
367 /**************************************************************************
368 * MMDRV_MidiOut_UnMap16To32W [internal]
370 static WINMM_MapType MMDRV_MidiOut_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
372 WINMM_MapType ret = WINMM_MAP_MSGERROR;
374 switch (wMsg) {
375 case MODM_GETNUMDEVS:
376 case MODM_DATA:
377 case MODM_RESET:
378 case MODM_SETVOLUME:
379 ret = WINMM_MAP_OK;
380 break;
382 case MODM_OPEN:
383 case MODM_CLOSE:
384 case MODM_GETVOLUME:
385 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
386 break;
388 case MODM_GETDEVCAPS:
390 LPMIDIOUTCAPSW moc32 = (LPMIDIOUTCAPSW)(*lpParam1);
391 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
393 moc16->wMid = moc32->wMid;
394 moc16->wPid = moc32->wPid;
395 moc16->vDriverVersion = moc32->vDriverVersion;
396 WideCharToMultiByte( CP_ACP, 0, moc32->szPname, -1, moc16->szPname,
397 sizeof(moc16->szPname), NULL, NULL );
398 moc16->wTechnology = moc32->wTechnology;
399 moc16->wVoices = moc32->wVoices;
400 moc16->wNotes = moc32->wNotes;
401 moc16->wChannelMask = moc32->wChannelMask;
402 moc16->dwSupport = moc32->dwSupport;
403 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
404 ret = WINMM_MAP_OK;
406 break;
407 case MODM_PREPARE:
408 case MODM_UNPREPARE:
409 case MODM_LONGDATA:
411 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
412 LPMIDIHDR mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
414 assert(mh16->lpNext == mh32);
415 mh16->dwBufferLength = mh32->dwBufferLength;
416 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
417 mh16->dwUser = mh32->dwUser;
418 mh16->dwFlags = mh32->dwFlags;
419 if (mh16->reserved >= sizeof(MIDIHDR))
420 mh16->dwOffset = mh32->dwOffset;
422 if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
423 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
424 mh16->lpNext = 0;
426 ret = WINMM_MAP_OK;
428 break;
430 case MODM_CACHEPATCHES:
431 case MODM_CACHEDRUMPATCHES:
432 default:
433 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
434 break;
436 return ret;
439 /**************************************************************************
440 * MMDRV_MidiOut_Map32WTo16 [internal]
442 static WINMM_MapType MMDRV_MidiOut_Map32WTo16 (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
444 WINMM_MapType ret = WINMM_MAP_MSGERROR;
446 switch (wMsg) {
447 case MODM_CLOSE:
448 case MODM_GETNUMDEVS:
449 case MODM_DATA:
450 case MODM_RESET:
451 case MODM_SETVOLUME:
452 ret = WINMM_MAP_OK;
453 break;
454 case MODM_GETDEVCAPS:
456 LPMIDIOUTCAPSW moc32 = (LPMIDIOUTCAPSW)*lpParam1;
457 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSW)+sizeof(MIDIOUTCAPS16));
459 if (ptr) {
460 *(LPMIDIOUTCAPSW*)ptr = moc32;
461 ret = WINMM_MAP_OKMEM;
462 } else {
463 ret = WINMM_MAP_NOMEM;
465 *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSW);
466 *lpParam2 = sizeof(MIDIOUTCAPS16);
468 break;
469 case MODM_PREPARE:
471 LPMIDIHDR mh32 = (LPMIDIHDR)*lpParam1;
472 LPMIDIHDR mh16;
473 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
474 sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
476 if (ptr) {
477 *(LPMIDIHDR*)ptr = mh32;
478 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
479 *lpParam1 = MapLS(mh16);
480 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
481 /* data will be copied on WODM_WRITE */
482 mh16->dwBufferLength = mh32->dwBufferLength;
483 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
484 mh16->dwUser = mh32->dwUser;
485 mh16->dwFlags = mh32->dwFlags;
486 /* FIXME: nothing on mh32->lpNext */
487 /* could link the mh32->lpNext at this level for memory house keeping */
488 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
490 mh32->lpNext = mh16; /* for reuse in unprepare and write */
491 mh32->reserved = *lpParam2;
493 TRACE("mh16=%08lx mh16->lpData=%p mh32->buflen=%u mh32->lpData=%p\n",
494 *lpParam1, mh16->lpData, mh32->dwBufferLength, mh32->lpData);
495 *lpParam2 = sizeof(MIDIHDR);
497 ret = WINMM_MAP_OKMEM;
498 } else {
499 ret = WINMM_MAP_NOMEM;
502 break;
503 case MODM_UNPREPARE:
504 case MODM_LONGDATA:
506 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
507 LPMIDIHDR mh16 = mh32->lpNext;
508 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
510 assert(*(LPMIDIHDR*)ptr == mh32);
512 if (wMsg == MODM_LONGDATA)
513 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
515 *lpParam1 = MapLS(mh16);
516 *lpParam2 = sizeof(MIDIHDR);
517 TRACE("mh16=%08lx mh16->lpData=%p mh32->buflen=%u mh32->lpData=%p\n",
518 *lpParam1, mh16->lpData, mh32->dwBufferLength, mh32->lpData);
520 /* dwBufferLength can be reduced between prepare & write */
521 if (wMsg == MODM_LONGDATA && mh16->dwBufferLength < mh32->dwBufferLength) {
522 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
523 mh16->dwBufferLength, mh32->dwBufferLength);
524 } else
525 mh16->dwBufferLength = mh32->dwBufferLength;
526 ret = WINMM_MAP_OKMEM;
528 break;
529 case MODM_OPEN:
531 LPMIDIOPENDESC mod32 = (LPMIDIOPENDESC)*lpParam1;
532 LPVOID ptr;
533 LPMIDIOPENDESC16 mod16;
535 /* allocated data are mapped as follows:
536 LPMIDIOPENDESC ptr to orig lParam1
537 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
538 DWORD dwUser passed to driver
539 MIDIOPENDESC16 mod16: openDesc passed to driver
540 MIDIOPENSTRMID cIds
542 ptr = HeapAlloc( GetProcessHeap(), 0,
543 sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
544 mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
546 if (ptr) {
547 SEGPTR segptr = MapLS(ptr);
548 *(LPMIDIOPENDESC*)ptr = mod32;
549 *(LPDWORD)((char*)ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
550 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
552 mod16->hMidi = HMIDI_16(mod32->hMidi);
553 mod16->dwCallback = mod32->dwCallback;
554 mod16->dwInstance = mod32->dwInstance;
555 mod16->dnDevNode = mod32->dnDevNode;
556 mod16->cIds = mod32->cIds;
557 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
559 *lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
560 *lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
562 ret = WINMM_MAP_OKMEM;
563 } else {
564 ret = WINMM_MAP_NOMEM;
567 break;
568 case MODM_GETVOLUME:
569 case MODM_CACHEPATCHES:
570 case MODM_CACHEDRUMPATCHES:
571 default:
572 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
573 break;
575 return ret;
578 /**************************************************************************
579 * MMDRV_MidiOut_UnMap32WTo16 [internal]
581 static WINMM_MapType MMDRV_MidiOut_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
583 WINMM_MapType ret = WINMM_MAP_MSGERROR;
585 switch (wMsg) {
586 case MODM_CLOSE:
587 case MODM_GETNUMDEVS:
588 case MODM_DATA:
589 case MODM_RESET:
590 case MODM_SETVOLUME:
591 ret = WINMM_MAP_OK;
592 break;
593 case MODM_GETDEVCAPS:
595 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
596 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSW);
597 LPMIDIOUTCAPSW moc32 = *(LPMIDIOUTCAPSW*)ptr;
599 moc32->wMid = moc16->wMid;
600 moc32->wPid = moc16->wPid;
601 moc32->vDriverVersion = moc16->vDriverVersion;
602 WideCharToMultiByte( CP_ACP, 0, moc32->szPname, -1, moc16->szPname,
603 sizeof(moc16->szPname), NULL, NULL );
604 moc32->wTechnology = moc16->wTechnology;
605 moc32->wVoices = moc16->wVoices;
606 moc32->wNotes = moc16->wNotes;
607 moc32->wChannelMask = moc16->wChannelMask;
608 moc32->dwSupport = moc16->dwSupport;
609 UnMapLS( *lpParam1 );
610 HeapFree( GetProcessHeap(), 0, ptr );
611 ret = WINMM_MAP_OK;
613 break;
614 case MODM_PREPARE:
615 case MODM_UNPREPARE:
616 case MODM_LONGDATA:
618 LPMIDIHDR mh16 = MapSL(*lpParam1);
619 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
620 LPMIDIHDR mh32 = *(LPMIDIHDR*)ptr;
622 assert(mh32->lpNext == mh16);
623 UnMapLS( *lpParam1 );
624 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
625 mh32->dwUser = mh16->dwUser;
626 mh32->dwFlags = mh16->dwFlags;
628 if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
629 HeapFree( GetProcessHeap(), 0, ptr );
630 mh32->lpNext = 0;
632 ret = WINMM_MAP_OK;
634 break;
635 case MODM_OPEN:
637 LPMIDIOPENDESC16 mod16 = MapSL(*lpParam1);
638 LPSTR ptr = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
639 UnMapLS( *lpParam1 );
640 **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
642 HeapFree( GetProcessHeap(), 0, ptr );
643 ret = WINMM_MAP_OK;
645 break;
646 case MODM_GETVOLUME:
647 case MODM_CACHEPATCHES:
648 case MODM_CACHEDRUMPATCHES:
649 default:
650 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
651 break;
653 return ret;
656 /**************************************************************************
657 * MMDRV_MidiOut_Callback [internal]
659 static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
661 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
663 switch (uMsg) {
664 case MOM_OPEN:
665 case MOM_CLOSE:
666 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
667 break;
668 case MOM_DONE:
669 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
670 /* initial map is: 32 => 16 */
671 LPMIDIHDR mh16 = MapSL(dwParam1);
672 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
674 dwParam1 = (DWORD)mh32;
675 mh32->dwFlags = mh16->dwFlags;
676 mh32->dwOffset = mh16->dwOffset;
677 if (mh32->reserved >= sizeof(MIDIHDR))
678 mh32->dwOffset = mh16->dwOffset;
679 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
680 /* initial map is: 16 => 32 */
681 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
682 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
683 LPMIDIHDR mh16 = MapSL(segmh16);
685 dwParam1 = (DWORD)segmh16;
686 mh16->dwFlags = mh32->dwFlags;
687 if (mh16->reserved >= sizeof(MIDIHDR))
688 mh16->dwOffset = mh32->dwOffset;
690 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
691 break;
692 /* case MOM_POSITIONCB: */
693 default:
694 ERR("Unknown msg %u\n", uMsg);
697 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
700 /* =================================
701 * W A V E I N M A P P E R S
702 * ================================= */
704 /**************************************************************************
705 * MMDRV_WaveIn_Map16To32W [internal]
707 static WINMM_MapType MMDRV_WaveIn_Map16To32W (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
709 WINMM_MapType ret = WINMM_MAP_MSGERROR;
711 switch (wMsg) {
712 case WIDM_GETNUMDEVS:
713 case WIDM_RESET:
714 case WIDM_START:
715 case WIDM_STOP:
716 ret = WINMM_MAP_OK;
717 break;
718 case WIDM_OPEN:
719 case WIDM_CLOSE:
720 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
721 break;
722 case WIDM_GETDEVCAPS:
724 LPWAVEINCAPSW wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSW));
725 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
727 if (wic32) {
728 *(LPWAVEINCAPS16*)wic32 = wic16;
729 wic32 = (LPWAVEINCAPSW)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
730 *lpParam1 = (DWORD)wic32;
731 *lpParam2 = sizeof(WAVEINCAPSW);
733 ret = WINMM_MAP_OKMEM;
734 } else {
735 ret = WINMM_MAP_NOMEM;
738 break;
739 case WIDM_GETPOS:
741 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
742 LPMMTIME16 mmt16 = MapSL(*lpParam1);
744 if (mmt32) {
745 *(LPMMTIME16*)mmt32 = mmt16;
746 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
748 mmt32->wType = mmt16->wType;
749 *lpParam1 = (DWORD)mmt32;
750 *lpParam2 = sizeof(MMTIME);
752 ret = WINMM_MAP_OKMEM;
753 } else {
754 ret = WINMM_MAP_NOMEM;
757 break;
758 case WIDM_PREPARE:
760 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
761 LPWAVEHDR wh16 = MapSL(*lpParam1);
763 if (wh32) {
764 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
765 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
766 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
767 wh32->dwBufferLength = wh16->dwBufferLength;
768 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
769 wh32->dwUser = wh16->dwUser;
770 wh32->dwFlags = wh16->dwFlags;
771 wh32->dwLoops = wh16->dwLoops;
772 /* FIXME: nothing on wh32->lpNext */
773 /* could link the wh32->lpNext at this level for memory house keeping */
774 wh16->lpNext = wh32; /* for reuse in unprepare and write */
775 *lpParam1 = (DWORD)wh32;
776 *lpParam2 = sizeof(WAVEHDR);
778 ret = WINMM_MAP_OKMEM;
779 } else {
780 ret = WINMM_MAP_NOMEM;
783 break;
784 case WIDM_ADDBUFFER:
785 case WIDM_UNPREPARE:
787 LPWAVEHDR wh16 = MapSL(*lpParam1);
788 LPWAVEHDR wh32 = wh16->lpNext;
790 *lpParam1 = (DWORD)wh32;
791 *lpParam2 = sizeof(WAVEHDR);
792 /* dwBufferLength can be reduced between prepare & write */
793 if (wMsg == WIDM_ADDBUFFER && wh32->dwBufferLength < wh16->dwBufferLength) {
794 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
795 wh32->dwBufferLength, wh16->dwBufferLength);
796 } else
797 wh32->dwBufferLength = wh16->dwBufferLength;
798 ret = WINMM_MAP_OKMEM;
800 break;
801 case WIDM_MAPPER_STATUS:
802 /* just a single DWORD */
803 *lpParam2 = (DWORD)MapSL(*lpParam2);
804 ret = WINMM_MAP_OK;
805 break;
806 default:
807 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
808 break;
810 return ret;
813 /**************************************************************************
814 * MMDRV_WaveIn_UnMap16To32W [internal]
816 static WINMM_MapType MMDRV_WaveIn_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
818 WINMM_MapType ret = WINMM_MAP_MSGERROR;
820 switch (wMsg) {
821 case WIDM_GETNUMDEVS:
822 case WIDM_RESET:
823 case WIDM_START:
824 case WIDM_STOP:
825 case WIDM_MAPPER_STATUS:
826 ret = WINMM_MAP_OK;
827 break;
828 case WIDM_OPEN:
829 case WIDM_CLOSE:
830 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
831 break;
832 case WIDM_GETDEVCAPS:
834 LPWAVEINCAPSW wic32 = (LPWAVEINCAPSW)(*lpParam1);
835 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
837 wic16->wMid = wic32->wMid;
838 wic16->wPid = wic32->wPid;
839 wic16->vDriverVersion = wic32->vDriverVersion;
840 WideCharToMultiByte( CP_ACP, 0, wic32->szPname, -1, wic16->szPname,
841 sizeof(wic16->szPname), NULL, NULL );
842 wic16->dwFormats = wic32->dwFormats;
843 wic16->wChannels = wic32->wChannels;
844 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
845 ret = WINMM_MAP_OK;
847 break;
848 case WIDM_GETPOS:
850 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
851 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
853 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
854 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
855 ret = WINMM_MAP_OK;
857 break;
858 case WIDM_ADDBUFFER:
859 case WIDM_PREPARE:
860 case WIDM_UNPREPARE:
862 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
863 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
865 assert(wh16->lpNext == wh32);
866 wh16->dwBufferLength = wh32->dwBufferLength;
867 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
868 wh16->dwUser = wh32->dwUser;
869 wh16->dwFlags = wh32->dwFlags;
870 wh16->dwLoops = wh32->dwLoops;
872 if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
873 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
874 wh16->lpNext = 0;
876 ret = WINMM_MAP_OK;
878 break;
879 default:
880 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
881 break;
883 return ret;
886 /**************************************************************************
887 * MMDRV_WaveIn_Map32WTo16 [internal]
889 static WINMM_MapType MMDRV_WaveIn_Map32WTo16 (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
891 WINMM_MapType ret = WINMM_MAP_MSGERROR;
893 switch (wMsg) {
894 case WIDM_CLOSE:
895 case WIDM_GETNUMDEVS:
896 case WIDM_RESET:
897 case WIDM_START:
898 case WIDM_STOP:
899 ret = WINMM_MAP_OK;
900 break;
902 case WIDM_OPEN:
904 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
905 int sz = sizeof(WAVEFORMATEX);
906 LPVOID ptr;
907 LPWAVEOPENDESC16 wod16;
909 /* allocated data are mapped as follows:
910 LPWAVEOPENDESC ptr to orig lParam1
911 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
912 DWORD dwUser passed to driver
913 WAVEOPENDESC16 wod16: openDesc passed to driver
914 WAVEFORMATEX openDesc->lpFormat passed to driver
915 xxx extra bytes to WAVEFORMATEX
917 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
918 TRACE("Allocating %u extra bytes (%d)\n", wod32->lpFormat->cbSize, wod32->lpFormat->wFormatTag);
919 sz += wod32->lpFormat->cbSize;
922 ptr = HeapAlloc( GetProcessHeap(), 0,
923 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
925 if (ptr) {
926 SEGPTR seg_ptr = MapLS( ptr );
927 *(LPWAVEOPENDESC*)ptr = wod32;
928 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
929 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
931 wod16->hWave = HWAVE_16(wod32->hWave);
932 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
933 memcpy(wod16 + 1, wod32->lpFormat, sz);
935 wod16->dwCallback = wod32->dwCallback;
936 wod16->dwInstance = wod32->dwInstance;
937 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
938 wod16->dnDevNode = wod32->dnDevNode;
940 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
941 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
943 ret = WINMM_MAP_OKMEM;
944 } else {
945 ret = WINMM_MAP_NOMEM;
948 break;
949 case WIDM_PREPARE:
951 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
952 LPWAVEHDR wh16;
953 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
954 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
956 if (ptr) {
957 SEGPTR seg_ptr = MapLS( ptr );
958 *(LPWAVEHDR*)ptr = wh32;
959 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
960 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
961 /* data will be copied on WODM_WRITE */
962 wh16->dwBufferLength = wh32->dwBufferLength;
963 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
964 wh16->dwUser = wh32->dwUser;
965 wh16->dwFlags = wh32->dwFlags;
966 wh16->dwLoops = wh32->dwLoops;
967 /* FIXME: nothing on wh32->lpNext */
968 /* could link the wh32->lpNext at this level for memory house keeping */
969 wh32->lpNext = wh16; /* for reuse in unprepare and write */
970 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
971 *lpParam2 = sizeof(WAVEHDR);
972 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
973 *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
975 ret = WINMM_MAP_OKMEM;
976 } else {
977 ret = WINMM_MAP_NOMEM;
980 break;
981 case WIDM_ADDBUFFER:
982 case WIDM_UNPREPARE:
984 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
985 LPWAVEHDR wh16 = wh32->lpNext;
986 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
987 SEGPTR seg_ptr = MapLS( ptr );
989 assert(*(LPWAVEHDR*)ptr == wh32);
991 if (wMsg == WIDM_ADDBUFFER)
992 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
994 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
995 *lpParam2 = sizeof(WAVEHDR);
996 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
997 *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
999 /* dwBufferLength can be reduced between prepare & write */
1000 if (wMsg == WIDM_ADDBUFFER && wh16->dwBufferLength < wh32->dwBufferLength) {
1001 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1002 wh16->dwBufferLength, wh32->dwBufferLength);
1003 } else
1004 wh16->dwBufferLength = wh32->dwBufferLength;
1005 ret = WINMM_MAP_OKMEM;
1007 break;
1008 case WIDM_GETDEVCAPS:
1010 LPWAVEINCAPSW wic32 = (LPWAVEINCAPSW)*lpParam1;
1011 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSW) + sizeof(WAVEINCAPS16));
1013 if (ptr) {
1014 *(LPWAVEINCAPSW*)ptr = wic32;
1015 ret = WINMM_MAP_OKMEM;
1016 } else {
1017 ret = WINMM_MAP_NOMEM;
1019 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSW);
1020 *lpParam2 = sizeof(WAVEINCAPS16);
1022 break;
1023 case WIDM_GETPOS:
1025 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1026 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1027 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1029 if (ptr) {
1030 *(LPMMTIME*)ptr = mmt32;
1031 mmt16->wType = mmt32->wType;
1032 ret = WINMM_MAP_OKMEM;
1033 } else {
1034 ret = WINMM_MAP_NOMEM;
1036 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1037 *lpParam2 = sizeof(MMTIME16);
1039 break;
1040 case DRVM_MAPPER_STATUS:
1042 LPDWORD p32 = (LPDWORD)*lpParam2;
1043 *lpParam2 = MapLS(p32);
1044 ret = WINMM_MAP_OKMEM;
1046 break;
1047 default:
1048 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1049 break;
1051 return ret;
1054 /**************************************************************************
1055 * MMDRV_WaveIn_UnMap32WTo16 [internal]
1057 static WINMM_MapType MMDRV_WaveIn_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1059 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1061 switch (wMsg) {
1062 case WIDM_CLOSE:
1063 case WIDM_GETNUMDEVS:
1064 case WIDM_RESET:
1065 case WIDM_START:
1066 case WIDM_STOP:
1067 ret = WINMM_MAP_OK;
1068 break;
1070 case WIDM_OPEN:
1072 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1073 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1074 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1076 UnMapLS( *lpParam1 );
1077 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1078 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1079 HeapFree( GetProcessHeap(), 0, ptr );
1080 ret = WINMM_MAP_OK;
1082 break;
1084 case WIDM_ADDBUFFER:
1085 case WIDM_PREPARE:
1086 case WIDM_UNPREPARE:
1088 LPWAVEHDR wh16 = MapSL(*lpParam1);
1089 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1090 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1092 assert(wh32->lpNext == wh16);
1093 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1094 wh32->dwUser = wh16->dwUser;
1095 wh32->dwFlags = wh16->dwFlags;
1096 wh32->dwLoops = wh16->dwLoops;
1097 UnMapLS( *lpParam1 );
1099 if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1100 HeapFree( GetProcessHeap(), 0, ptr );
1101 wh32->lpNext = 0;
1103 ret = WINMM_MAP_OK;
1105 break;
1106 case WIDM_GETDEVCAPS:
1108 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
1109 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSW);
1110 LPWAVEINCAPSW wic32 = *(LPWAVEINCAPSW*)ptr;
1112 wic32->wMid = wic16->wMid;
1113 wic32->wPid = wic16->wPid;
1114 wic32->vDriverVersion = wic16->vDriverVersion;
1115 WideCharToMultiByte( CP_ACP, 0, wic32->szPname, -1, wic16->szPname,
1116 sizeof(wic16->szPname), NULL, NULL );
1117 wic32->dwFormats = wic16->dwFormats;
1118 wic32->wChannels = wic16->wChannels;
1119 UnMapLS( *lpParam1 );
1120 HeapFree( GetProcessHeap(), 0, ptr );
1121 ret = WINMM_MAP_OK;
1123 break;
1124 case WIDM_GETPOS:
1126 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1127 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1128 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1130 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1131 UnMapLS( *lpParam1 );
1132 HeapFree( GetProcessHeap(), 0, ptr );
1133 ret = WINMM_MAP_OK;
1135 break;
1136 case DRVM_MAPPER_STATUS:
1138 UnMapLS( *lpParam2 );
1139 ret = WINMM_MAP_OK;
1141 break;
1142 default:
1143 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1144 break;
1146 return ret;
1149 /**************************************************************************
1150 * MMDRV_WaveIn_Callback [internal]
1152 static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1154 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1156 switch (uMsg) {
1157 case WIM_OPEN:
1158 case WIM_CLOSE:
1159 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1160 break;
1161 case WIM_DATA:
1162 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1163 /* initial map is: 32 => 16 */
1164 LPWAVEHDR wh16 = MapSL(dwParam1);
1165 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1167 dwParam1 = (DWORD)wh32;
1168 wh32->dwFlags = wh16->dwFlags;
1169 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1170 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1171 /* initial map is: 16 => 32 */
1172 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1173 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1174 LPWAVEHDR wh16 = MapSL(segwh16);
1176 dwParam1 = (DWORD)segwh16;
1177 wh16->dwFlags = wh32->dwFlags;
1178 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1180 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1181 break;
1182 default:
1183 ERR("Unknown msg %u\n", uMsg);
1186 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1189 /* =================================
1190 * W A V E O U T M A P P E R S
1191 * ================================= */
1193 /**************************************************************************
1194 * MMDRV_WaveOut_Map16To32W [internal]
1196 static WINMM_MapType MMDRV_WaveOut_Map16To32W (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
1198 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1200 switch (wMsg) {
1201 /* nothing to do */
1202 case WODM_BREAKLOOP:
1203 case WODM_CLOSE:
1204 case WODM_GETNUMDEVS:
1205 case WODM_PAUSE:
1206 case WODM_RESET:
1207 case WODM_RESTART:
1208 case WODM_SETPITCH:
1209 case WODM_SETPLAYBACKRATE:
1210 case WODM_SETVOLUME:
1211 ret = WINMM_MAP_OK;
1212 break;
1214 case WODM_GETPITCH:
1215 case WODM_GETPLAYBACKRATE:
1216 case WODM_GETVOLUME:
1217 case WODM_OPEN:
1218 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1219 break;
1221 case WODM_GETDEVCAPS:
1223 LPWAVEOUTCAPSW woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSW));
1224 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1226 if (woc32) {
1227 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1228 woc32 = (LPWAVEOUTCAPSW)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1229 *lpParam1 = (DWORD)woc32;
1230 *lpParam2 = sizeof(WAVEOUTCAPSW);
1232 ret = WINMM_MAP_OKMEM;
1233 } else {
1234 ret = WINMM_MAP_NOMEM;
1237 break;
1238 case WODM_GETPOS:
1240 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1241 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1243 if (mmt32) {
1244 *(LPMMTIME16*)mmt32 = mmt16;
1245 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1247 mmt32->wType = mmt16->wType;
1248 *lpParam1 = (DWORD)mmt32;
1249 *lpParam2 = sizeof(MMTIME);
1251 ret = WINMM_MAP_OKMEM;
1252 } else {
1253 ret = WINMM_MAP_NOMEM;
1256 break;
1257 case WODM_PREPARE:
1259 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1260 LPWAVEHDR wh16 = MapSL(*lpParam1);
1262 if (wh32) {
1263 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1264 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1265 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1266 wh32->dwBufferLength = wh16->dwBufferLength;
1267 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1268 wh32->dwUser = wh16->dwUser;
1269 wh32->dwFlags = wh16->dwFlags;
1270 wh32->dwLoops = wh16->dwLoops;
1271 /* FIXME: nothing on wh32->lpNext */
1272 /* could link the wh32->lpNext at this level for memory house keeping */
1273 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1274 *lpParam1 = (DWORD)wh32;
1275 *lpParam2 = sizeof(WAVEHDR);
1277 ret = WINMM_MAP_OKMEM;
1278 } else {
1279 ret = WINMM_MAP_NOMEM;
1282 break;
1283 case WODM_UNPREPARE:
1284 case WODM_WRITE:
1286 LPWAVEHDR wh16 = MapSL(*lpParam1);
1287 LPWAVEHDR wh32 = wh16->lpNext;
1289 *lpParam1 = (DWORD)wh32;
1290 *lpParam2 = sizeof(WAVEHDR);
1291 /* dwBufferLength can be reduced between prepare & write */
1292 if (wMsg == WODM_WRITE && wh32->dwBufferLength < wh16->dwBufferLength) {
1293 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1294 wh32->dwBufferLength, wh16->dwBufferLength);
1295 } else
1296 wh32->dwBufferLength = wh16->dwBufferLength;
1297 ret = WINMM_MAP_OKMEM;
1299 break;
1300 case WODM_MAPPER_STATUS:
1301 *lpParam2 = (DWORD)MapSL(*lpParam2);
1302 ret = WINMM_MAP_OK;
1303 break;
1304 default:
1305 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1306 break;
1308 return ret;
1311 /**************************************************************************
1312 * MMDRV_WaveOut_UnMap16To32W [internal]
1314 static WINMM_MapType MMDRV_WaveOut_UnMap16To32W(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1316 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1318 switch (wMsg) {
1319 /* nothing to do */
1320 case WODM_BREAKLOOP:
1321 case WODM_CLOSE:
1322 case WODM_GETNUMDEVS:
1323 case WODM_PAUSE:
1324 case WODM_RESET:
1325 case WODM_RESTART:
1326 case WODM_SETPITCH:
1327 case WODM_SETPLAYBACKRATE:
1328 case WODM_SETVOLUME:
1329 case WODM_MAPPER_STATUS:
1330 ret = WINMM_MAP_OK;
1331 break;
1333 case WODM_GETPITCH:
1334 case WODM_GETPLAYBACKRATE:
1335 case WODM_GETVOLUME:
1336 case WODM_OPEN:
1337 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1338 break;
1340 case WODM_GETDEVCAPS:
1342 LPWAVEOUTCAPSW woc32 = (LPWAVEOUTCAPSW)(*lpParam1);
1343 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1345 woc16->wMid = woc32->wMid;
1346 woc16->wPid = woc32->wPid;
1347 woc16->vDriverVersion = woc32->vDriverVersion;
1348 WideCharToMultiByte( CP_ACP, 0, woc32->szPname, -1, woc16->szPname,
1349 sizeof(woc16->szPname), NULL, NULL );
1350 woc16->dwFormats = woc32->dwFormats;
1351 woc16->wChannels = woc32->wChannels;
1352 woc16->dwSupport = woc32->dwSupport;
1353 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1354 ret = WINMM_MAP_OK;
1356 break;
1357 case WODM_GETPOS:
1359 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1360 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1362 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1363 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1364 ret = WINMM_MAP_OK;
1366 break;
1367 case WODM_PREPARE:
1368 case WODM_UNPREPARE:
1369 case WODM_WRITE:
1371 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1372 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1374 assert(wh16->lpNext == wh32);
1375 wh16->dwBufferLength = wh32->dwBufferLength;
1376 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1377 wh16->dwUser = wh32->dwUser;
1378 wh16->dwFlags = wh32->dwFlags;
1379 wh16->dwLoops = wh32->dwLoops;
1381 if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1382 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1383 wh16->lpNext = 0;
1385 ret = WINMM_MAP_OK;
1387 break;
1388 default:
1389 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1390 break;
1392 return ret;
1395 /**************************************************************************
1396 * MMDRV_WaveOut_Map32WTo16 [internal]
1398 static WINMM_MapType MMDRV_WaveOut_Map32WTo16 (UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
1400 WINMM_MapType ret;
1402 switch (wMsg) {
1403 /* nothing to do */
1404 case WODM_BREAKLOOP:
1405 case WODM_CLOSE:
1406 case WODM_GETNUMDEVS:
1407 case WODM_PAUSE:
1408 case WODM_RESET:
1409 case WODM_RESTART:
1410 case WODM_SETPITCH:
1411 case WODM_SETPLAYBACKRATE:
1412 case WODM_SETVOLUME:
1413 ret = WINMM_MAP_OK;
1414 break;
1416 case WODM_GETDEVCAPS:
1418 LPWAVEOUTCAPSW woc32 = (LPWAVEOUTCAPSW)*lpParam1;
1419 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1420 sizeof(LPWAVEOUTCAPSW) + sizeof(WAVEOUTCAPS16));
1422 if (ptr) {
1423 *(LPWAVEOUTCAPSW*)ptr = woc32;
1424 ret = WINMM_MAP_OKMEM;
1425 } else {
1426 ret = WINMM_MAP_NOMEM;
1428 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSW);
1429 *lpParam2 = sizeof(WAVEOUTCAPS16);
1431 break;
1432 case WODM_GETPITCH:
1433 FIXME("NIY: no conversion yet\n");
1434 ret = WINMM_MAP_MSGERROR;
1435 break;
1436 case WODM_GETPLAYBACKRATE:
1437 FIXME("NIY: no conversion yet\n");
1438 ret = WINMM_MAP_MSGERROR;
1439 break;
1440 case WODM_GETPOS:
1442 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1443 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1444 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1446 if (ptr) {
1447 *(LPMMTIME*)ptr = mmt32;
1448 mmt16->wType = mmt32->wType;
1449 ret = WINMM_MAP_OKMEM;
1450 } else {
1451 ret = WINMM_MAP_NOMEM;
1453 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1454 *lpParam2 = sizeof(MMTIME16);
1456 break;
1457 case WODM_GETVOLUME:
1458 FIXME("NIY: no conversion yet\n");
1459 ret = WINMM_MAP_MSGERROR;
1460 break;
1461 case WODM_OPEN:
1463 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1464 int sz = sizeof(WAVEFORMATEX);
1465 LPVOID ptr;
1466 LPWAVEOPENDESC16 wod16;
1468 /* allocated data are mapped as follows:
1469 LPWAVEOPENDESC ptr to orig lParam1
1470 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1471 DWORD dwUser passed to driver
1472 WAVEOPENDESC16 wod16: openDesc passed to driver
1473 WAVEFORMATEX openDesc->lpFormat passed to driver
1474 xxx extra bytes to WAVEFORMATEX
1476 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1477 TRACE("Allocating %u extra bytes (%d)\n", wod32->lpFormat->cbSize, wod32->lpFormat->wFormatTag);
1478 sz += wod32->lpFormat->cbSize;
1481 ptr = HeapAlloc( GetProcessHeap(), 0,
1482 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1484 if (ptr) {
1485 SEGPTR seg_ptr = MapLS( ptr );
1486 *(LPWAVEOPENDESC*)ptr = wod32;
1487 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1488 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1490 wod16->hWave = HWAVE_16(wod32->hWave);
1491 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1492 memcpy(wod16 + 1, wod32->lpFormat, sz);
1494 wod16->dwCallback = wod32->dwCallback;
1495 wod16->dwInstance = wod32->dwInstance;
1496 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1497 wod16->dnDevNode = wod32->dnDevNode;
1499 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1500 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1502 ret = WINMM_MAP_OKMEM;
1503 } else {
1504 ret = WINMM_MAP_NOMEM;
1507 break;
1508 case WODM_PREPARE:
1510 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1511 LPWAVEHDR wh16;
1512 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1513 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1515 if (ptr) {
1516 SEGPTR seg_ptr = MapLS( ptr );
1517 *(LPWAVEHDR*)ptr = wh32;
1518 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1519 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1520 /* data will be copied on WODM_WRITE */
1521 wh16->dwBufferLength = wh32->dwBufferLength;
1522 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1523 wh16->dwUser = wh32->dwUser;
1524 wh16->dwFlags = wh32->dwFlags;
1525 wh16->dwLoops = wh32->dwLoops;
1526 /* FIXME: nothing on wh32->lpNext */
1527 /* could link the wh32->lpNext at this level for memory house keeping */
1528 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1529 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1530 *lpParam2 = sizeof(WAVEHDR);
1531 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
1532 *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
1534 ret = WINMM_MAP_OKMEM;
1535 } else {
1536 ret = WINMM_MAP_NOMEM;
1539 break;
1540 case WODM_UNPREPARE:
1541 case WODM_WRITE:
1543 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1544 LPWAVEHDR wh16 = wh32->lpNext;
1545 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1546 SEGPTR seg_ptr = MapLS( ptr );
1548 assert(*(LPWAVEHDR*)ptr == wh32);
1550 if (wMsg == WODM_WRITE)
1551 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1553 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1554 *lpParam2 = sizeof(WAVEHDR);
1555 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
1556 *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
1558 /* dwBufferLength can be reduced between prepare & write */
1559 if (wMsg == WODM_WRITE && wh16->dwBufferLength < wh32->dwBufferLength) {
1560 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1561 wh16->dwBufferLength, wh32->dwBufferLength);
1562 } else
1563 wh16->dwBufferLength = wh32->dwBufferLength;
1564 ret = WINMM_MAP_OKMEM;
1566 break;
1567 case DRVM_MAPPER_STATUS:
1569 LPDWORD p32 = (LPDWORD)*lpParam2;
1570 *lpParam2 = MapLS(p32);
1571 ret = WINMM_MAP_OKMEM;
1573 break;
1574 default:
1575 FIXME("NIY: no conversion yet\n");
1576 ret = WINMM_MAP_MSGERROR;
1577 break;
1579 return ret;
1582 /**************************************************************************
1583 * MMDRV_WaveOut_UnMap32WTo16 [internal]
1585 static WINMM_MapType MMDRV_WaveOut_UnMap32WTo16(UINT wMsg, DWORD_PTR *lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1587 WINMM_MapType ret;
1589 switch (wMsg) {
1590 /* nothing to do */
1591 case WODM_BREAKLOOP:
1592 case WODM_CLOSE:
1593 case WODM_GETNUMDEVS:
1594 case WODM_PAUSE:
1595 case WODM_RESET:
1596 case WODM_RESTART:
1597 case WODM_SETPITCH:
1598 case WODM_SETPLAYBACKRATE:
1599 case WODM_SETVOLUME:
1600 ret = WINMM_MAP_OK;
1601 break;
1603 case WODM_GETDEVCAPS:
1605 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1606 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSW);
1607 LPWAVEOUTCAPSW woc32 = *(LPWAVEOUTCAPSW*)ptr;
1609 woc32->wMid = woc16->wMid;
1610 woc32->wPid = woc16->wPid;
1611 woc32->vDriverVersion = woc16->vDriverVersion;
1612 WideCharToMultiByte( CP_ACP, 0, woc32->szPname, -1, woc16->szPname,
1613 sizeof(woc16->szPname), NULL, NULL );
1614 woc32->dwFormats = woc16->dwFormats;
1615 woc32->wChannels = woc16->wChannels;
1616 woc32->dwSupport = woc16->dwSupport;
1617 UnMapLS( *lpParam1 );
1618 HeapFree( GetProcessHeap(), 0, ptr );
1619 ret = WINMM_MAP_OK;
1621 break;
1622 case WODM_GETPITCH:
1623 FIXME("NIY: no conversion yet\n");
1624 ret = WINMM_MAP_MSGERROR;
1625 break;
1626 case WODM_GETPLAYBACKRATE:
1627 FIXME("NIY: no conversion yet\n");
1628 ret = WINMM_MAP_MSGERROR;
1629 break;
1630 case WODM_GETPOS:
1632 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1633 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1634 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1636 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1637 UnMapLS( *lpParam1 );
1638 HeapFree( GetProcessHeap(), 0, ptr );
1639 ret = WINMM_MAP_OK;
1641 break;
1642 case WODM_OPEN:
1644 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1645 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1646 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1648 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1649 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1650 UnMapLS( *lpParam1 );
1651 HeapFree( GetProcessHeap(), 0, ptr );
1652 ret = WINMM_MAP_OK;
1654 break;
1655 case WODM_PREPARE:
1656 case WODM_UNPREPARE:
1657 case WODM_WRITE:
1659 LPWAVEHDR wh16 = MapSL(*lpParam1);
1660 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1661 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1663 assert(wh32->lpNext == wh16);
1664 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1665 wh32->dwUser = wh16->dwUser;
1666 wh32->dwFlags = wh16->dwFlags;
1667 wh32->dwLoops = wh16->dwLoops;
1669 UnMapLS( *lpParam1 );
1670 if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1671 HeapFree( GetProcessHeap(), 0, ptr );
1672 wh32->lpNext = 0;
1674 ret = WINMM_MAP_OK;
1676 break;
1677 case WODM_GETVOLUME:
1678 FIXME("NIY: no conversion yet\n");
1679 ret = WINMM_MAP_MSGERROR;
1680 break;
1681 case DRVM_MAPPER_STATUS:
1683 UnMapLS( *lpParam2 );
1684 ret = WINMM_MAP_OK;
1686 break;
1687 default:
1688 FIXME("NIY: no conversion yet\n");
1689 ret = WINMM_MAP_MSGERROR;
1690 break;
1692 return ret;
1695 /**************************************************************************
1696 * MMDRV_WaveOut_Callback [internal]
1698 static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1700 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1702 switch (uMsg) {
1703 case WOM_OPEN:
1704 case WOM_CLOSE:
1705 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1706 break;
1707 case WOM_DONE:
1708 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1709 /* initial map is: 32 => 16 */
1710 LPWAVEHDR wh16 = MapSL(dwParam1);
1711 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1713 dwParam1 = (DWORD)wh32;
1714 wh32->dwFlags = wh16->dwFlags;
1715 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1716 /* initial map is: 16 => 32 */
1717 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1718 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1719 LPWAVEHDR wh16 = MapSL(segwh16);
1721 dwParam1 = (DWORD)segwh16;
1722 wh16->dwFlags = wh32->dwFlags;
1724 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1725 break;
1726 default:
1727 ERR("Unknown msg %u\n", uMsg);
1730 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1733 /* =================================
1734 * M A P P E R S H A N D L I N G
1735 * ================================= */
1737 static LRESULT MMDRV_CallMMDrvFunc16(DWORD fp16, WORD dev, WORD msg, LONG instance,
1738 LONG lp1, LONG lp2)
1740 WORD args[8];
1741 DWORD ret;
1743 args[7] = dev;
1744 args[6] = msg;
1745 args[5] = HIWORD(instance);
1746 args[4] = LOWORD(instance);
1747 args[3] = HIWORD(lp1);
1748 args[2] = LOWORD(lp1);
1749 args[1] = HIWORD(lp2);
1750 args[0] = LOWORD(lp2);
1751 WOWCallback16Ex( fp16, WCB16_PASCAL, sizeof(args), args, &ret );
1752 return LOWORD(ret);
1755 /**************************************************************************
1756 * MMDRV_GetDescription16 [internal]
1758 static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
1760 OFSTRUCT ofs;
1761 HFILE hFile;
1762 WORD w;
1763 DWORD dw;
1764 BOOL ret = FALSE;
1766 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
1767 ERR("Can't open file %s (builtin driver ?)\n", fname);
1768 return FALSE;
1771 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
1773 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
1774 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
1775 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
1776 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
1777 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %u\n", dw+0x2C));
1778 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
1779 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %u\n", dw));
1780 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
1781 buflen = min((int)(unsigned)(BYTE)buf[0], buflen - 1);
1782 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
1783 buf[buflen] = '\0';
1784 ret = TRUE;
1785 TRACE("Got '%s' [%d]\n", buf, buflen);
1786 theEnd:
1787 _lclose(hFile);
1788 return ret;
1791 /******************************************************************
1792 * MMDRV_LoadMMDrvFunc16
1795 static unsigned MMDRV_LoadMMDrvFunc16(LPCSTR drvName, LPWINE_DRIVER d,
1796 LPWINE_MM_DRIVER lpDrv)
1798 WINEMM_msgFunc16 func;
1799 unsigned count = 0;
1800 char buffer[128];
1802 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
1803 * The beginning of the module description indicates the driver supports
1804 * waveform, auxiliary, and mixer devices. Use one of the following
1805 * device-type names, followed by a colon (:) to indicate the type of
1806 * device your driver supports. If the driver supports more than one
1807 * type of device, separate each device-type name with a comma (,).
1809 * wave for waveform audio devices
1810 * wavemapper for wave mappers
1811 * midi for MIDI audio devices
1812 * midimapper for midi mappers
1813 * aux for auxiliary audio devices
1814 * mixer for mixer devices
1817 if (d->d.d16.hDriver16) {
1818 HMODULE16 hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
1820 #define AA(_h,_w,_x,_y,_z) \
1821 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
1822 if (func != NULL) \
1823 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
1824 TRACE("Got %d bit func '%s'\n", _y, #_x); }
1826 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
1827 A(MMDRV_AUX, auxMessage);
1828 A(MMDRV_MIXER, mxdMessage);
1829 A(MMDRV_MIDIIN, midMessage);
1830 A(MMDRV_MIDIOUT,modMessage);
1831 A(MMDRV_WAVEIN, widMessage);
1832 A(MMDRV_WAVEOUT,wodMessage);
1833 #undef A
1834 #undef AA
1836 if (TRACE_ON(winmm)) {
1837 if (MMDRV_GetDescription16(drvName, buffer, sizeof(buffer)))
1838 TRACE("%s => %s\n", drvName, buffer);
1839 else
1840 TRACE("%s => No description\n", drvName);
1843 return count;
1846 /* =================================
1847 * M C I
1848 * ================================= */
1850 /**************************************************************************
1851 * MCI_MapMsg16To32W [internal]
1853 static WINMM_MapType MCI_MapMsg16To32W(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR* lParam)
1855 if (*lParam == 0)
1856 return WINMM_MAP_OK;
1857 /* FIXME: to add also (with seg/linear modifications to do):
1858 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
1859 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
1861 switch (wMsg) {
1862 /* case MCI_CAPTURE */
1863 case MCI_CLOSE:
1864 case MCI_CLOSE_DRIVER:
1865 case MCI_CONFIGURE:
1866 case MCI_COPY:
1867 case MCI_CUE:
1868 case MCI_CUT:
1869 case MCI_DELETE:
1870 case MCI_FREEZE:
1871 case MCI_GETDEVCAPS:
1872 /* case MCI_INDEX: */
1873 /* case MCI_MARK: */
1874 /* case MCI_MONITOR: */
1875 case MCI_PASTE:
1876 case MCI_PAUSE:
1877 case MCI_PLAY:
1878 case MCI_PUT:
1879 case MCI_REALIZE:
1880 case MCI_RECORD:
1881 case MCI_RESUME:
1882 case MCI_SEEK:
1883 case MCI_SET:
1884 /* case MCI_SETTIMECODE:*/
1885 /* case MCI_SIGNAL:*/
1886 case MCI_SPIN:
1887 case MCI_STATUS: /* FIXME: is wrong for digital video */
1888 case MCI_STEP:
1889 case MCI_STOP:
1890 /* case MCI_UNDO: */
1891 case MCI_UNFREEZE:
1892 case MCI_UPDATE:
1893 case MCI_WHERE:
1894 *lParam = (DWORD)MapSL(*lParam);
1895 return WINMM_MAP_OK;
1896 case MCI_WINDOW:
1897 /* in fact, I would also need the dwFlags... to see
1898 * which members of lParam are effectively used
1900 *lParam = (DWORD)MapSL(*lParam);
1901 FIXME("Current mapping may be wrong\n");
1902 break;
1903 case MCI_BREAK:
1905 LPMCI_BREAK_PARMS mbp32 = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_BREAK_PARMS));
1906 LPMCI_BREAK_PARMS16 mbp16 = MapSL(*lParam);
1908 if (mbp32) {
1909 mbp32->dwCallback = mbp16->dwCallback;
1910 mbp32->nVirtKey = mbp16->nVirtKey;
1911 mbp32->hwndBreak = HWND_32(mbp16->hwndBreak);
1912 } else {
1913 return WINMM_MAP_NOMEM;
1915 *lParam = (DWORD)mbp32;
1917 return WINMM_MAP_OKMEM;
1918 case MCI_ESCAPE:
1920 LPMCI_VD_ESCAPE_PARMSW mvep32w = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_VD_ESCAPE_PARMSW));
1921 LPMCI_VD_ESCAPE_PARMS16 mvep16 = MapSL(*lParam);
1923 if (mvep32w) {
1924 mvep32w->dwCallback = mvep16->dwCallback;
1925 mvep32w->lpstrCommand = MCI_strdupAtoW(MapSL(mvep16->lpstrCommand));
1926 } else {
1927 return WINMM_MAP_NOMEM;
1929 *lParam = (DWORD)mvep32w;
1931 return WINMM_MAP_OKMEM;
1932 case MCI_INFO:
1934 LPMCI_INFO_PARMSW mip32w = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_INFO_PARMSW));
1935 LPMCI_INFO_PARMS16 mip16 = MapSL(*lParam);
1937 /* FIXME this is wrong if device is of type
1938 * MCI_DEVTYPE_DIGITAL_VIDEO, some members are not mapped
1940 if (mip32w) {
1941 *(LPMCI_INFO_PARMS16*)(mip32w) = mip16;
1942 mip32w = (LPMCI_INFO_PARMSW)((char*)mip32w + sizeof(LPMCI_INFO_PARMS16));
1943 mip32w->dwCallback = mip16->dwCallback;
1944 mip32w->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mip16->dwRetSize * sizeof(WCHAR));
1945 mip32w->dwRetSize = mip16->dwRetSize * sizeof(WCHAR);
1946 } else {
1947 return WINMM_MAP_NOMEM;
1949 *lParam = (DWORD)mip32w;
1951 return WINMM_MAP_OKMEM;
1952 case MCI_OPEN:
1953 case MCI_OPEN_DRIVER:
1955 LPMCI_OPEN_PARMSW mop32w = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_OPEN_PARMSW) + 2 * sizeof(DWORD));
1956 LPMCI_OPEN_PARMS16 mop16 = MapSL(*lParam);
1958 if (mop32w) {
1959 *(LPMCI_OPEN_PARMS16*)(mop32w) = mop16;
1960 mop32w = (LPMCI_OPEN_PARMSW)((char*)mop32w + sizeof(LPMCI_OPEN_PARMS16));
1961 mop32w->dwCallback = mop16->dwCallback;
1962 mop32w->wDeviceID = mop16->wDeviceID;
1963 if( ( dwFlags & ( MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID)) == MCI_OPEN_TYPE)
1964 mop32w->lpstrDeviceType = MCI_strdupAtoW(MapSL(mop16->lpstrDeviceType));
1965 else
1966 mop32w->lpstrDeviceType = (LPWSTR) mop16->lpstrDeviceType;
1967 if( ( dwFlags & ( MCI_OPEN_ELEMENT | MCI_OPEN_ELEMENT_ID)) == MCI_OPEN_ELEMENT)
1968 mop32w->lpstrElementName = MCI_strdupAtoW(MapSL(mop16->lpstrElementName));
1969 else
1970 mop32w->lpstrElementName = (LPWSTR) mop16->lpstrElementName;
1971 if( ( dwFlags & MCI_OPEN_ALIAS))
1972 mop32w->lpstrAlias = MCI_strdupAtoW(MapSL(mop16->lpstrAlias));
1973 else
1974 mop32w->lpstrAlias = (LPWSTR) mop16->lpstrAlias;
1975 /* copy extended information if any...
1976 * FIXME: this may seg fault if initial structure does not contain them and
1977 * the reads after msip16 fail under LDT limits...
1978 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
1979 * should not take care of extended parameters, and should be used by MCI_Open
1980 * to fetch uDevType. When, this is known, the mapping for sending the
1981 * MCI_OPEN_DRIVER shall be done depending on uDevType.
1983 memcpy(mop32w + 1, mop16 + 1, 2 * sizeof(DWORD));
1984 } else {
1985 return WINMM_MAP_NOMEM;
1987 *lParam = (DWORD)mop32w;
1989 return WINMM_MAP_OKMEM;
1990 case MCI_SYSINFO:
1992 LPMCI_SYSINFO_PARMSW msip32w = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_SYSINFO_PARMSW));
1993 LPMCI_SYSINFO_PARMS16 msip16 = MapSL(*lParam);
1995 if (msip32w) {
1996 *(LPMCI_SYSINFO_PARMS16*)(msip32w) = msip16;
1997 msip32w = (LPMCI_SYSINFO_PARMSW)((char*)msip32w + sizeof(LPMCI_OPEN_PARMS16));
1998 msip32w->dwCallback = msip16->dwCallback;
1999 msip32w->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, msip16->dwRetSize * sizeof(WCHAR));
2000 msip32w->dwRetSize = msip16->dwRetSize;
2001 msip32w->dwNumber = msip16->dwNumber;
2002 msip32w->wDeviceType = msip16->wDeviceType;
2003 } else {
2004 return WINMM_MAP_NOMEM;
2006 *lParam = (DWORD)msip32w;
2008 return WINMM_MAP_OKMEM;
2009 case MCI_SOUND:
2011 LPMCI_SOUND_PARMSW mbp32 = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_SOUND_PARMSW));
2012 LPMCI_SOUND_PARMS16 mbp16 = MapSL(*lParam);
2014 if (mbp32) {
2015 mbp32->dwCallback = mbp16->dwCallback;
2016 mbp32->lpstrSoundName = MCI_strdupAtoW(MapSL(mbp16->lpstrSoundName));
2017 } else {
2018 return WINMM_MAP_NOMEM;
2020 *lParam = (DWORD)mbp32;
2022 return WINMM_MAP_OKMEM;
2023 case DRV_LOAD:
2024 case DRV_ENABLE:
2025 case DRV_OPEN:
2026 case DRV_CLOSE:
2027 case DRV_DISABLE:
2028 case DRV_FREE:
2029 case DRV_CONFIGURE:
2030 case DRV_QUERYCONFIGURE:
2031 case DRV_INSTALL:
2032 case DRV_REMOVE:
2033 case DRV_EXITSESSION:
2034 case DRV_EXITAPPLICATION:
2035 case DRV_POWER:
2036 FIXME("This is a hack\n");
2037 return WINMM_MAP_OK;
2038 default:
2039 FIXME("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2041 return WINMM_MAP_MSGERROR;
2044 /**************************************************************************
2045 * MCI_UnMapMsg16To32W [internal]
2047 static WINMM_MapType MCI_UnMapMsg16To32W(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR lParam)
2049 switch (wMsg) {
2050 /* case MCI_CAPTURE */
2051 case MCI_CLOSE:
2052 case MCI_CLOSE_DRIVER:
2053 case MCI_CONFIGURE:
2054 case MCI_COPY:
2055 case MCI_CUE:
2056 case MCI_CUT:
2057 case MCI_DELETE:
2058 case MCI_FREEZE:
2059 case MCI_GETDEVCAPS:
2060 /* case MCI_INDEX: */
2061 /* case MCI_MARK: */
2062 /* case MCI_MONITOR: */
2063 case MCI_PASTE:
2064 case MCI_PAUSE:
2065 case MCI_PLAY:
2066 case MCI_PUT:
2067 case MCI_REALIZE:
2068 case MCI_RECORD:
2069 case MCI_RESUME:
2070 case MCI_SEEK:
2071 case MCI_SET:
2072 /* case MCI_SETTIMECODE:*/
2073 /* case MCI_SIGNAL:*/
2074 case MCI_SPIN:
2075 case MCI_STATUS:
2076 case MCI_STEP:
2077 case MCI_STOP:
2078 /* case MCI_UNDO: */
2079 case MCI_UNFREEZE:
2080 case MCI_UPDATE:
2081 case MCI_WHERE:
2082 return WINMM_MAP_OK;
2084 case MCI_WINDOW:
2085 /* FIXME ?? see Map function */
2086 return WINMM_MAP_OK;
2088 case MCI_BREAK:
2089 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2090 return WINMM_MAP_OK;
2091 case MCI_ESCAPE:
2092 if (lParam) {
2093 LPMCI_VD_ESCAPE_PARMSW mvep32W = (LPMCI_VD_ESCAPE_PARMSW)lParam;
2094 HeapFree(GetProcessHeap(), 0, (LPVOID)mvep32W->lpstrCommand);
2095 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2097 return WINMM_MAP_OK;
2098 case MCI_INFO:
2099 if (lParam) {
2100 LPMCI_INFO_PARMSW mip32w = (LPMCI_INFO_PARMSW)lParam;
2101 LPMCI_INFO_PARMS16 mip16 = *(LPMCI_INFO_PARMS16*)((char*)mip32w - sizeof(LPMCI_INFO_PARMS16));
2103 WideCharToMultiByte(CP_ACP, 0,
2104 mip32w->lpstrReturn, mip32w->dwRetSize / sizeof(WCHAR),
2105 MapSL(mip16->lpstrReturn), mip16->dwRetSize,
2106 NULL, NULL);
2107 HeapFree(GetProcessHeap(), 0, mip32w->lpstrReturn);
2108 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2110 return WINMM_MAP_OK;
2111 case MCI_SYSINFO:
2112 if (lParam) {
2113 LPMCI_SYSINFO_PARMSW msip32w = (LPMCI_SYSINFO_PARMSW)lParam;
2114 LPMCI_SYSINFO_PARMS16 msip16 = *(LPMCI_SYSINFO_PARMS16*)((char*)msip32w - sizeof(LPMCI_SYSINFO_PARMS16));
2116 WideCharToMultiByte(CP_ACP, 0,
2117 msip32w->lpstrReturn, msip32w->dwRetSize,
2118 MapSL(msip16->lpstrReturn), msip16->dwRetSize,
2119 NULL, NULL);
2120 HeapFree(GetProcessHeap(), 0, msip32w->lpstrReturn);
2121 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2123 return WINMM_MAP_OK;
2124 case MCI_SOUND:
2125 if (lParam) {
2126 LPMCI_SOUND_PARMSW msp32W = (LPMCI_SOUND_PARMSW)lParam;
2127 HeapFree(GetProcessHeap(), 0, (LPVOID)msp32W->lpstrSoundName);
2128 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2130 return WINMM_MAP_OK;
2131 case MCI_OPEN:
2132 case MCI_OPEN_DRIVER:
2133 if (lParam) {
2134 LPMCI_OPEN_PARMSW mop32w = (LPMCI_OPEN_PARMSW)lParam;
2135 LPMCI_OPEN_PARMS16 mop16 = *(LPMCI_OPEN_PARMS16*)((char*)mop32w - sizeof(LPMCI_OPEN_PARMS16));
2137 mop16->wDeviceID = mop32w->wDeviceID;
2138 if( ( dwFlags & ( MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID)) == MCI_OPEN_TYPE)
2139 HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrDeviceType);
2140 if( ( dwFlags & ( MCI_OPEN_ELEMENT | MCI_OPEN_ELEMENT_ID)) == MCI_OPEN_ELEMENT)
2141 HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrElementName);
2142 if( ( dwFlags & MCI_OPEN_ALIAS))
2143 HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrAlias);
2144 if (!HeapFree(GetProcessHeap(), 0, (LPVOID)(lParam - sizeof(LPMCI_OPEN_PARMS16))))
2145 FIXME("bad free line=%d\n", __LINE__);
2147 return WINMM_MAP_OK;
2148 case DRV_LOAD:
2149 case DRV_ENABLE:
2150 case DRV_OPEN:
2151 case DRV_CLOSE:
2152 case DRV_DISABLE:
2153 case DRV_FREE:
2154 case DRV_CONFIGURE:
2155 case DRV_QUERYCONFIGURE:
2156 case DRV_INSTALL:
2157 case DRV_REMOVE:
2158 case DRV_EXITSESSION:
2159 case DRV_EXITAPPLICATION:
2160 case DRV_POWER:
2161 FIXME("This is a hack\n");
2162 return WINMM_MAP_OK;
2163 default:
2164 FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2166 return WINMM_MAP_MSGERROR;
2170 * 0000 stop
2171 * 0001 squeeze signed 4 bytes to 2 bytes *( LPINT16)D = ( INT16)*( LPINT16)S; D += 2; S += 4
2172 * 0010 squeeze unsigned 4 bytes to 2 bytes *(LPUINT16)D = (UINT16)*(LPUINT16)S; D += 2; S += 4
2173 * 0100
2174 * 0101
2175 * 0110 zero 4 bytes *(DWORD)D = 0 D += 4; S += 4
2176 * 0111 copy string *(LPSTR*)D = seg dup(*(LPSTR*)S) D += 4; S += 4
2177 * 1xxx copy xxx + 1 bytes memcpy(D, S, xxx + 1); D += xxx+1; S += xxx+1
2180 /**************************************************************************
2181 * MCI_MsgMapper32WTo16_Create [internal]
2183 * Helper for MCI_MapMsg32WTo16.
2184 * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit
2185 * segmented pointer.
2186 * map contains a list of action to be performed for the mapping (see list
2187 * above)
2188 * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area.
2190 static WINMM_MapType MCI_MsgMapper32WTo16_Create(void** ptr, int size16, DWORD map, BOOLEAN keep)
2192 void* lp = HeapAlloc( GetProcessHeap(), 0, (keep ? sizeof(void**) : 0) + size16 );
2193 LPBYTE p16, p32;
2195 if (!lp) {
2196 return WINMM_MAP_NOMEM;
2198 p32 = *ptr;
2199 if (keep) {
2200 *(void**)lp = *ptr;
2201 p16 = (LPBYTE)lp + sizeof(void**);
2202 *ptr = (char*)MapLS(lp) + sizeof(void**);
2203 } else {
2204 p16 = lp;
2205 *ptr = (void*)MapLS(lp);
2208 if (map == 0) {
2209 memcpy(p16, p32, size16);
2210 } else {
2211 unsigned nibble;
2212 unsigned sz;
2214 while (map & 0xF) {
2215 nibble = map & 0xF;
2216 if (nibble & 0x8) {
2217 sz = (nibble & 7) + 1;
2218 memcpy(p16, p32, sz);
2219 p16 += sz;
2220 p32 += sz;
2221 size16 -= sz; /* DEBUG only */
2222 } else {
2223 switch (nibble) {
2224 case 0x1:
2225 *(LPINT16)p16 = *(LPINT)p32;
2226 p16 += sizeof(INT16);
2227 p32 += sizeof(INT);
2228 size16 -= sizeof(INT16);
2229 break;
2230 case 0x2:
2231 *(LPUINT16)p16 = *(LPUINT)p32;
2232 p16 += sizeof(UINT16);
2233 p32 += sizeof(UINT);
2234 size16 -= sizeof(UINT16);
2235 break;
2236 case 0x6:
2237 *(LPDWORD)p16 = 0;
2238 p16 += sizeof(DWORD);
2239 p32 += sizeof(DWORD);
2240 size16 -= sizeof(DWORD);
2241 break;
2242 case 0x7:
2243 *(SEGPTR *)p16 = MapLS( MCI_strdupWtoA( *(LPCWSTR *)p32 ) );
2244 p16 += sizeof(SEGPTR);
2245 p32 += sizeof(LPSTR);
2246 size16 -= sizeof(SEGPTR);
2247 break;
2248 default:
2249 FIXME("Unknown nibble for mapping (%x)\n", nibble);
2252 map >>= 4;
2254 if (size16 != 0) /* DEBUG only */
2255 FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2257 return WINMM_MAP_OKMEM;
2260 /**************************************************************************
2261 * MCI_MsgMapper32WTo16_Destroy [internal]
2263 * Helper for MCI_UnMapMsg32WTo16.
2265 static WINMM_MapType MCI_MsgMapper32WTo16_Destroy(void* ptr, int size16, DWORD map, BOOLEAN kept)
2267 if (ptr) {
2268 void* msg16 = MapSL((SEGPTR)ptr);
2269 void* alloc;
2270 LPBYTE p32, p16;
2271 unsigned nibble;
2273 UnMapLS( (SEGPTR)ptr );
2274 if (kept) {
2275 alloc = (char*)msg16 - sizeof(void**);
2276 p32 = *(void**)alloc;
2277 p16 = msg16;
2279 if (map == 0) {
2280 memcpy(p32, p16, size16);
2281 } else {
2282 while (map & 0xF) {
2283 nibble = map & 0xF;
2284 if (nibble & 0x8) {
2285 memcpy(p32, p16, (nibble & 7) + 1);
2286 p16 += (nibble & 7) + 1;
2287 p32 += (nibble & 7) + 1;
2288 size16 -= (nibble & 7) + 1;
2289 } else {
2290 switch (nibble) {
2291 case 0x1:
2292 *(LPINT)p32 = *(LPINT16)p16;
2293 p16 += sizeof(INT16);
2294 p32 += sizeof(INT);
2295 size16 -= sizeof(INT16);
2296 break;
2297 case 0x2:
2298 *(LPUINT)p32 = *(LPUINT16)p16;
2299 p16 += sizeof(UINT16);
2300 p32 += sizeof(UINT);
2301 size16 -= sizeof(UINT16);
2302 break;
2303 case 0x6:
2304 p16 += sizeof(UINT);
2305 p32 += sizeof(UINT);
2306 size16 -= sizeof(UINT);
2307 break;
2308 case 0x7:
2309 HeapFree(GetProcessHeap(), 0, MapSL(*(SEGPTR *)p16));
2310 UnMapLS( *(SEGPTR *)p16 );
2311 p16 += sizeof(SEGPTR);
2312 p32 += sizeof(char*);
2313 size16 -= sizeof(SEGPTR);
2314 break;
2315 default:
2316 FIXME("Unknown nibble for mapping (%x)\n", nibble);
2319 map >>= 4;
2321 if (size16 != 0) /* DEBUG only */
2322 FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2324 } else {
2325 alloc = msg16;
2328 HeapFree( GetProcessHeap(), 0, alloc );
2330 return WINMM_MAP_OK;
2333 /**************************************************************************
2334 * MCI_MapMsg32WTo16 [internal]
2336 * Map a 32W bit MCI message to a 16 bit MCI message.
2338 static WINMM_MapType MCI_MapMsg32WTo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR* lParam)
2340 int size;
2341 BOOLEAN keep = FALSE;
2342 DWORD map = 0;
2344 if (*lParam == 0)
2345 return WINMM_MAP_OK;
2347 /* FIXME: to add also (with seg/linear modifications to do):
2348 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
2349 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
2351 switch (wMsg) {
2352 case MCI_BREAK:
2353 size = sizeof(MCI_BREAK_PARMS);
2354 break;
2355 /* case MCI_CAPTURE */
2356 case MCI_CLOSE:
2357 case MCI_CLOSE_DRIVER:
2358 case MCI_CONFIGURE:
2359 size = sizeof(MCI_GENERIC_PARMS);
2360 break;
2361 /* case MCI_COPY: */
2362 case MCI_CUE:
2363 switch (uDevType) {
2364 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_CUE_PARMS); break;
2365 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_CUE_PARMS); break;*/ FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2366 default: size = sizeof(MCI_GENERIC_PARMS); break;
2368 break;
2369 /* case MCI_CUT:*/
2370 case MCI_DELETE:
2371 switch (uDevType) {
2372 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_DELETE_PARMS16); map = 0x0F1111FB; break;
2373 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_DELETE_PARMS); break;
2374 default: size = sizeof(MCI_GENERIC_PARMS); break;
2376 break;
2377 /* case MCI_ESCAPE: */
2378 case MCI_FREEZE:
2379 switch (uDevType) {
2380 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_FREEZE_PARMS); map = 0x0001111B; break;
2381 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break;
2382 default: size = sizeof(MCI_GENERIC_PARMS); break;
2384 break;
2385 case MCI_GETDEVCAPS:
2386 keep = TRUE;
2387 size = sizeof(MCI_GETDEVCAPS_PARMS);
2388 break;
2389 /* case MCI_INDEX: */
2390 case MCI_INFO:
2392 LPMCI_INFO_PARMSW mip32w = (LPMCI_INFO_PARMSW)(*lParam);
2393 char* ptr;
2394 LPMCI_INFO_PARMS16 mip16;
2396 switch (uDevType) {
2397 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_INFO_PARMS16); break;
2398 default: size = sizeof(MCI_INFO_PARMS16); break;
2400 ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMCI_INFO_PARMSW) + size);
2401 if (ptr)
2403 *(LPMCI_INFO_PARMSW*)ptr = mip32w;
2404 mip16 = (LPMCI_INFO_PARMS16)(ptr + sizeof(LPMCI_INFO_PARMSW));
2405 mip16->dwCallback = mip32w->dwCallback;
2406 mip16->lpstrReturn = MapLS( HeapAlloc(GetProcessHeap(), 0, mip32w->dwRetSize / sizeof(WCHAR)) );
2407 mip16->dwRetSize = mip32w->dwRetSize / sizeof(WCHAR);
2408 if (uDevType == MCI_DEVTYPE_DIGITAL_VIDEO) {
2409 ((LPMCI_DGV_INFO_PARMS16)mip16)->dwItem = ((LPMCI_DGV_INFO_PARMSW)mip32w)->dwItem;
2411 } else {
2412 return WINMM_MAP_NOMEM;
2414 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_INFO_PARMSW);
2416 return WINMM_MAP_OKMEM;
2417 /* case MCI_MARK: */
2418 /* case MCI_MONITOR: */
2419 case MCI_OPEN:
2420 case MCI_OPEN_DRIVER:
2422 LPMCI_OPEN_PARMSW mop32w = (LPMCI_OPEN_PARMSW)(*lParam);
2423 char* ptr = HeapAlloc( GetProcessHeap(), 0,
2424 sizeof(LPMCI_OPEN_PARMSW) + sizeof(MCI_OPEN_PARMS16) + 2 * sizeof(DWORD));
2425 LPMCI_OPEN_PARMS16 mop16;
2428 if (ptr) {
2429 *(LPMCI_OPEN_PARMSW*)(ptr) = mop32w;
2430 mop16 = (LPMCI_OPEN_PARMS16)(ptr + sizeof(LPMCI_OPEN_PARMSW));
2431 mop16->dwCallback = mop32w->dwCallback;
2432 mop16->wDeviceID = mop32w->wDeviceID;
2433 if (dwFlags & MCI_OPEN_TYPE) {
2434 if (dwFlags & MCI_OPEN_TYPE_ID) {
2435 /* dword "transparent" value */
2436 mop16->lpstrDeviceType = (SEGPTR)mop32w->lpstrDeviceType;
2437 } else {
2438 /* string */
2439 mop16->lpstrDeviceType = MapLS( MCI_strdupWtoA(mop32w->lpstrDeviceType) );
2441 } else {
2442 /* nuthin' */
2443 mop16->lpstrDeviceType = 0;
2445 if (dwFlags & MCI_OPEN_ELEMENT) {
2446 if (dwFlags & MCI_OPEN_ELEMENT_ID) {
2447 mop16->lpstrElementName = (SEGPTR)mop32w->lpstrElementName;
2448 } else {
2449 mop16->lpstrElementName = MapLS( MCI_strdupWtoA(mop32w->lpstrElementName) );
2451 } else {
2452 mop16->lpstrElementName = 0;
2454 if (dwFlags & MCI_OPEN_ALIAS) {
2455 mop16->lpstrAlias = MapLS( MCI_strdupWtoA(mop32w->lpstrAlias) );
2456 } else {
2457 mop16->lpstrAlias = 0;
2459 /* copy extended information if any...
2460 * FIXME: this may seg fault if initial structure does not contain them and
2461 * the reads after msip16 fail under LDT limits...
2462 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
2463 * should not take care of extended parameters, and should be used by MCI_Open
2464 * to fetch uDevType. When, this is known, the mapping for sending the
2465 * MCI_OPEN_DRIVER shall be done depending on uDevType.
2467 memcpy(mop16 + 1, mop32w + 1, 2 * sizeof(DWORD));
2468 } else {
2469 return WINMM_MAP_NOMEM;
2471 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_PARMSW);
2473 return WINMM_MAP_OKMEM;
2474 /* case MCI_PASTE:*/
2475 case MCI_PAUSE:
2476 size = sizeof(MCI_GENERIC_PARMS);
2477 break;
2478 case MCI_PLAY:
2479 size = sizeof(MCI_PLAY_PARMS);
2480 break;
2481 case MCI_PUT:
2482 switch (uDevType) {
2483 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break;
2484 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break;
2485 default: size = sizeof(MCI_GENERIC_PARMS); break;
2487 break;
2488 case MCI_REALIZE:
2489 size = sizeof(MCI_GENERIC_PARMS);
2490 break;
2491 case MCI_RECORD:
2492 switch (uDevType) {
2493 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECORD_PARMS16); map = 0x0F1111FB; break;
2494 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_RECORD_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2495 default: size = sizeof(MCI_RECORD_PARMS); break;
2497 break;
2498 case MCI_RESUME:
2499 size = sizeof(MCI_GENERIC_PARMS);
2500 break;
2501 case MCI_SEEK:
2502 switch (uDevType) {
2503 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SEEK_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2504 default: size = sizeof(MCI_SEEK_PARMS); break;
2506 break;
2507 case MCI_SET:
2508 switch (uDevType) {
2509 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SET_PARMS); break;
2510 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SET_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2511 case MCI_DEVTYPE_SEQUENCER: size = sizeof(MCI_SEQ_SET_PARMS); break;
2512 /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned,
2513 * so not doing anything should work...
2515 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_SET_PARMS); break;
2516 default: size = sizeof(MCI_SET_PARMS); break;
2518 break;
2519 case MCI_SETAUDIO:
2520 switch (uDevType) {
2521 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SETAUDIO_PARMS16);map = 0x0000077FF; break;
2522 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2523 default: size = sizeof(MCI_GENERIC_PARMS); break;
2525 break;
2526 /* case MCI_SETTIMECODE:*/
2527 /* case MCI_SIGNAL:*/
2528 /* case MCI_SOUND:*/
2529 case MCI_SPIN:
2530 size = sizeof(MCI_SET_PARMS);
2531 break;
2532 case MCI_STATUS:
2533 keep = TRUE;
2534 switch (uDevType) {
2535 /* FIXME:
2536 * don't know if buffer for value is the one passed through lpstrDevice
2537 * or is provided by MCI driver.
2538 * Assuming solution 2: provided by MCI driver, so zeroing on entry
2540 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16); map = 0x0B6FF; break;
2541 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2542 default: size = sizeof(MCI_STATUS_PARMS); break;
2544 break;
2545 case MCI_STEP:
2546 switch (uDevType) {
2547 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STEP_PARMS); break;
2548 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STEP_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2549 case MCI_DEVTYPE_VIDEODISC: size = sizeof(MCI_VD_STEP_PARMS); break;
2550 default: size = sizeof(MCI_GENERIC_PARMS); break;
2552 break;
2553 case MCI_STOP:
2554 size = sizeof(MCI_SET_PARMS);
2555 break;
2556 case MCI_SYSINFO:
2558 LPMCI_SYSINFO_PARMSW msip32w = (LPMCI_SYSINFO_PARMSW)(*lParam);
2559 LPMCI_SYSINFO_PARMS16 msip16;
2560 char* ptr = HeapAlloc( GetProcessHeap(), 0,
2561 sizeof(LPMCI_SYSINFO_PARMSW) + sizeof(MCI_SYSINFO_PARMS16) );
2563 if (ptr) {
2564 *(LPMCI_SYSINFO_PARMSW*)(ptr) = msip32w;
2565 msip16 = (LPMCI_SYSINFO_PARMS16)(ptr + sizeof(LPMCI_SYSINFO_PARMSW));
2567 msip16->dwCallback = msip32w->dwCallback;
2568 msip16->lpstrReturn = MapLS( HeapAlloc(GetProcessHeap(), 0, msip32w->dwRetSize) );
2569 msip16->dwRetSize = msip32w->dwRetSize;
2570 msip16->dwNumber = msip32w->dwNumber;
2571 msip16->wDeviceType = msip32w->wDeviceType;
2572 } else {
2573 return WINMM_MAP_NOMEM;
2575 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_SYSINFO_PARMSW);
2577 return WINMM_MAP_OKMEM;
2578 /* case MCI_UNDO: */
2579 case MCI_UNFREEZE:
2580 switch (uDevType) {
2581 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break;
2582 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; break;
2583 default: size = sizeof(MCI_GENERIC_PARMS); break;
2585 break;
2586 case MCI_UPDATE:
2587 switch (uDevType) {
2588 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_UPDATE_PARMS16); map = 0x000B1111B; break;
2589 default: size = sizeof(MCI_GENERIC_PARMS); break;
2591 break;
2592 case MCI_WHERE:
2593 switch (uDevType) {
2594 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break;
2595 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break;
2596 default: size = sizeof(MCI_GENERIC_PARMS); break;
2598 break;
2599 case MCI_WINDOW:
2600 switch (uDevType) {
2601 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7FB; break;
2602 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7FB; break;
2603 default: size = sizeof(MCI_GENERIC_PARMS); break;
2605 break;
2606 case DRV_OPEN:
2608 LPMCI_OPEN_DRIVER_PARMSW modp32w = (LPMCI_OPEN_DRIVER_PARMSW)(*lParam);
2609 LPMCI_OPEN_DRIVER_PARMS16 modp16;
2610 char *ptr = HeapAlloc( GetProcessHeap(), 0,
2611 sizeof(LPMCI_OPEN_DRIVER_PARMSW) + sizeof(MCI_OPEN_DRIVER_PARMS16));
2613 if (ptr) {
2614 *(LPMCI_OPEN_DRIVER_PARMSW*)(ptr) = modp32w;
2615 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSW));
2616 modp16->wDeviceID = modp32w->wDeviceID;
2617 modp16->lpstrParams = MapLS( MCI_strdupWtoA(modp32w->lpstrParams) );
2618 /* other fields are gonna be filled by the driver, don't copy them */
2619 } else {
2620 return WINMM_MAP_NOMEM;
2622 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_DRIVER_PARMSW);
2624 return WINMM_MAP_OKMEM;
2625 case DRV_LOAD:
2626 case DRV_ENABLE:
2627 case DRV_CLOSE:
2628 case DRV_DISABLE:
2629 case DRV_FREE:
2630 case DRV_CONFIGURE:
2631 case DRV_QUERYCONFIGURE:
2632 case DRV_INSTALL:
2633 case DRV_REMOVE:
2634 case DRV_EXITSESSION:
2635 case DRV_EXITAPPLICATION:
2636 case DRV_POWER:
2637 return WINMM_MAP_OK;
2639 default:
2640 FIXME("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2641 return WINMM_MAP_MSGERROR;
2643 return MCI_MsgMapper32WTo16_Create((void**)lParam, size, map, keep);
2646 /**************************************************************************
2647 * MCI_UnMapMsg32WTo16 [internal]
2649 static WINMM_MapType MCI_UnMapMsg32WTo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR lParam)
2651 int size = 0;
2652 BOOLEAN kept = FALSE; /* there is no need to compute size when kept is FALSE */
2653 DWORD map = 0;
2655 switch (wMsg) {
2656 case MCI_BREAK:
2657 break;
2658 /* case MCI_CAPTURE */
2659 case MCI_CLOSE:
2660 case MCI_CLOSE_DRIVER:
2661 case MCI_CONFIGURE:
2662 break;
2663 /* case MCI_COPY: */
2664 case MCI_CUE:
2665 break;
2666 /* case MCI_CUT: */
2667 case MCI_DELETE:
2668 break;
2669 /* case MCI_ESCAPE: */
2670 case MCI_FREEZE:
2671 break;
2672 case MCI_GETDEVCAPS:
2673 kept = TRUE;
2674 size = sizeof(MCI_GETDEVCAPS_PARMS);
2675 break;
2676 /* case MCI_INDEX: */
2677 case MCI_INFO:
2678 if (lParam) {
2679 LPMCI_INFO_PARMS16 mip16 = (LPMCI_INFO_PARMS16)MapSL(lParam);
2680 LPMCI_INFO_PARMSW mip32w = *(LPMCI_INFO_PARMSW*)((char*)mip16 - sizeof(LPMCI_INFO_PARMSW));
2682 MultiByteToWideChar(CP_ACP, 0, MapSL(mip16->lpstrReturn), mip16->dwRetSize,
2683 mip32w->lpstrReturn, mip32w->dwRetSize / sizeof(WCHAR));
2684 UnMapLS( lParam );
2685 UnMapLS( mip16->lpstrReturn );
2686 HeapFree( GetProcessHeap(), 0, MapSL(mip16->lpstrReturn) );
2687 HeapFree( GetProcessHeap(), 0, (char*)mip16 - sizeof(LPMCI_OPEN_PARMSW) );
2689 return WINMM_MAP_OK;
2690 /* case MCI_MARK: */
2691 /* case MCI_MONITOR: */
2692 case MCI_OPEN:
2693 case MCI_OPEN_DRIVER:
2694 if (lParam) {
2695 LPMCI_OPEN_PARMS16 mop16 = (LPMCI_OPEN_PARMS16)MapSL(lParam);
2696 LPMCI_OPEN_PARMSW mop32w = *(LPMCI_OPEN_PARMSW*)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSW));
2697 UnMapLS( lParam );
2698 mop32w->wDeviceID = mop16->wDeviceID;
2699 if ((dwFlags & MCI_OPEN_TYPE) && !(dwFlags & MCI_OPEN_TYPE_ID))
2701 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrDeviceType));
2702 UnMapLS( mop16->lpstrDeviceType );
2704 if ((dwFlags & MCI_OPEN_ELEMENT) && !(dwFlags & MCI_OPEN_ELEMENT_ID))
2706 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrElementName));
2707 UnMapLS( mop16->lpstrElementName );
2709 if (dwFlags & MCI_OPEN_ALIAS)
2711 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrAlias));
2712 UnMapLS( mop16->lpstrAlias );
2714 HeapFree( GetProcessHeap(), 0, (char*)mop16 - sizeof(LPMCI_OPEN_PARMSW) );
2716 return WINMM_MAP_OK;
2717 /* case MCI_PASTE:*/
2718 case MCI_PAUSE:
2719 break;
2720 case MCI_PLAY:
2721 break;
2722 case MCI_PUT:
2723 break;
2724 case MCI_REALIZE:
2725 break;
2726 case MCI_RECORD:
2727 break;
2728 case MCI_RESUME:
2729 break;
2730 case MCI_SEEK:
2731 break;
2732 case MCI_SET:
2733 break;
2734 case MCI_SETAUDIO:
2735 switch (uDevType) {
2736 case MCI_DEVTYPE_DIGITAL_VIDEO: map = 0x0000077FF; break;
2737 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2739 break;
2740 /* case MCI_SETTIMECODE:*/
2741 /* case MCI_SIGNAL:*/
2742 /* case MCI_SOUND:*/
2743 case MCI_SPIN:
2744 break;
2745 case MCI_STATUS:
2746 kept = TRUE;
2747 switch (uDevType) {
2748 case MCI_DEVTYPE_DIGITAL_VIDEO:
2749 if (lParam) {
2750 LPMCI_DGV_STATUS_PARMS16 mdsp16 = (LPMCI_DGV_STATUS_PARMS16)MapSL(lParam);
2751 LPMCI_DGV_STATUS_PARMSA mdsp32a = *(LPMCI_DGV_STATUS_PARMSA*)((char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA));
2753 UnMapLS( lParam );
2754 if (mdsp16) {
2755 mdsp32a->dwReturn = mdsp16->dwReturn;
2756 if (dwFlags & MCI_DGV_STATUS_DISKSPACE) {
2757 TRACE("MCI_STATUS (DGV) lpstrDrive=%08x\n", mdsp16->lpstrDrive);
2758 TRACE("MCI_STATUS (DGV) lpstrDrive=%s\n", (LPSTR)MapSL(mdsp16->lpstrDrive));
2759 UnMapLS( mdsp16->lpstrDrive );
2761 HeapFree( GetProcessHeap(), 0, (char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA) );
2762 } else {
2763 return WINMM_MAP_NOMEM;
2766 return WINMM_MAP_OKMEM;
2767 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2768 default: size = sizeof(MCI_STATUS_PARMS); break;
2770 break;
2771 case MCI_STEP:
2772 break;
2773 case MCI_STOP:
2774 break;
2775 case MCI_SYSINFO:
2776 if (lParam) {
2777 LPMCI_SYSINFO_PARMS16 msip16 = (LPMCI_SYSINFO_PARMS16)MapSL(lParam);
2778 LPMCI_SYSINFO_PARMSW msip32w = *(LPMCI_SYSINFO_PARMSW*)((char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSW));
2780 UnMapLS( lParam );
2781 if (msip16) {
2782 MultiByteToWideChar(CP_ACP, 0, MapSL(msip16->lpstrReturn), msip16->dwRetSize,
2783 msip32w->lpstrReturn, msip32w->dwRetSize/sizeof(WCHAR));
2784 UnMapLS( msip16->lpstrReturn );
2785 HeapFree( GetProcessHeap(), 0, MapSL(msip16->lpstrReturn) );
2786 HeapFree( GetProcessHeap(), 0, (char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSW) );
2787 } else {
2788 return WINMM_MAP_NOMEM;
2791 return WINMM_MAP_OKMEM;
2792 /* case MCI_UNDO: */
2793 case MCI_UNFREEZE:
2794 break;
2795 case MCI_UPDATE:
2796 break;
2797 case MCI_WHERE:
2798 switch (uDevType) {
2799 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break;
2800 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break;
2801 default: break;
2803 break;
2804 case MCI_WINDOW:
2805 switch (uDevType) {
2806 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7666; break;
2807 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7666; break;
2808 default: break;
2810 /* FIXME: see map function */
2811 break;
2812 case DRV_OPEN:
2813 if (lParam) {
2814 LPMCI_OPEN_DRIVER_PARMS16 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)MapSL(lParam);
2815 LPMCI_OPEN_DRIVER_PARMSW modp32w = *(LPMCI_OPEN_DRIVER_PARMSW*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSW));
2817 UnMapLS( lParam );
2818 modp32w->wCustomCommandTable = modp16->wCustomCommandTable;
2819 modp32w->wType = modp16->wType;
2820 HeapFree(GetProcessHeap(), 0, MapSL(modp16->lpstrParams));
2821 UnMapLS( modp16->lpstrParams );
2822 HeapFree( GetProcessHeap(), 0, (char *)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSW) );
2824 return WINMM_MAP_OK;
2825 case DRV_LOAD:
2826 case DRV_ENABLE:
2827 case DRV_CLOSE:
2828 case DRV_DISABLE:
2829 case DRV_FREE:
2830 case DRV_CONFIGURE:
2831 case DRV_QUERYCONFIGURE:
2832 case DRV_INSTALL:
2833 case DRV_REMOVE:
2834 case DRV_EXITSESSION:
2835 case DRV_EXITAPPLICATION:
2836 case DRV_POWER:
2837 FIXME("This is a hack\n");
2838 return WINMM_MAP_OK;
2840 default:
2841 FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2842 return WINMM_MAP_MSGERROR;
2844 return MCI_MsgMapper32WTo16_Destroy((void*)lParam, size, map, kept);
2847 void MMDRV_Init16(void)
2849 #define A(_x,_y) MMDRV_InstallMap(_x, \
2850 MMDRV_##_y##_Map16To32W, MMDRV_##_y##_UnMap16To32W, \
2851 MMDRV_##_y##_Map32WTo16, MMDRV_##_y##_UnMap32WTo16, \
2852 MMDRV_##_y##_Callback)
2853 A(MMDRV_AUX, Aux);
2854 A(MMDRV_MIXER, Mixer);
2855 A(MMDRV_MIDIIN, MidiIn);
2856 A(MMDRV_MIDIOUT, MidiOut);
2857 A(MMDRV_WAVEIN, WaveIn);
2858 A(MMDRV_WAVEOUT, WaveOut);
2859 #undef A
2861 pFnCallMMDrvFunc16 = MMDRV_CallMMDrvFunc16;
2862 pFnLoadMMDrvFunc16 = MMDRV_LoadMMDrvFunc16;
2864 pFnMciMapMsg16To32W = MCI_MapMsg16To32W;
2865 pFnMciUnMapMsg16To32W = MCI_UnMapMsg16To32W;
2866 pFnMciMapMsg32WTo16 = MCI_MapMsg32WTo16;
2867 pFnMciUnMapMsg32WTo16 = MCI_UnMapMsg32WTo16;