winmm: Avoid using sizeof() in traces.
[wine/multimedia.git] / dlls / winmm / message16.c
blob6ecf34b1209a37c4ca7ef96e87caf9c39238a58d
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 "winreg.h"
29 #include "winver.h"
30 #include "wownt32.h"
31 #include "winemm16.h"
32 #include "digitalv.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(winmm);
37 /**************************************************************************
38 * MMDRV_Callback [internal]
40 static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
42 TRACE("CB (*%08lx)(%p %08x %08lx %08lx %08lx\n",
43 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
45 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION)
47 WORD args[8];
48 /* 16 bit func, call it */
49 TRACE("Function (16 bit) !\n");
51 args[7] = HDRVR_16(hDev);
52 args[6] = uMsg;
53 args[5] = HIWORD(mld->dwClientInstance);
54 args[4] = LOWORD(mld->dwClientInstance);
55 args[3] = HIWORD(dwParam1);
56 args[2] = LOWORD(dwParam1);
57 args[1] = HIWORD(dwParam2);
58 args[0] = LOWORD(dwParam2);
59 WOWCallback16Ex( mld->dwCallback, WCB16_PASCAL, sizeof(args), args, NULL );
60 } else {
61 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
62 mld->dwClientInstance, dwParam1, dwParam2);
66 /* =================================
67 * A U X M A P P E R S
68 * ================================= */
70 /**************************************************************************
71 * MMDRV_Aux_Map16To32W [internal]
73 static WINMM_MapType MMDRV_Aux_Map16To32W (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
75 return WINMM_MAP_MSGERROR;
78 /**************************************************************************
79 * MMDRV_Aux_UnMap16To32W [internal]
81 static WINMM_MapType MMDRV_Aux_UnMap16To32W(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
83 return WINMM_MAP_MSGERROR;
86 /**************************************************************************
87 * MMDRV_Aux_Map32WTo16 [internal]
89 static WINMM_MapType MMDRV_Aux_Map32WTo16 (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
91 return WINMM_MAP_MSGERROR;
94 /**************************************************************************
95 * MMDRV_Aux_UnMap32WTo16 [internal]
97 static WINMM_MapType MMDRV_Aux_UnMap32WTo16(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
99 #if 0
100 case AUXDM_GETDEVCAPS:
101 lpCaps->wMid = ac16.wMid;
102 lpCaps->wPid = ac16.wPid;
103 lpCaps->vDriverVersion = ac16.vDriverVersion;
104 strcpy(lpCaps->szPname, ac16.szPname);
105 lpCaps->wTechnology = ac16.wTechnology;
106 lpCaps->dwSupport = ac16.dwSupport;
107 #endif
108 return WINMM_MAP_MSGERROR;
111 /**************************************************************************
112 * MMDRV_Aux_Callback [internal]
114 static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
116 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
118 FIXME("NIY\n");
119 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
122 /* =================================
123 * M I X E R M A P P E R S
124 * ================================= */
126 /**************************************************************************
127 * xMMDRV_Mixer_Map16To32W [internal]
129 static WINMM_MapType MMDRV_Mixer_Map16To32W (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
131 return WINMM_MAP_MSGERROR;
134 /**************************************************************************
135 * MMDRV_Mixer_UnMap16To32W [internal]
137 static WINMM_MapType MMDRV_Mixer_UnMap16To32W(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
139 #if 0
140 MIXERCAPSA micA;
141 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
143 if (ret == MMSYSERR_NOERROR) {
144 mixcaps->wMid = micA.wMid;
145 mixcaps->wPid = micA.wPid;
146 mixcaps->vDriverVersion = micA.vDriverVersion;
147 strcpy(mixcaps->szPname, micA.szPname);
148 mixcaps->fdwSupport = micA.fdwSupport;
149 mixcaps->cDestinations = micA.cDestinations;
151 return ret;
152 #endif
153 return WINMM_MAP_MSGERROR;
156 /**************************************************************************
157 * MMDRV_Mixer_Map32WTo16 [internal]
159 static WINMM_MapType MMDRV_Mixer_Map32WTo16 (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
161 return WINMM_MAP_MSGERROR;
164 /**************************************************************************
165 * MMDRV_Mixer_UnMap32WTo16 [internal]
167 static WINMM_MapType MMDRV_Mixer_UnMap32WTo16(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
169 return WINMM_MAP_MSGERROR;
172 /**************************************************************************
173 * MMDRV_Mixer_Callback [internal]
175 static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
177 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
179 FIXME("NIY\n");
180 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
183 /* =================================
184 * M I D I I N M A P P E R S
185 * ================================= */
187 /**************************************************************************
188 * MMDRV_MidiIn_Map16To32W [internal]
190 static WINMM_MapType MMDRV_MidiIn_Map16To32W (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
192 return WINMM_MAP_MSGERROR;
195 /**************************************************************************
196 * MMDRV_MidiIn_UnMap16To32W [internal]
198 static WINMM_MapType MMDRV_MidiIn_UnMap16To32W(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
200 return WINMM_MAP_MSGERROR;
203 /**************************************************************************
204 * MMDRV_MidiIn_Map32WTo16 [internal]
206 static WINMM_MapType MMDRV_MidiIn_Map32WTo16 (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
208 return WINMM_MAP_MSGERROR;
211 /**************************************************************************
212 * MMDRV_MidiIn_UnMap32WTo16 [internal]
214 static WINMM_MapType MMDRV_MidiIn_UnMap32WTo16(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
216 return WINMM_MAP_MSGERROR;
219 /**************************************************************************
220 * MMDRV_MidiIn_Callback [internal]
222 static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
224 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
226 switch (uMsg) {
227 case MIM_OPEN:
228 case MIM_CLOSE:
229 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
231 case MIM_DATA:
232 case MIM_MOREDATA:
233 case MIM_ERROR:
234 /* dwParam1 & dwParam2 are data, nothing to do */
235 break;
236 case MIM_LONGDATA:
237 case MIM_LONGERROR:
238 /* dwParam1 points to a MidiHdr, work to be done !!! */
239 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
240 /* initial map is: 32 => 16 */
241 LPMIDIHDR mh16 = MapSL(dwParam1);
242 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
244 dwParam1 = (DWORD)mh32;
245 mh32->dwFlags = mh16->dwFlags;
246 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
247 if (mh32->reserved >= sizeof(MIDIHDR))
248 mh32->dwOffset = mh16->dwOffset;
249 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
250 /* initial map is: 16 => 32 */
251 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
252 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
253 LPMIDIHDR mh16 = MapSL(segmh16);
255 dwParam1 = (DWORD)segmh16;
256 mh16->dwFlags = mh32->dwFlags;
257 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
258 if (mh16->reserved >= sizeof(MIDIHDR))
259 mh16->dwOffset = mh32->dwOffset;
261 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
262 break;
263 /* case MOM_POSITIONCB: */
264 default:
265 ERR("Unknown msg %u\n", uMsg);
268 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
271 /* =================================
272 * M I D I O U T M A P P E R S
273 * ================================= */
275 /**************************************************************************
276 * MMDRV_MidiOut_Map16To32W [internal]
278 static WINMM_MapType MMDRV_MidiOut_Map16To32W (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
280 WINMM_MapType ret = WINMM_MAP_MSGERROR;
282 switch (wMsg) {
283 case MODM_GETNUMDEVS:
284 case MODM_DATA:
285 case MODM_RESET:
286 case MODM_SETVOLUME:
287 ret = WINMM_MAP_OK;
288 break;
290 case MODM_OPEN:
291 case MODM_CLOSE:
292 case MODM_GETVOLUME:
293 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
294 break;
296 case MODM_GETDEVCAPS:
298 LPMIDIOUTCAPSW moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSW));
299 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
301 if (moc32) {
302 *(LPMIDIOUTCAPS16*)moc32 = moc16;
303 moc32 = (LPMIDIOUTCAPSW)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
304 *lpParam1 = (DWORD)moc32;
305 *lpParam2 = sizeof(MIDIOUTCAPSW);
307 ret = WINMM_MAP_OKMEM;
308 } else {
309 ret = WINMM_MAP_NOMEM;
312 break;
313 case MODM_PREPARE:
315 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
316 LPMIDIHDR mh16 = MapSL(*lpParam1);
318 if (mh32) {
319 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
320 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
321 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
322 mh32->dwBufferLength = mh16->dwBufferLength;
323 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
324 mh32->dwUser = mh16->dwUser;
325 mh32->dwFlags = mh16->dwFlags;
326 /* FIXME: nothing on mh32->lpNext */
327 /* could link the mh32->lpNext at this level for memory house keeping */
328 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
329 mh16->lpNext = mh32; /* for reuse in unprepare and write */
330 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
331 mh16->reserved = *lpParam2;
332 *lpParam1 = (DWORD)mh32;
333 *lpParam2 = sizeof(MIDIHDR);
335 ret = WINMM_MAP_OKMEM;
336 } else {
337 ret = WINMM_MAP_NOMEM;
340 break;
341 case MODM_UNPREPARE:
342 case MODM_LONGDATA:
344 LPMIDIHDR mh16 = MapSL(*lpParam1);
345 LPMIDIHDR mh32 = (LPMIDIHDR)mh16->lpNext;
347 *lpParam1 = (DWORD)mh32;
348 *lpParam2 = sizeof(MIDIHDR);
349 /* dwBufferLength can be reduced between prepare & write */
350 if (wMsg == MODM_LONGDATA && mh32->dwBufferLength < mh16->dwBufferLength) {
351 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
352 mh32->dwBufferLength, mh16->dwBufferLength);
353 } else
354 mh32->dwBufferLength = mh16->dwBufferLength;
355 ret = WINMM_MAP_OKMEM;
357 break;
359 case MODM_CACHEPATCHES:
360 case MODM_CACHEDRUMPATCHES:
361 default:
362 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
363 break;
365 return ret;
368 /**************************************************************************
369 * MMDRV_MidiOut_UnMap16To32W [internal]
371 static WINMM_MapType MMDRV_MidiOut_UnMap16To32W(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
373 WINMM_MapType ret = WINMM_MAP_MSGERROR;
375 switch (wMsg) {
376 case MODM_GETNUMDEVS:
377 case MODM_DATA:
378 case MODM_RESET:
379 case MODM_SETVOLUME:
380 ret = WINMM_MAP_OK;
381 break;
383 case MODM_OPEN:
384 case MODM_CLOSE:
385 case MODM_GETVOLUME:
386 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
387 break;
389 case MODM_GETDEVCAPS:
391 LPMIDIOUTCAPSW moc32 = (LPMIDIOUTCAPSW)(*lpParam1);
392 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
394 moc16->wMid = moc32->wMid;
395 moc16->wPid = moc32->wPid;
396 moc16->vDriverVersion = moc32->vDriverVersion;
397 WideCharToMultiByte( CP_ACP, 0, moc32->szPname, -1, moc16->szPname,
398 sizeof(moc16->szPname), NULL, NULL );
399 moc16->wTechnology = moc32->wTechnology;
400 moc16->wVoices = moc32->wVoices;
401 moc16->wNotes = moc32->wNotes;
402 moc16->wChannelMask = moc32->wChannelMask;
403 moc16->dwSupport = moc32->dwSupport;
404 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
405 ret = WINMM_MAP_OK;
407 break;
408 case MODM_PREPARE:
409 case MODM_UNPREPARE:
410 case MODM_LONGDATA:
412 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
413 LPMIDIHDR mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
415 assert(mh16->lpNext == mh32);
416 mh16->dwBufferLength = mh32->dwBufferLength;
417 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
418 mh16->dwUser = mh32->dwUser;
419 mh16->dwFlags = mh32->dwFlags;
420 if (mh16->reserved >= sizeof(MIDIHDR))
421 mh16->dwOffset = mh32->dwOffset;
423 if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
424 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
425 mh16->lpNext = 0;
427 ret = WINMM_MAP_OK;
429 break;
431 case MODM_CACHEPATCHES:
432 case MODM_CACHEDRUMPATCHES:
433 default:
434 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
435 break;
437 return ret;
440 /**************************************************************************
441 * MMDRV_MidiOut_Map32WTo16 [internal]
443 static WINMM_MapType MMDRV_MidiOut_Map32WTo16 (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
445 WINMM_MapType ret = WINMM_MAP_MSGERROR;
447 switch (wMsg) {
448 case MODM_CLOSE:
449 case MODM_GETNUMDEVS:
450 case MODM_DATA:
451 case MODM_RESET:
452 case MODM_SETVOLUME:
453 ret = WINMM_MAP_OK;
454 break;
455 case MODM_GETDEVCAPS:
457 LPMIDIOUTCAPSW moc32 = (LPMIDIOUTCAPSW)*lpParam1;
458 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSW)+sizeof(MIDIOUTCAPS16));
460 if (ptr) {
461 *(LPMIDIOUTCAPSW*)ptr = moc32;
462 ret = WINMM_MAP_OKMEM;
463 } else {
464 ret = WINMM_MAP_NOMEM;
466 *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSW);
467 *lpParam2 = sizeof(MIDIOUTCAPS16);
469 break;
470 case MODM_PREPARE:
472 LPMIDIHDR mh32 = (LPMIDIHDR)*lpParam1;
473 LPMIDIHDR mh16;
474 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
475 sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
477 if (ptr) {
478 *(LPMIDIHDR*)ptr = mh32;
479 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
480 *lpParam1 = MapLS(mh16);
481 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
482 /* data will be copied on WODM_WRITE */
483 mh16->dwBufferLength = mh32->dwBufferLength;
484 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
485 mh16->dwUser = mh32->dwUser;
486 mh16->dwFlags = mh32->dwFlags;
487 /* FIXME: nothing on mh32->lpNext */
488 /* could link the mh32->lpNext at this level for memory house keeping */
489 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
491 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
492 mh32->reserved = *lpParam2;
494 TRACE("mh16=%08lx mh16->lpData=%p mh32->buflen=%u mh32->lpData=%p\n",
495 *lpParam1, mh16->lpData, mh32->dwBufferLength, mh32->lpData);
496 *lpParam2 = sizeof(MIDIHDR);
498 ret = WINMM_MAP_OKMEM;
499 } else {
500 ret = WINMM_MAP_NOMEM;
503 break;
504 case MODM_UNPREPARE:
505 case MODM_LONGDATA:
507 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
508 LPMIDIHDR mh16 = (LPMIDIHDR)mh32->lpNext;
509 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
511 assert(*(LPMIDIHDR*)ptr == mh32);
513 if (wMsg == MODM_LONGDATA)
514 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
516 *lpParam1 = MapLS(mh16);
517 *lpParam2 = sizeof(MIDIHDR);
518 TRACE("mh16=%08lx mh16->lpData=%p mh32->buflen=%u mh32->lpData=%p\n",
519 *lpParam1, mh16->lpData, mh32->dwBufferLength, mh32->lpData);
521 /* dwBufferLength can be reduced between prepare & write */
522 if (wMsg == MODM_LONGDATA && mh16->dwBufferLength < mh32->dwBufferLength) {
523 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
524 mh16->dwBufferLength, mh32->dwBufferLength);
525 } else
526 mh16->dwBufferLength = mh32->dwBufferLength;
527 ret = WINMM_MAP_OKMEM;
529 break;
530 case MODM_OPEN:
532 LPMIDIOPENDESC mod32 = (LPMIDIOPENDESC)*lpParam1;
533 LPVOID ptr;
534 LPMIDIOPENDESC16 mod16;
536 /* allocated data are mapped as follows:
537 LPMIDIOPENDESC ptr to orig lParam1
538 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
539 DWORD dwUser passed to driver
540 MIDIOPENDESC16 mod16: openDesc passed to driver
541 MIDIOPENSTRMID cIds
543 ptr = HeapAlloc( GetProcessHeap(), 0,
544 sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
545 mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
547 if (ptr) {
548 SEGPTR segptr = MapLS(ptr);
549 *(LPMIDIOPENDESC*)ptr = mod32;
550 *(LPDWORD)((char*)ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
551 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
553 mod16->hMidi = HMIDI_16(mod32->hMidi);
554 mod16->dwCallback = mod32->dwCallback;
555 mod16->dwInstance = mod32->dwInstance;
556 mod16->dnDevNode = mod32->dnDevNode;
557 mod16->cIds = mod32->cIds;
558 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
560 *lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
561 *lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
563 ret = WINMM_MAP_OKMEM;
564 } else {
565 ret = WINMM_MAP_NOMEM;
568 break;
569 case MODM_GETVOLUME:
570 case MODM_CACHEPATCHES:
571 case MODM_CACHEDRUMPATCHES:
572 default:
573 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
574 break;
576 return ret;
579 /**************************************************************************
580 * MMDRV_MidiOut_UnMap32WTo16 [internal]
582 static WINMM_MapType MMDRV_MidiOut_UnMap32WTo16(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
584 WINMM_MapType ret = WINMM_MAP_MSGERROR;
586 switch (wMsg) {
587 case MODM_CLOSE:
588 case MODM_GETNUMDEVS:
589 case MODM_DATA:
590 case MODM_RESET:
591 case MODM_SETVOLUME:
592 ret = WINMM_MAP_OK;
593 break;
594 case MODM_GETDEVCAPS:
596 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
597 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSW);
598 LPMIDIOUTCAPSW moc32 = *(LPMIDIOUTCAPSW*)ptr;
600 moc32->wMid = moc16->wMid;
601 moc32->wPid = moc16->wPid;
602 moc32->vDriverVersion = moc16->vDriverVersion;
603 WideCharToMultiByte( CP_ACP, 0, moc32->szPname, -1, moc16->szPname,
604 sizeof(moc16->szPname), NULL, NULL );
605 moc32->wTechnology = moc16->wTechnology;
606 moc32->wVoices = moc16->wVoices;
607 moc32->wNotes = moc16->wNotes;
608 moc32->wChannelMask = moc16->wChannelMask;
609 moc32->dwSupport = moc16->dwSupport;
610 UnMapLS( *lpParam1 );
611 HeapFree( GetProcessHeap(), 0, ptr );
612 ret = WINMM_MAP_OK;
614 break;
615 case MODM_PREPARE:
616 case MODM_UNPREPARE:
617 case MODM_LONGDATA:
619 LPMIDIHDR mh16 = MapSL(*lpParam1);
620 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
621 LPMIDIHDR mh32 = *(LPMIDIHDR*)ptr;
623 assert(mh32->lpNext == (LPMIDIHDR)mh16);
624 UnMapLS( *lpParam1 );
625 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
626 mh32->dwUser = mh16->dwUser;
627 mh32->dwFlags = mh16->dwFlags;
629 if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
630 HeapFree( GetProcessHeap(), 0, ptr );
631 mh32->lpNext = 0;
633 ret = WINMM_MAP_OK;
635 break;
636 case MODM_OPEN:
638 LPMIDIOPENDESC16 mod16 = MapSL(*lpParam1);
639 LPSTR ptr = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
640 UnMapLS( *lpParam1 );
641 **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
643 HeapFree( GetProcessHeap(), 0, ptr );
644 ret = WINMM_MAP_OK;
646 break;
647 case MODM_GETVOLUME:
648 case MODM_CACHEPATCHES:
649 case MODM_CACHEDRUMPATCHES:
650 default:
651 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
652 break;
654 return ret;
657 /**************************************************************************
658 * MMDRV_MidiOut_Callback [internal]
660 static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
662 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
664 switch (uMsg) {
665 case MOM_OPEN:
666 case MOM_CLOSE:
667 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
668 break;
669 case MOM_DONE:
670 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
671 /* initial map is: 32 => 16 */
672 LPMIDIHDR mh16 = MapSL(dwParam1);
673 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
675 dwParam1 = (DWORD)mh32;
676 mh32->dwFlags = mh16->dwFlags;
677 mh32->dwOffset = mh16->dwOffset;
678 if (mh32->reserved >= sizeof(MIDIHDR))
679 mh32->dwOffset = mh16->dwOffset;
680 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
681 /* initial map is: 16 => 32 */
682 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
683 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
684 LPMIDIHDR mh16 = MapSL(segmh16);
686 dwParam1 = (DWORD)segmh16;
687 mh16->dwFlags = mh32->dwFlags;
688 if (mh16->reserved >= sizeof(MIDIHDR))
689 mh16->dwOffset = mh32->dwOffset;
691 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
692 break;
693 /* case MOM_POSITIONCB: */
694 default:
695 ERR("Unknown msg %u\n", uMsg);
698 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
701 /* =================================
702 * W A V E I N M A P P E R S
703 * ================================= */
705 /**************************************************************************
706 * MMDRV_WaveIn_Map16To32W [internal]
708 static WINMM_MapType MMDRV_WaveIn_Map16To32W (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
710 WINMM_MapType ret = WINMM_MAP_MSGERROR;
712 switch (wMsg) {
713 case WIDM_GETNUMDEVS:
714 case WIDM_RESET:
715 case WIDM_START:
716 case WIDM_STOP:
717 ret = WINMM_MAP_OK;
718 break;
719 case WIDM_OPEN:
720 case WIDM_CLOSE:
721 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
722 break;
723 case WIDM_GETDEVCAPS:
725 LPWAVEINCAPSW wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSW));
726 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
728 if (wic32) {
729 *(LPWAVEINCAPS16*)wic32 = wic16;
730 wic32 = (LPWAVEINCAPSW)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
731 *lpParam1 = (DWORD)wic32;
732 *lpParam2 = sizeof(WAVEINCAPSW);
734 ret = WINMM_MAP_OKMEM;
735 } else {
736 ret = WINMM_MAP_NOMEM;
739 break;
740 case WIDM_GETPOS:
742 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
743 LPMMTIME16 mmt16 = MapSL(*lpParam1);
745 if (mmt32) {
746 *(LPMMTIME16*)mmt32 = mmt16;
747 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
749 mmt32->wType = mmt16->wType;
750 *lpParam1 = (DWORD)mmt32;
751 *lpParam2 = sizeof(MMTIME);
753 ret = WINMM_MAP_OKMEM;
754 } else {
755 ret = WINMM_MAP_NOMEM;
758 break;
759 case WIDM_PREPARE:
761 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
762 LPWAVEHDR wh16 = MapSL(*lpParam1);
764 if (wh32) {
765 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
766 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
767 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
768 wh32->dwBufferLength = wh16->dwBufferLength;
769 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
770 wh32->dwUser = wh16->dwUser;
771 wh32->dwFlags = wh16->dwFlags;
772 wh32->dwLoops = wh16->dwLoops;
773 /* FIXME: nothing on wh32->lpNext */
774 /* could link the wh32->lpNext at this level for memory house keeping */
775 wh16->lpNext = wh32; /* for reuse in unprepare and write */
776 *lpParam1 = (DWORD)wh32;
777 *lpParam2 = sizeof(WAVEHDR);
779 ret = WINMM_MAP_OKMEM;
780 } else {
781 ret = WINMM_MAP_NOMEM;
784 break;
785 case WIDM_ADDBUFFER:
786 case WIDM_UNPREPARE:
788 LPWAVEHDR wh16 = MapSL(*lpParam1);
789 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
791 *lpParam1 = (DWORD)wh32;
792 *lpParam2 = sizeof(WAVEHDR);
793 /* dwBufferLength can be reduced between prepare & write */
794 if (wMsg == WIDM_ADDBUFFER && wh32->dwBufferLength < wh16->dwBufferLength) {
795 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
796 wh32->dwBufferLength, wh16->dwBufferLength);
797 } else
798 wh32->dwBufferLength = wh16->dwBufferLength;
799 ret = WINMM_MAP_OKMEM;
801 break;
802 case WIDM_MAPPER_STATUS:
803 /* just a single DWORD */
804 *lpParam2 = (DWORD)MapSL(*lpParam2);
805 ret = WINMM_MAP_OK;
806 break;
807 default:
808 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
809 break;
811 return ret;
814 /**************************************************************************
815 * MMDRV_WaveIn_UnMap16To32W [internal]
817 static WINMM_MapType MMDRV_WaveIn_UnMap16To32W(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
819 WINMM_MapType ret = WINMM_MAP_MSGERROR;
821 switch (wMsg) {
822 case WIDM_GETNUMDEVS:
823 case WIDM_RESET:
824 case WIDM_START:
825 case WIDM_STOP:
826 case WIDM_MAPPER_STATUS:
827 ret = WINMM_MAP_OK;
828 break;
829 case WIDM_OPEN:
830 case WIDM_CLOSE:
831 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
832 break;
833 case WIDM_GETDEVCAPS:
835 LPWAVEINCAPSW wic32 = (LPWAVEINCAPSW)(*lpParam1);
836 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
838 wic16->wMid = wic32->wMid;
839 wic16->wPid = wic32->wPid;
840 wic16->vDriverVersion = wic32->vDriverVersion;
841 WideCharToMultiByte( CP_ACP, 0, wic32->szPname, -1, wic16->szPname,
842 sizeof(wic16->szPname), NULL, NULL );
843 wic16->dwFormats = wic32->dwFormats;
844 wic16->wChannels = wic32->wChannels;
845 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
846 ret = WINMM_MAP_OK;
848 break;
849 case WIDM_GETPOS:
851 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
852 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
854 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
855 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
856 ret = WINMM_MAP_OK;
858 break;
859 case WIDM_ADDBUFFER:
860 case WIDM_PREPARE:
861 case WIDM_UNPREPARE:
863 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
864 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
866 assert(wh16->lpNext == wh32);
867 wh16->dwBufferLength = wh32->dwBufferLength;
868 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
869 wh16->dwUser = wh32->dwUser;
870 wh16->dwFlags = wh32->dwFlags;
871 wh16->dwLoops = wh32->dwLoops;
873 if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
874 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
875 wh16->lpNext = 0;
877 ret = WINMM_MAP_OK;
879 break;
880 default:
881 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
882 break;
884 return ret;
887 /**************************************************************************
888 * MMDRV_WaveIn_Map32WTo16 [internal]
890 static WINMM_MapType MMDRV_WaveIn_Map32WTo16 (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
892 WINMM_MapType ret = WINMM_MAP_MSGERROR;
894 switch (wMsg) {
895 case WIDM_CLOSE:
896 case WIDM_GETNUMDEVS:
897 case WIDM_RESET:
898 case WIDM_START:
899 case WIDM_STOP:
900 ret = WINMM_MAP_OK;
901 break;
903 case WIDM_OPEN:
905 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
906 int sz = sizeof(WAVEFORMATEX);
907 LPVOID ptr;
908 LPWAVEOPENDESC16 wod16;
910 /* allocated data are mapped as follows:
911 LPWAVEOPENDESC ptr to orig lParam1
912 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
913 DWORD dwUser passed to driver
914 WAVEOPENDESC16 wod16: openDesc passed to driver
915 WAVEFORMATEX openDesc->lpFormat passed to driver
916 xxx extra bytes to WAVEFORMATEX
918 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
919 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
920 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
923 ptr = HeapAlloc( GetProcessHeap(), 0,
924 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
926 if (ptr) {
927 SEGPTR seg_ptr = MapLS( ptr );
928 *(LPWAVEOPENDESC*)ptr = wod32;
929 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
930 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
932 wod16->hWave = HWAVE_16(wod32->hWave);
933 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
934 memcpy(wod16 + 1, wod32->lpFormat, sz);
936 wod16->dwCallback = wod32->dwCallback;
937 wod16->dwInstance = wod32->dwInstance;
938 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
939 wod16->dnDevNode = wod32->dnDevNode;
941 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
942 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
944 ret = WINMM_MAP_OKMEM;
945 } else {
946 ret = WINMM_MAP_NOMEM;
949 break;
950 case WIDM_PREPARE:
952 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
953 LPWAVEHDR wh16;
954 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
955 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
957 if (ptr) {
958 SEGPTR seg_ptr = MapLS( ptr );
959 *(LPWAVEHDR*)ptr = wh32;
960 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
961 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
962 /* data will be copied on WODM_WRITE */
963 wh16->dwBufferLength = wh32->dwBufferLength;
964 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
965 wh16->dwUser = wh32->dwUser;
966 wh16->dwFlags = wh32->dwFlags;
967 wh16->dwLoops = wh32->dwLoops;
968 /* FIXME: nothing on wh32->lpNext */
969 /* could link the wh32->lpNext at this level for memory house keeping */
970 wh32->lpNext = wh16; /* for reuse in unprepare and write */
971 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
972 *lpParam2 = sizeof(WAVEHDR);
973 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
974 *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
976 ret = WINMM_MAP_OKMEM;
977 } else {
978 ret = WINMM_MAP_NOMEM;
981 break;
982 case WIDM_ADDBUFFER:
983 case WIDM_UNPREPARE:
985 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
986 LPWAVEHDR wh16 = wh32->lpNext;
987 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
988 SEGPTR seg_ptr = MapLS( ptr );
990 assert(*(LPWAVEHDR*)ptr == wh32);
992 if (wMsg == WIDM_ADDBUFFER)
993 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
995 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
996 *lpParam2 = sizeof(WAVEHDR);
997 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
998 *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
1000 /* dwBufferLength can be reduced between prepare & write */
1001 if (wMsg == WIDM_ADDBUFFER && wh16->dwBufferLength < wh32->dwBufferLength) {
1002 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1003 wh16->dwBufferLength, wh32->dwBufferLength);
1004 } else
1005 wh16->dwBufferLength = wh32->dwBufferLength;
1006 ret = WINMM_MAP_OKMEM;
1008 break;
1009 case WIDM_GETDEVCAPS:
1011 LPWAVEINCAPSW wic32 = (LPWAVEINCAPSW)*lpParam1;
1012 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSW) + sizeof(WAVEINCAPS16));
1014 if (ptr) {
1015 *(LPWAVEINCAPSW*)ptr = wic32;
1016 ret = WINMM_MAP_OKMEM;
1017 } else {
1018 ret = WINMM_MAP_NOMEM;
1020 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSW);
1021 *lpParam2 = sizeof(WAVEINCAPS16);
1023 break;
1024 case WIDM_GETPOS:
1026 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1027 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1028 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1030 if (ptr) {
1031 *(LPMMTIME*)ptr = mmt32;
1032 mmt16->wType = mmt32->wType;
1033 ret = WINMM_MAP_OKMEM;
1034 } else {
1035 ret = WINMM_MAP_NOMEM;
1037 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1038 *lpParam2 = sizeof(MMTIME16);
1040 break;
1041 case DRVM_MAPPER_STATUS:
1043 LPDWORD p32 = (LPDWORD)*lpParam2;
1044 *lpParam2 = MapLS(p32);
1045 ret = WINMM_MAP_OKMEM;
1047 break;
1048 default:
1049 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1050 break;
1052 return ret;
1055 /**************************************************************************
1056 * MMDRV_WaveIn_UnMap32WTo16 [internal]
1058 static WINMM_MapType MMDRV_WaveIn_UnMap32WTo16(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1060 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1062 switch (wMsg) {
1063 case WIDM_CLOSE:
1064 case WIDM_GETNUMDEVS:
1065 case WIDM_RESET:
1066 case WIDM_START:
1067 case WIDM_STOP:
1068 ret = WINMM_MAP_OK;
1069 break;
1071 case WIDM_OPEN:
1073 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1074 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1075 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1077 UnMapLS( *lpParam1 );
1078 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1079 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1080 HeapFree( GetProcessHeap(), 0, ptr );
1081 ret = WINMM_MAP_OK;
1083 break;
1085 case WIDM_ADDBUFFER:
1086 case WIDM_PREPARE:
1087 case WIDM_UNPREPARE:
1089 LPWAVEHDR wh16 = MapSL(*lpParam1);
1090 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1091 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1093 assert(wh32->lpNext == wh16);
1094 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1095 wh32->dwUser = wh16->dwUser;
1096 wh32->dwFlags = wh16->dwFlags;
1097 wh32->dwLoops = wh16->dwLoops;
1098 UnMapLS( *lpParam1 );
1100 if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1101 HeapFree( GetProcessHeap(), 0, ptr );
1102 wh32->lpNext = 0;
1104 ret = WINMM_MAP_OK;
1106 break;
1107 case WIDM_GETDEVCAPS:
1109 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
1110 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSW);
1111 LPWAVEINCAPSW wic32 = *(LPWAVEINCAPSW*)ptr;
1113 wic32->wMid = wic16->wMid;
1114 wic32->wPid = wic16->wPid;
1115 wic32->vDriverVersion = wic16->vDriverVersion;
1116 WideCharToMultiByte( CP_ACP, 0, wic32->szPname, -1, wic16->szPname,
1117 sizeof(wic16->szPname), NULL, NULL );
1118 wic32->dwFormats = wic16->dwFormats;
1119 wic32->wChannels = wic16->wChannels;
1120 UnMapLS( *lpParam1 );
1121 HeapFree( GetProcessHeap(), 0, ptr );
1122 ret = WINMM_MAP_OK;
1124 break;
1125 case WIDM_GETPOS:
1127 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1128 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1129 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1131 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1132 UnMapLS( *lpParam1 );
1133 HeapFree( GetProcessHeap(), 0, ptr );
1134 ret = WINMM_MAP_OK;
1136 break;
1137 case DRVM_MAPPER_STATUS:
1139 UnMapLS( *lpParam2 );
1140 ret = WINMM_MAP_OK;
1142 break;
1143 default:
1144 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1145 break;
1147 return ret;
1150 /**************************************************************************
1151 * MMDRV_WaveIn_Callback [internal]
1153 static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1155 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1157 switch (uMsg) {
1158 case WIM_OPEN:
1159 case WIM_CLOSE:
1160 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1161 break;
1162 case WIM_DATA:
1163 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1164 /* initial map is: 32 => 16 */
1165 LPWAVEHDR wh16 = MapSL(dwParam1);
1166 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1168 dwParam1 = (DWORD)wh32;
1169 wh32->dwFlags = wh16->dwFlags;
1170 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1171 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1172 /* initial map is: 16 => 32 */
1173 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1174 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1175 LPWAVEHDR wh16 = MapSL(segwh16);
1177 dwParam1 = (DWORD)segwh16;
1178 wh16->dwFlags = wh32->dwFlags;
1179 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1181 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1182 break;
1183 default:
1184 ERR("Unknown msg %u\n", uMsg);
1187 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1190 /* =================================
1191 * W A V E O U T M A P P E R S
1192 * ================================= */
1194 /**************************************************************************
1195 * MMDRV_WaveOut_Map16To32W [internal]
1197 static WINMM_MapType MMDRV_WaveOut_Map16To32W (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
1199 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1201 switch (wMsg) {
1202 /* nothing to do */
1203 case WODM_BREAKLOOP:
1204 case WODM_CLOSE:
1205 case WODM_GETNUMDEVS:
1206 case WODM_PAUSE:
1207 case WODM_RESET:
1208 case WODM_RESTART:
1209 case WODM_SETPITCH:
1210 case WODM_SETPLAYBACKRATE:
1211 case WODM_SETVOLUME:
1212 ret = WINMM_MAP_OK;
1213 break;
1215 case WODM_GETPITCH:
1216 case WODM_GETPLAYBACKRATE:
1217 case WODM_GETVOLUME:
1218 case WODM_OPEN:
1219 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1220 break;
1222 case WODM_GETDEVCAPS:
1224 LPWAVEOUTCAPSW woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSW));
1225 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1227 if (woc32) {
1228 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1229 woc32 = (LPWAVEOUTCAPSW)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1230 *lpParam1 = (DWORD)woc32;
1231 *lpParam2 = sizeof(WAVEOUTCAPSW);
1233 ret = WINMM_MAP_OKMEM;
1234 } else {
1235 ret = WINMM_MAP_NOMEM;
1238 break;
1239 case WODM_GETPOS:
1241 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1242 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1244 if (mmt32) {
1245 *(LPMMTIME16*)mmt32 = mmt16;
1246 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1248 mmt32->wType = mmt16->wType;
1249 *lpParam1 = (DWORD)mmt32;
1250 *lpParam2 = sizeof(MMTIME);
1252 ret = WINMM_MAP_OKMEM;
1253 } else {
1254 ret = WINMM_MAP_NOMEM;
1257 break;
1258 case WODM_PREPARE:
1260 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1261 LPWAVEHDR wh16 = MapSL(*lpParam1);
1263 if (wh32) {
1264 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1265 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1266 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1267 wh32->dwBufferLength = wh16->dwBufferLength;
1268 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1269 wh32->dwUser = wh16->dwUser;
1270 wh32->dwFlags = wh16->dwFlags;
1271 wh32->dwLoops = wh16->dwLoops;
1272 /* FIXME: nothing on wh32->lpNext */
1273 /* could link the wh32->lpNext at this level for memory house keeping */
1274 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1275 *lpParam1 = (DWORD)wh32;
1276 *lpParam2 = sizeof(WAVEHDR);
1278 ret = WINMM_MAP_OKMEM;
1279 } else {
1280 ret = WINMM_MAP_NOMEM;
1283 break;
1284 case WODM_UNPREPARE:
1285 case WODM_WRITE:
1287 LPWAVEHDR wh16 = MapSL(*lpParam1);
1288 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1290 *lpParam1 = (DWORD)wh32;
1291 *lpParam2 = sizeof(WAVEHDR);
1292 /* dwBufferLength can be reduced between prepare & write */
1293 if (wMsg == WODM_WRITE && wh32->dwBufferLength < wh16->dwBufferLength) {
1294 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1295 wh32->dwBufferLength, wh16->dwBufferLength);
1296 } else
1297 wh32->dwBufferLength = wh16->dwBufferLength;
1298 ret = WINMM_MAP_OKMEM;
1300 break;
1301 case WODM_MAPPER_STATUS:
1302 *lpParam2 = (DWORD)MapSL(*lpParam2);
1303 ret = WINMM_MAP_OK;
1304 break;
1305 default:
1306 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1307 break;
1309 return ret;
1312 /**************************************************************************
1313 * MMDRV_WaveOut_UnMap16To32W [internal]
1315 static WINMM_MapType MMDRV_WaveOut_UnMap16To32W(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1317 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1319 switch (wMsg) {
1320 /* nothing to do */
1321 case WODM_BREAKLOOP:
1322 case WODM_CLOSE:
1323 case WODM_GETNUMDEVS:
1324 case WODM_PAUSE:
1325 case WODM_RESET:
1326 case WODM_RESTART:
1327 case WODM_SETPITCH:
1328 case WODM_SETPLAYBACKRATE:
1329 case WODM_SETVOLUME:
1330 case WODM_MAPPER_STATUS:
1331 ret = WINMM_MAP_OK;
1332 break;
1334 case WODM_GETPITCH:
1335 case WODM_GETPLAYBACKRATE:
1336 case WODM_GETVOLUME:
1337 case WODM_OPEN:
1338 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1339 break;
1341 case WODM_GETDEVCAPS:
1343 LPWAVEOUTCAPSW woc32 = (LPWAVEOUTCAPSW)(*lpParam1);
1344 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1346 woc16->wMid = woc32->wMid;
1347 woc16->wPid = woc32->wPid;
1348 woc16->vDriverVersion = woc32->vDriverVersion;
1349 WideCharToMultiByte( CP_ACP, 0, woc32->szPname, -1, woc16->szPname,
1350 sizeof(woc16->szPname), NULL, NULL );
1351 woc16->dwFormats = woc32->dwFormats;
1352 woc16->wChannels = woc32->wChannels;
1353 woc16->dwSupport = woc32->dwSupport;
1354 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1355 ret = WINMM_MAP_OK;
1357 break;
1358 case WODM_GETPOS:
1360 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1361 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1363 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1364 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1365 ret = WINMM_MAP_OK;
1367 break;
1368 case WODM_PREPARE:
1369 case WODM_UNPREPARE:
1370 case WODM_WRITE:
1372 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1373 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1375 assert(wh16->lpNext == wh32);
1376 wh16->dwBufferLength = wh32->dwBufferLength;
1377 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1378 wh16->dwUser = wh32->dwUser;
1379 wh16->dwFlags = wh32->dwFlags;
1380 wh16->dwLoops = wh32->dwLoops;
1382 if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1383 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1384 wh16->lpNext = 0;
1386 ret = WINMM_MAP_OK;
1388 break;
1389 default:
1390 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1391 break;
1393 return ret;
1396 /**************************************************************************
1397 * MMDRV_WaveOut_Map32WTo16 [internal]
1399 static WINMM_MapType MMDRV_WaveOut_Map32WTo16 (UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2)
1401 WINMM_MapType ret;
1403 switch (wMsg) {
1404 /* nothing to do */
1405 case WODM_BREAKLOOP:
1406 case WODM_CLOSE:
1407 case WODM_GETNUMDEVS:
1408 case WODM_PAUSE:
1409 case WODM_RESET:
1410 case WODM_RESTART:
1411 case WODM_SETPITCH:
1412 case WODM_SETPLAYBACKRATE:
1413 case WODM_SETVOLUME:
1414 ret = WINMM_MAP_OK;
1415 break;
1417 case WODM_GETDEVCAPS:
1419 LPWAVEOUTCAPSW woc32 = (LPWAVEOUTCAPSW)*lpParam1;
1420 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1421 sizeof(LPWAVEOUTCAPSW) + sizeof(WAVEOUTCAPS16));
1423 if (ptr) {
1424 *(LPWAVEOUTCAPSW*)ptr = woc32;
1425 ret = WINMM_MAP_OKMEM;
1426 } else {
1427 ret = WINMM_MAP_NOMEM;
1429 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSW);
1430 *lpParam2 = sizeof(WAVEOUTCAPS16);
1432 break;
1433 case WODM_GETPITCH:
1434 FIXME("NIY: no conversion yet\n");
1435 ret = WINMM_MAP_MSGERROR;
1436 break;
1437 case WODM_GETPLAYBACKRATE:
1438 FIXME("NIY: no conversion yet\n");
1439 ret = WINMM_MAP_MSGERROR;
1440 break;
1441 case WODM_GETPOS:
1443 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1444 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1445 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1447 if (ptr) {
1448 *(LPMMTIME*)ptr = mmt32;
1449 mmt16->wType = mmt32->wType;
1450 ret = WINMM_MAP_OKMEM;
1451 } else {
1452 ret = WINMM_MAP_NOMEM;
1454 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1455 *lpParam2 = sizeof(MMTIME16);
1457 break;
1458 case WODM_GETVOLUME:
1459 FIXME("NIY: no conversion yet\n");
1460 ret = WINMM_MAP_MSGERROR;
1461 break;
1462 case WODM_OPEN:
1464 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1465 int sz = sizeof(WAVEFORMATEX);
1466 LPVOID ptr;
1467 LPWAVEOPENDESC16 wod16;
1469 /* allocated data are mapped as follows:
1470 LPWAVEOPENDESC ptr to orig lParam1
1471 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1472 DWORD dwUser passed to driver
1473 WAVEOPENDESC16 wod16: openDesc passed to driver
1474 WAVEFORMATEX openDesc->lpFormat passed to driver
1475 xxx extra bytes to WAVEFORMATEX
1477 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1478 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1479 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1482 ptr = HeapAlloc( GetProcessHeap(), 0,
1483 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1485 if (ptr) {
1486 SEGPTR seg_ptr = MapLS( ptr );
1487 *(LPWAVEOPENDESC*)ptr = wod32;
1488 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1489 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1491 wod16->hWave = HWAVE_16(wod32->hWave);
1492 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1493 memcpy(wod16 + 1, wod32->lpFormat, sz);
1495 wod16->dwCallback = wod32->dwCallback;
1496 wod16->dwInstance = wod32->dwInstance;
1497 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1498 wod16->dnDevNode = wod32->dnDevNode;
1500 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1501 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1503 ret = WINMM_MAP_OKMEM;
1504 } else {
1505 ret = WINMM_MAP_NOMEM;
1508 break;
1509 case WODM_PREPARE:
1511 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1512 LPWAVEHDR wh16;
1513 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1514 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1516 if (ptr) {
1517 SEGPTR seg_ptr = MapLS( ptr );
1518 *(LPWAVEHDR*)ptr = wh32;
1519 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1520 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1521 /* data will be copied on WODM_WRITE */
1522 wh16->dwBufferLength = wh32->dwBufferLength;
1523 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1524 wh16->dwUser = wh32->dwUser;
1525 wh16->dwFlags = wh32->dwFlags;
1526 wh16->dwLoops = wh32->dwLoops;
1527 /* FIXME: nothing on wh32->lpNext */
1528 /* could link the wh32->lpNext at this level for memory house keeping */
1529 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1530 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1531 *lpParam2 = sizeof(WAVEHDR);
1532 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
1533 *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
1535 ret = WINMM_MAP_OKMEM;
1536 } else {
1537 ret = WINMM_MAP_NOMEM;
1540 break;
1541 case WODM_UNPREPARE:
1542 case WODM_WRITE:
1544 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1545 LPWAVEHDR wh16 = wh32->lpNext;
1546 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1547 SEGPTR seg_ptr = MapLS( ptr );
1549 assert(*(LPWAVEHDR*)ptr == wh32);
1551 if (wMsg == WODM_WRITE)
1552 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1554 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1555 *lpParam2 = sizeof(WAVEHDR);
1556 TRACE("wh16=%08lx wh16->lpData=%p wh32->buflen=%u wh32->lpData=%p\n",
1557 *lpParam1, wh16->lpData, wh32->dwBufferLength, wh32->lpData);
1559 /* dwBufferLength can be reduced between prepare & write */
1560 if (wMsg == WODM_WRITE && wh16->dwBufferLength < wh32->dwBufferLength) {
1561 ERR("Size of buffer has been increased from %d to %d, keeping initial value\n",
1562 wh16->dwBufferLength, wh32->dwBufferLength);
1563 } else
1564 wh16->dwBufferLength = wh32->dwBufferLength;
1565 ret = WINMM_MAP_OKMEM;
1567 break;
1568 case DRVM_MAPPER_STATUS:
1570 LPDWORD p32 = (LPDWORD)*lpParam2;
1571 *lpParam2 = MapLS(p32);
1572 ret = WINMM_MAP_OKMEM;
1574 break;
1575 default:
1576 FIXME("NIY: no conversion yet\n");
1577 ret = WINMM_MAP_MSGERROR;
1578 break;
1580 return ret;
1583 /**************************************************************************
1584 * MMDRV_WaveOut_UnMap32WTo16 [internal]
1586 static WINMM_MapType MMDRV_WaveOut_UnMap32WTo16(UINT wMsg, LPDWORD lpdwUser, DWORD_PTR* lpParam1, DWORD_PTR* lpParam2, MMRESULT fn_ret)
1588 WINMM_MapType ret;
1590 switch (wMsg) {
1591 /* nothing to do */
1592 case WODM_BREAKLOOP:
1593 case WODM_CLOSE:
1594 case WODM_GETNUMDEVS:
1595 case WODM_PAUSE:
1596 case WODM_RESET:
1597 case WODM_RESTART:
1598 case WODM_SETPITCH:
1599 case WODM_SETPLAYBACKRATE:
1600 case WODM_SETVOLUME:
1601 ret = WINMM_MAP_OK;
1602 break;
1604 case WODM_GETDEVCAPS:
1606 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1607 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSW);
1608 LPWAVEOUTCAPSW woc32 = *(LPWAVEOUTCAPSW*)ptr;
1610 woc32->wMid = woc16->wMid;
1611 woc32->wPid = woc16->wPid;
1612 woc32->vDriverVersion = woc16->vDriverVersion;
1613 WideCharToMultiByte( CP_ACP, 0, woc32->szPname, -1, woc16->szPname,
1614 sizeof(woc16->szPname), NULL, NULL );
1615 woc32->dwFormats = woc16->dwFormats;
1616 woc32->wChannels = woc16->wChannels;
1617 woc32->dwSupport = woc16->dwSupport;
1618 UnMapLS( *lpParam1 );
1619 HeapFree( GetProcessHeap(), 0, ptr );
1620 ret = WINMM_MAP_OK;
1622 break;
1623 case WODM_GETPITCH:
1624 FIXME("NIY: no conversion yet\n");
1625 ret = WINMM_MAP_MSGERROR;
1626 break;
1627 case WODM_GETPLAYBACKRATE:
1628 FIXME("NIY: no conversion yet\n");
1629 ret = WINMM_MAP_MSGERROR;
1630 break;
1631 case WODM_GETPOS:
1633 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1634 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1635 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1637 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1638 UnMapLS( *lpParam1 );
1639 HeapFree( GetProcessHeap(), 0, ptr );
1640 ret = WINMM_MAP_OK;
1642 break;
1643 case WODM_OPEN:
1645 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1646 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1647 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1649 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1650 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1651 UnMapLS( *lpParam1 );
1652 HeapFree( GetProcessHeap(), 0, ptr );
1653 ret = WINMM_MAP_OK;
1655 break;
1656 case WODM_PREPARE:
1657 case WODM_UNPREPARE:
1658 case WODM_WRITE:
1660 LPWAVEHDR wh16 = MapSL(*lpParam1);
1661 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1662 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1664 assert(wh32->lpNext == wh16);
1665 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1666 wh32->dwUser = wh16->dwUser;
1667 wh32->dwFlags = wh16->dwFlags;
1668 wh32->dwLoops = wh16->dwLoops;
1670 UnMapLS( *lpParam1 );
1671 if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1672 HeapFree( GetProcessHeap(), 0, ptr );
1673 wh32->lpNext = 0;
1675 ret = WINMM_MAP_OK;
1677 break;
1678 case WODM_GETVOLUME:
1679 FIXME("NIY: no conversion yet\n");
1680 ret = WINMM_MAP_MSGERROR;
1681 break;
1682 case DRVM_MAPPER_STATUS:
1684 UnMapLS( *lpParam2 );
1685 ret = WINMM_MAP_OK;
1687 break;
1688 default:
1689 FIXME("NIY: no conversion yet\n");
1690 ret = WINMM_MAP_MSGERROR;
1691 break;
1693 return ret;
1696 /**************************************************************************
1697 * MMDRV_WaveOut_Callback [internal]
1699 static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1701 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1703 switch (uMsg) {
1704 case WOM_OPEN:
1705 case WOM_CLOSE:
1706 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1707 break;
1708 case WOM_DONE:
1709 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1710 /* initial map is: 32 => 16 */
1711 LPWAVEHDR wh16 = MapSL(dwParam1);
1712 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1714 dwParam1 = (DWORD)wh32;
1715 wh32->dwFlags = wh16->dwFlags;
1716 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1717 /* initial map is: 16 => 32 */
1718 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1719 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1720 LPWAVEHDR wh16 = MapSL(segwh16);
1722 dwParam1 = (DWORD)segwh16;
1723 wh16->dwFlags = wh32->dwFlags;
1725 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1726 break;
1727 default:
1728 ERR("Unknown msg %u\n", uMsg);
1731 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1734 /* =================================
1735 * M A P P E R S H A N D L I N G
1736 * ================================= */
1738 static LRESULT MMDRV_CallMMDrvFunc16(DWORD fp16, WORD dev, WORD msg, LONG instance,
1739 LONG lp1, LONG lp2)
1741 WORD args[8];
1742 DWORD ret;
1744 args[7] = dev;
1745 args[6] = msg;
1746 args[5] = HIWORD(instance);
1747 args[4] = LOWORD(instance);
1748 args[3] = HIWORD(lp1);
1749 args[2] = LOWORD(lp1);
1750 args[1] = HIWORD(lp2);
1751 args[0] = LOWORD(lp2);
1752 WOWCallback16Ex( fp16, WCB16_PASCAL, sizeof(args), args, &ret );
1753 return LOWORD(ret);
1756 /**************************************************************************
1757 * MMDRV_GetDescription16 [internal]
1759 static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
1761 OFSTRUCT ofs;
1762 HFILE hFile;
1763 WORD w;
1764 DWORD dw;
1765 BOOL ret = FALSE;
1767 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
1768 ERR("Can't open file %s (builtin driver ?)\n", fname);
1769 return FALSE;
1772 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
1774 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
1775 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
1776 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
1777 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
1778 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %u\n", dw+0x2C));
1779 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
1780 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %u\n", dw));
1781 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
1782 buflen = min((int)(unsigned)(BYTE)buf[0], buflen - 1);
1783 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
1784 buf[buflen] = '\0';
1785 ret = TRUE;
1786 TRACE("Got '%s' [%d]\n", buf, buflen);
1787 theEnd:
1788 _lclose(hFile);
1789 return ret;
1792 /******************************************************************
1793 * MMDRV_LoadMMDrvFunc16
1796 unsigned MMDRV_LoadMMDrvFunc16(LPCSTR drvName, LPWINE_DRIVER d,
1797 LPWINE_MM_DRIVER lpDrv)
1799 WINEMM_msgFunc16 func;
1800 unsigned count = 0;
1801 char buffer[128];
1803 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
1804 * The beginning of the module description indicates the driver supports
1805 * waveform, auxiliary, and mixer devices. Use one of the following
1806 * device-type names, followed by a colon (:) to indicate the type of
1807 * device your driver supports. If the driver supports more than one
1808 * type of device, separate each device-type name with a comma (,).
1810 * wave for waveform audio devices
1811 * wavemapper for wave mappers
1812 * midi for MIDI audio devices
1813 * midimapper for midi mappers
1814 * aux for auxiliary audio devices
1815 * mixer for mixer devices
1818 if (d->d.d16.hDriver16) {
1819 HMODULE16 hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
1821 #define AA(_h,_w,_x,_y,_z) \
1822 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
1823 if (func != NULL) \
1824 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
1825 TRACE("Got %d bit func '%s'\n", _y, #_x); }
1827 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
1828 A(MMDRV_AUX, auxMessage);
1829 A(MMDRV_MIXER, mxdMessage);
1830 A(MMDRV_MIDIIN, midMessage);
1831 A(MMDRV_MIDIOUT,modMessage);
1832 A(MMDRV_WAVEIN, widMessage);
1833 A(MMDRV_WAVEOUT,wodMessage);
1834 #undef A
1835 #undef AA
1837 if (TRACE_ON(winmm)) {
1838 if (MMDRV_GetDescription16(drvName, buffer, sizeof(buffer)))
1839 TRACE("%s => %s\n", drvName, buffer);
1840 else
1841 TRACE("%s => No description\n", drvName);
1844 return count;
1847 /* =================================
1848 * M C I
1849 * ================================= */
1851 #if 0
1852 /* FIXME: this code is kept for not yet implemented optimisation for an application
1853 * using the 32A MCI interface and calling a 16 bit driver.
1854 * For now, we're doing two conversions:
1855 * - 32A => 32W (in 32 bit MCI code)
1856 * - 32W => 16 in this file
1860 * 0000 stop
1861 * 0001 squeeze signed 4 bytes to 2 bytes *( LPINT16)D = ( INT16)*( LPINT16)S; D += 2; S += 4
1862 * 0010 squeeze unsigned 4 bytes to 2 bytes *(LPUINT16)D = (UINT16)*(LPUINT16)S; D += 2; S += 4
1863 * 0100
1864 * 0101
1865 * 0110 zero 4 bytes *(DWORD)D = 0 D += 4; S += 4
1866 * 0111 copy string *(LPSTR*)D = seg dup(*(LPSTR*)S) D += 4; S += 4
1867 * 1xxx copy xxx + 1 bytes memcpy(D, S, xxx + 1); D += xxx+1; S += xxx+1
1870 /**************************************************************************
1871 * MCI_MsgMapper32ATo16_Create [internal]
1873 * Helper for MCI_MapMsg32ATo16.
1874 * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit
1875 * segmented pointer.
1876 * map contains a list of action to be performed for the mapping (see list
1877 * above)
1878 * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area.
1880 static WINMM_MapType MCI_MsgMapper32ATo16_Create(void** ptr, int size16, DWORD map, BOOLEAN keep)
1882 void* lp = HeapAlloc( GetProcessHeap(), 0, (keep ? sizeof(void**) : 0) + size16 );
1883 LPBYTE p16, p32;
1885 if (!lp) {
1886 return WINMM_MAP_NOMEM;
1888 p32 = (LPBYTE)(*ptr);
1889 if (keep) {
1890 *(void**)lp = *ptr;
1891 p16 = (LPBYTE)lp + sizeof(void**);
1892 *ptr = (char*)MapLS(lp) + sizeof(void**);
1893 } else {
1894 p16 = lp;
1895 *ptr = (void*)MapLS(lp);
1898 if (map == 0) {
1899 memcpy(p16, p32, size16);
1900 } else {
1901 unsigned nibble;
1902 unsigned sz;
1904 while (map & 0xF) {
1905 nibble = map & 0xF;
1906 if (nibble & 0x8) {
1907 sz = (nibble & 7) + 1;
1908 memcpy(p16, p32, sz);
1909 p16 += sz;
1910 p32 += sz;
1911 size16 -= sz; /* DEBUG only */
1912 } else {
1913 switch (nibble) {
1914 case 0x1:
1915 *(LPINT16)p16 = *(LPINT)p32;
1916 p16 += sizeof(INT16);
1917 p32 += sizeof(INT);
1918 size16 -= sizeof(INT16);
1919 break;
1920 case 0x2:
1921 *(LPUINT16)p16 = *(LPUINT)p32;
1922 p16 += sizeof(UINT16);
1923 p32 += sizeof(UINT);
1924 size16 -= sizeof(UINT16);
1925 break;
1926 case 0x6:
1927 *(LPDWORD)p16 = 0;
1928 p16 += sizeof(DWORD);
1929 p32 += sizeof(DWORD);
1930 size16 -= sizeof(DWORD);
1931 break;
1932 case 0x7:
1933 *(SEGPTR *)p16 = MapLS( *(LPSTR *)p32 );
1934 p16 += sizeof(SEGPTR);
1935 p32 += sizeof(LPSTR);
1936 size16 -= sizeof(SEGPTR);
1937 break;
1938 default:
1939 FIXME("Unknown nibble for mapping (%x)\n", nibble);
1942 map >>= 4;
1944 if (size16 != 0) /* DEBUG only */
1945 FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
1947 return WINMM_MAP_OKMEM;
1950 /**************************************************************************
1951 * MCI_MsgMapper32ATo16_Destroy [internal]
1953 * Helper for MCI_UnMapMsg32ATo16.
1955 static WINMM_MapType MCI_MsgMapper32ATo16_Destroy(void* ptr, int size16, DWORD map, BOOLEAN kept)
1957 if (ptr) {
1958 void* msg16 = MapSL((SEGPTR)ptr);
1959 void* alloc;
1960 LPBYTE p32, p16;
1961 unsigned nibble;
1963 UnMapLS( (SEGPTR)ptr );
1964 if (kept) {
1965 alloc = (char*)msg16 - sizeof(void**);
1966 p32 = *(void**)alloc;
1967 p16 = msg16;
1969 if (map == 0) {
1970 memcpy(p32, p16, size16);
1971 } else {
1972 while (map & 0xF) {
1973 nibble = map & 0xF;
1974 if (nibble & 0x8) {
1975 memcpy(p32, p16, (nibble & 7) + 1);
1976 p16 += (nibble & 7) + 1;
1977 p32 += (nibble & 7) + 1;
1978 size16 -= (nibble & 7) + 1;
1979 } else {
1980 switch (nibble) {
1981 case 0x1:
1982 *(LPINT)p32 = *(LPINT16)p16;
1983 p16 += sizeof(INT16);
1984 p32 += sizeof(INT);
1985 size16 -= sizeof(INT16);
1986 break;
1987 case 0x2:
1988 *(LPUINT)p32 = *(LPUINT16)p16;
1989 p16 += sizeof(UINT16);
1990 p32 += sizeof(UINT);
1991 size16 -= sizeof(UINT16);
1992 break;
1993 case 0x6:
1994 p16 += sizeof(UINT);
1995 p32 += sizeof(UINT);
1996 size16 -= sizeof(UINT);
1997 break;
1998 case 0x7:
1999 UnMapLS( *(SEGPTR *)p16 );
2000 p16 += sizeof(SEGPTR);
2001 p32 += sizeof(char*);
2002 size16 -= sizeof(SEGPTR);
2003 break;
2004 default:
2005 FIXME("Unknown nibble for mapping (%x)\n", nibble);
2008 map >>= 4;
2010 if (size16 != 0) /* DEBUG only */
2011 FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2013 } else {
2014 alloc = msg16;
2017 HeapFree( GetProcessHeap(), 0, alloc );
2019 return WINMM_MAP_OK;
2022 /**************************************************************************
2023 * MCI_MapMsg32ATo16 [internal]
2025 * Map a 32-A bit MCI message to a 16 bit MCI message.
2027 static WINMM_MapType MCI_MapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD* lParam)
2029 int size;
2030 BOOLEAN keep = FALSE;
2031 DWORD map = 0;
2033 if (*lParam == 0)
2034 return WINMM_MAP_OK;
2036 /* FIXME: to add also (with seg/linear modifications to do):
2037 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
2038 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
2040 switch (wMsg) {
2041 case MCI_BREAK:
2042 size = sizeof(MCI_BREAK_PARMS);
2043 break;
2044 /* case MCI_CAPTURE */
2045 case MCI_CLOSE:
2046 case MCI_CLOSE_DRIVER:
2047 case MCI_CONFIGURE:
2048 size = sizeof(MCI_GENERIC_PARMS);
2049 break;
2050 /* case MCI_COPY: */
2051 case MCI_CUE:
2052 switch (uDevType) {
2053 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_CUE_PARMS); break;
2054 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_CUE_PARMS); break;*/ FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2055 default: size = sizeof(MCI_GENERIC_PARMS); break;
2057 break;
2058 /* case MCI_CUT:*/
2059 case MCI_DELETE:
2060 switch (uDevType) {
2061 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_DELETE_PARMS16); map = 0x0F1111FB; break;
2062 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_DELETE_PARMS); break;
2063 default: size = sizeof(MCI_GENERIC_PARMS); break;
2065 break;
2066 /* case MCI_ESCAPE: */
2067 case MCI_FREEZE:
2068 switch (uDevType) {
2069 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_FREEZE_PARMS); map = 0x0001111B; break;
2070 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break;
2071 default: size = sizeof(MCI_GENERIC_PARMS); break;
2073 break;
2074 case MCI_GETDEVCAPS:
2075 keep = TRUE;
2076 size = sizeof(MCI_GETDEVCAPS_PARMS);
2077 break;
2078 /* case MCI_INDEX: */
2079 case MCI_INFO:
2081 LPMCI_INFO_PARMSA mip32a = (LPMCI_INFO_PARMSA)(*lParam);
2082 LPMCI_INFO_PARMS16 mip16;
2084 switch (uDevType) {
2085 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_INFO_PARMS16); break;
2086 default: size = sizeof(MCI_INFO_PARMS16); break;
2088 mip16 = HeapAlloc( GetProcessHeap(), 0, size);
2089 if (mip16)
2091 mip16->dwCallback = mip32a->dwCallback;
2092 mip16->lpstrReturn = MapLS( mip32a->lpstrReturn );
2093 mip16->dwRetSize = mip32a->dwRetSize;
2094 if (uDevType == MCI_DEVTYPE_DIGITAL_VIDEO) {
2095 ((LPMCI_DGV_INFO_PARMS16)mip16)->dwItem = ((LPMCI_DGV_INFO_PARMSA)mip32a)->dwItem;
2097 } else {
2098 return WINMM_MAP_NOMEM;
2100 *lParam = MapLS(mip16);
2102 return WINMM_MAP_OKMEM;
2103 /* case MCI_MARK: */
2104 /* case MCI_MONITOR: */
2105 case MCI_OPEN:
2106 case MCI_OPEN_DRIVER:
2108 LPMCI_OPEN_PARMSA mop32a = (LPMCI_OPEN_PARMSA)(*lParam);
2109 char* ptr = HeapAlloc( GetProcessHeap(), 0,
2110 sizeof(LPMCI_OPEN_PARMSA) + sizeof(MCI_OPEN_PARMS16) + 2 * sizeof(DWORD));
2111 LPMCI_OPEN_PARMS16 mop16;
2114 if (ptr) {
2115 *(LPMCI_OPEN_PARMSA*)(ptr) = mop32a;
2116 mop16 = (LPMCI_OPEN_PARMS16)(ptr + sizeof(LPMCI_OPEN_PARMSA));
2117 mop16->dwCallback = mop32a->dwCallback;
2118 mop16->wDeviceID = mop32a->wDeviceID;
2119 if (dwFlags & MCI_OPEN_TYPE) {
2120 if (dwFlags & MCI_OPEN_TYPE_ID) {
2121 /* dword "transparent" value */
2122 mop16->lpstrDeviceType = (SEGPTR)mop32a->lpstrDeviceType;
2123 } else {
2124 /* string */
2125 mop16->lpstrDeviceType = MapLS( mop32a->lpstrDeviceType );
2127 } else {
2128 /* nuthin' */
2129 mop16->lpstrDeviceType = 0;
2131 if (dwFlags & MCI_OPEN_ELEMENT) {
2132 if (dwFlags & MCI_OPEN_ELEMENT_ID) {
2133 mop16->lpstrElementName = (SEGPTR)mop32a->lpstrElementName;
2134 } else {
2135 mop16->lpstrElementName = MapLS( mop32a->lpstrElementName );
2137 } else {
2138 mop16->lpstrElementName = 0;
2140 if (dwFlags & MCI_OPEN_ALIAS) {
2141 mop16->lpstrAlias = MapLS( mop32a->lpstrAlias );
2142 } else {
2143 mop16->lpstrAlias = 0;
2145 /* copy extended information if any...
2146 * FIXME: this may seg fault if initial structure does not contain them and
2147 * the reads after msip16 fail under LDT limits...
2148 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
2149 * should not take care of extended parameters, and should be used by MCI_Open
2150 * to fetch uDevType. When, this is known, the mapping for sending the
2151 * MCI_OPEN_DRIVER shall be done depending on uDevType.
2153 memcpy(mop16 + 1, mop32a + 1, 2 * sizeof(DWORD));
2154 } else {
2155 return WINMM_MAP_NOMEM;
2157 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_PARMSA);
2159 return WINMM_MAP_OKMEM;
2160 /* case MCI_PASTE:*/
2161 case MCI_PAUSE:
2162 size = sizeof(MCI_GENERIC_PARMS);
2163 break;
2164 case MCI_PLAY:
2165 size = sizeof(MCI_PLAY_PARMS);
2166 break;
2167 case MCI_PUT:
2168 switch (uDevType) {
2169 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break;
2170 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break;
2171 default: size = sizeof(MCI_GENERIC_PARMS); break;
2173 break;
2174 case MCI_REALIZE:
2175 size = sizeof(MCI_GENERIC_PARMS);
2176 break;
2177 case MCI_RECORD:
2178 switch (uDevType) {
2179 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECORD_PARMS16); map = 0x0F1111FB; break;
2180 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_RECORD_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2181 default: size = sizeof(MCI_RECORD_PARMS); break;
2183 break;
2184 case MCI_RESUME:
2185 size = sizeof(MCI_GENERIC_PARMS);
2186 break;
2187 case MCI_SEEK:
2188 switch (uDevType) {
2189 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SEEK_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2190 default: size = sizeof(MCI_SEEK_PARMS); break;
2192 break;
2193 case MCI_SET:
2194 switch (uDevType) {
2195 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SET_PARMS); break;
2196 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SET_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2197 case MCI_DEVTYPE_SEQUENCER: size = sizeof(MCI_SEQ_SET_PARMS); break;
2198 /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned,
2199 * so not doing anything should work...
2201 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_SET_PARMS); break;
2202 default: size = sizeof(MCI_SET_PARMS); break;
2204 break;
2205 case MCI_SETAUDIO:
2206 switch (uDevType) {
2207 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SETAUDIO_PARMS16);map = 0x0000077FF; break;
2208 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2209 default: size = sizeof(MCI_GENERIC_PARMS); break;
2211 break;
2212 /* case MCI_SETTIMECODE:*/
2213 /* case MCI_SIGNAL:*/
2214 /* case MCI_SOUND:*/
2215 case MCI_SPIN:
2216 size = sizeof(MCI_SET_PARMS);
2217 break;
2218 case MCI_STATUS:
2219 keep = TRUE;
2220 switch (uDevType) {
2221 /* FIXME:
2222 * don't know if buffer for value is the one passed through lpstrDevice
2223 * or is provided by MCI driver.
2224 * Assuming solution 2: provided by MCI driver, so zeroing on entry
2226 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16); map = 0x0B6FF; break;
2227 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2228 default: size = sizeof(MCI_STATUS_PARMS); break;
2230 break;
2231 case MCI_STEP:
2232 switch (uDevType) {
2233 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STEP_PARMS); break;
2234 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STEP_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2235 case MCI_DEVTYPE_VIDEODISC: size = sizeof(MCI_VD_STEP_PARMS); break;
2236 default: size = sizeof(MCI_GENERIC_PARMS); break;
2238 break;
2239 case MCI_STOP:
2240 size = sizeof(MCI_SET_PARMS);
2241 break;
2242 case MCI_SYSINFO:
2244 LPMCI_SYSINFO_PARMSA msip32a = (LPMCI_SYSINFO_PARMSA)(*lParam);
2245 LPMCI_SYSINFO_PARMS16 msip16;
2246 char* ptr = HeapAlloc( GetProcessHeap(), 0,
2247 sizeof(LPMCI_SYSINFO_PARMSA) + sizeof(MCI_SYSINFO_PARMS16) );
2249 if (ptr) {
2250 *(LPMCI_SYSINFO_PARMSA*)(ptr) = msip32a;
2251 msip16 = (LPMCI_SYSINFO_PARMS16)(ptr + sizeof(LPMCI_SYSINFO_PARMSA));
2253 msip16->dwCallback = msip32a->dwCallback;
2254 msip16->lpstrReturn = MapLS( msip32a->lpstrReturn );
2255 msip16->dwRetSize = msip32a->dwRetSize;
2256 msip16->dwNumber = msip32a->dwNumber;
2257 msip16->wDeviceType = msip32a->wDeviceType;
2258 } else {
2259 return WINMM_MAP_NOMEM;
2261 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_SYSINFO_PARMSA);
2263 return WINMM_MAP_OKMEM;
2264 /* case MCI_UNDO: */
2265 case MCI_UNFREEZE:
2266 switch (uDevType) {
2267 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break;
2268 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; break;
2269 default: size = sizeof(MCI_GENERIC_PARMS); break;
2271 break;
2272 case MCI_UPDATE:
2273 switch (uDevType) {
2274 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_UPDATE_PARMS16); map = 0x000B1111B; break;
2275 default: size = sizeof(MCI_GENERIC_PARMS); break;
2277 break;
2278 case MCI_WHERE:
2279 switch (uDevType) {
2280 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break;
2281 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break;
2282 default: size = sizeof(MCI_GENERIC_PARMS); break;
2284 break;
2285 case MCI_WINDOW:
2286 switch (uDevType) {
2287 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7FB; break;
2288 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7FB; break;
2289 default: size = sizeof(MCI_GENERIC_PARMS); break;
2291 break;
2292 case DRV_OPEN:
2294 LPMCI_OPEN_DRIVER_PARMSA modp32a = (LPMCI_OPEN_DRIVER_PARMSA)(*lParam);
2295 LPMCI_OPEN_DRIVER_PARMS16 modp16;
2296 char *ptr = HeapAlloc( GetProcessHeap(), 0,
2297 sizeof(LPMCI_OPEN_DRIVER_PARMSA) + sizeof(MCI_OPEN_DRIVER_PARMS16));
2299 if (ptr) {
2300 *(LPMCI_OPEN_DRIVER_PARMSA*)(ptr) = modp32a;
2301 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSA));
2302 modp16->wDeviceID = modp32a->wDeviceID;
2303 modp16->lpstrParams = MapLS( modp32a->lpstrParams );
2304 /* other fields are gonna be filled by the driver, don't copy them */
2305 } else {
2306 return WINMM_MAP_NOMEM;
2308 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_DRIVER_PARMSA);
2310 return WINMM_MAP_OKMEM;
2311 case DRV_LOAD:
2312 case DRV_ENABLE:
2313 case DRV_CLOSE:
2314 case DRV_DISABLE:
2315 case DRV_FREE:
2316 case DRV_CONFIGURE:
2317 case DRV_QUERYCONFIGURE:
2318 case DRV_INSTALL:
2319 case DRV_REMOVE:
2320 case DRV_EXITSESSION:
2321 case DRV_EXITAPPLICATION:
2322 case DRV_POWER:
2323 return WINMM_MAP_OK;
2325 default:
2326 FIXME("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2327 return WINMM_MAP_MSGERROR;
2329 return MCI_MsgMapper32ATo16_Create((void**)lParam, size, map, keep);
2332 /**************************************************************************
2333 * MCI_UnMapMsg32ATo16 [internal]
2335 static WINMM_MapType MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD lParam)
2337 int size = 0;
2338 BOOLEAN kept = FALSE; /* there is no need to compute size when kept is FALSE */
2339 DWORD map = 0;
2341 switch (wMsg) {
2342 case MCI_BREAK:
2343 break;
2344 /* case MCI_CAPTURE */
2345 case MCI_CLOSE:
2346 case MCI_CLOSE_DRIVER:
2347 case MCI_CONFIGURE:
2348 break;
2349 /* case MCI_COPY: */
2350 case MCI_CUE:
2351 break;
2352 /* case MCI_CUT: */
2353 case MCI_DELETE:
2354 break;
2355 /* case MCI_ESCAPE: */
2356 case MCI_FREEZE:
2357 break;
2358 case MCI_GETDEVCAPS:
2359 kept = TRUE;
2360 size = sizeof(MCI_GETDEVCAPS_PARMS);
2361 break;
2362 /* case MCI_INDEX: */
2363 case MCI_INFO:
2365 LPMCI_INFO_PARMS16 mip16 = (LPMCI_INFO_PARMS16)MapSL(lParam);
2366 UnMapLS( lParam );
2367 UnMapLS( mip16->lpstrReturn );
2368 HeapFree( GetProcessHeap(), 0, mip16 );
2370 return WINMM_MAP_OK;
2371 /* case MCI_MARK: */
2372 /* case MCI_MONITOR: */
2373 case MCI_OPEN:
2374 case MCI_OPEN_DRIVER:
2375 if (lParam) {
2376 LPMCI_OPEN_PARMS16 mop16 = (LPMCI_OPEN_PARMS16)MapSL(lParam);
2377 LPMCI_OPEN_PARMSA mop32a = *(LPMCI_OPEN_PARMSA*)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSA));
2378 UnMapLS( lParam );
2379 mop32a->wDeviceID = mop16->wDeviceID;
2380 if ((dwFlags & MCI_OPEN_TYPE) && !(dwFlags & MCI_OPEN_TYPE_ID))
2381 UnMapLS( mop16->lpstrDeviceType );
2382 if ((dwFlags & MCI_OPEN_ELEMENT) && !(dwFlags & MCI_OPEN_ELEMENT_ID))
2383 UnMapLS( mop16->lpstrElementName );
2384 if (dwFlags & MCI_OPEN_ALIAS)
2385 UnMapLS( mop16->lpstrAlias );
2386 HeapFree( GetProcessHeap(), 0, (char*)mop16 - sizeof(LPMCI_OPEN_PARMSA) );
2388 return WINMM_MAP_OK;
2389 /* case MCI_PASTE:*/
2390 case MCI_PAUSE:
2391 break;
2392 case MCI_PLAY:
2393 break;
2394 case MCI_PUT:
2395 break;
2396 case MCI_REALIZE:
2397 break;
2398 case MCI_RECORD:
2399 break;
2400 case MCI_RESUME:
2401 break;
2402 case MCI_SEEK:
2403 break;
2404 case MCI_SET:
2405 break;
2406 case MCI_SETAUDIO:
2407 switch (uDevType) {
2408 case MCI_DEVTYPE_DIGITAL_VIDEO: map = 0x0000077FF; break;
2409 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2411 break;
2412 /* case MCI_SETTIMECODE:*/
2413 /* case MCI_SIGNAL:*/
2414 /* case MCI_SOUND:*/
2415 case MCI_SPIN:
2416 break;
2417 case MCI_STATUS:
2418 kept = TRUE;
2419 switch (uDevType) {
2420 case MCI_DEVTYPE_DIGITAL_VIDEO:
2421 if (lParam) {
2422 LPMCI_DGV_STATUS_PARMS16 mdsp16 = (LPMCI_DGV_STATUS_PARMS16)MapSL(lParam);
2423 LPMCI_DGV_STATUS_PARMSA mdsp32a = *(LPMCI_DGV_STATUS_PARMSA*)((char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA));
2425 UnMapLS( lParam );
2426 if (mdsp16) {
2427 mdsp32a->dwReturn = mdsp16->dwReturn;
2428 if (dwFlags & MCI_DGV_STATUS_DISKSPACE) {
2429 TRACE("MCI_STATUS (DGV) lpstrDrive=%08lx\n", mdsp16->lpstrDrive);
2430 TRACE("MCI_STATUS (DGV) lpstrDrive=%s\n", (LPSTR)MapSL(mdsp16->lpstrDrive));
2431 UnMapLS( mdsp16->lpstrDrive );
2433 HeapFree( GetProcessHeap(), 0, (char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA) );
2434 } else {
2435 return WINMM_MAP_NOMEM;
2438 return WINMM_MAP_OKMEM;
2439 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2440 default: size = sizeof(MCI_STATUS_PARMS); break;
2442 break;
2443 case MCI_STEP:
2444 break;
2445 case MCI_STOP:
2446 break;
2447 case MCI_SYSINFO:
2448 if (lParam) {
2449 LPMCI_SYSINFO_PARMS16 msip16 = (LPMCI_SYSINFO_PARMS16)MapSL(lParam);
2450 LPMCI_SYSINFO_PARMSA msip32a = *(LPMCI_SYSINFO_PARMSA*)((char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA));
2452 UnMapLS( lParam );
2453 if (msip16) {
2454 msip16->dwCallback = msip32a->dwCallback;
2455 UnMapLS( msip16->lpstrReturn );
2456 HeapFree( GetProcessHeap(), 0, (char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA) );
2457 } else {
2458 return WINMM_MAP_NOMEM;
2461 return WINMM_MAP_OKMEM;
2462 /* case MCI_UNDO: */
2463 case MCI_UNFREEZE:
2464 break;
2465 case MCI_UPDATE:
2466 break;
2467 case MCI_WHERE:
2468 switch (uDevType) {
2469 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break;
2470 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break;
2471 default: break;
2473 break;
2474 case MCI_WINDOW:
2475 switch (uDevType) {
2476 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7666; break;
2477 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7666; break;
2478 default: break;
2480 /* FIXME: see map function */
2481 break;
2483 case DRV_OPEN:
2484 if (lParam) {
2485 LPMCI_OPEN_DRIVER_PARMS16 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)MapSL(lParam);
2486 LPMCI_OPEN_DRIVER_PARMSA modp32a = *(LPMCI_OPEN_DRIVER_PARMSA*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA));
2488 UnMapLS( lParam );
2489 modp32a->wCustomCommandTable = modp16->wCustomCommandTable;
2490 modp32a->wType = modp16->wType;
2491 UnMapLS( modp16->lpstrParams );
2492 HeapFree( GetProcessHeap(), 0, (char *)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA) );
2494 return WINMM_MAP_OK;
2495 case DRV_LOAD:
2496 case DRV_ENABLE:
2497 case DRV_CLOSE:
2498 case DRV_DISABLE:
2499 case DRV_FREE:
2500 case DRV_CONFIGURE:
2501 case DRV_QUERYCONFIGURE:
2502 case DRV_INSTALL:
2503 case DRV_REMOVE:
2504 case DRV_EXITSESSION:
2505 case DRV_EXITAPPLICATION:
2506 case DRV_POWER:
2507 FIXME("This is a hack\n");
2508 return WINMM_MAP_OK;
2509 default:
2510 FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2511 return WINMM_MAP_MSGERROR;
2513 return MCI_MsgMapper32ATo16_Destroy((void*)lParam, size, map, kept);
2515 #endif
2517 /**************************************************************************
2518 * MCI_MapMsg16To32W [internal]
2520 static WINMM_MapType MCI_MapMsg16To32W(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR* lParam)
2522 if (*lParam == 0)
2523 return WINMM_MAP_OK;
2524 /* FIXME: to add also (with seg/linear modifications to do):
2525 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
2526 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
2528 switch (wMsg) {
2529 /* case MCI_CAPTURE */
2530 case MCI_CLOSE:
2531 case MCI_CLOSE_DRIVER:
2532 case MCI_CONFIGURE:
2533 case MCI_COPY:
2534 case MCI_CUE:
2535 case MCI_CUT:
2536 case MCI_DELETE:
2537 case MCI_FREEZE:
2538 case MCI_GETDEVCAPS:
2539 /* case MCI_INDEX: */
2540 /* case MCI_MARK: */
2541 /* case MCI_MONITOR: */
2542 case MCI_PASTE:
2543 case MCI_PAUSE:
2544 case MCI_PLAY:
2545 case MCI_PUT:
2546 case MCI_REALIZE:
2547 case MCI_RECORD:
2548 case MCI_RESUME:
2549 case MCI_SEEK:
2550 case MCI_SET:
2551 /* case MCI_SETTIMECODE:*/
2552 /* case MCI_SIGNAL:*/
2553 case MCI_SPIN:
2554 case MCI_STATUS: /* FIXME: is wrong for digital video */
2555 case MCI_STEP:
2556 case MCI_STOP:
2557 /* case MCI_UNDO: */
2558 case MCI_UNFREEZE:
2559 case MCI_UPDATE:
2560 case MCI_WHERE:
2561 *lParam = (DWORD)MapSL(*lParam);
2562 return WINMM_MAP_OK;
2563 case MCI_WINDOW:
2564 /* in fact, I would also need the dwFlags... to see
2565 * which members of lParam are effectively used
2567 *lParam = (DWORD)MapSL(*lParam);
2568 FIXME("Current mapping may be wrong\n");
2569 break;
2570 case MCI_BREAK:
2572 LPMCI_BREAK_PARMS mbp32 = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_BREAK_PARMS));
2573 LPMCI_BREAK_PARMS16 mbp16 = MapSL(*lParam);
2575 if (mbp32) {
2576 mbp32->dwCallback = mbp16->dwCallback;
2577 mbp32->nVirtKey = mbp16->nVirtKey;
2578 mbp32->hwndBreak = HWND_32(mbp16->hwndBreak);
2579 } else {
2580 return WINMM_MAP_NOMEM;
2582 *lParam = (DWORD)mbp32;
2584 return WINMM_MAP_OKMEM;
2585 case MCI_ESCAPE:
2587 LPMCI_VD_ESCAPE_PARMSW mvep32w = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_VD_ESCAPE_PARMSW));
2588 LPMCI_VD_ESCAPE_PARMS16 mvep16 = MapSL(*lParam);
2590 if (mvep32w) {
2591 mvep32w->dwCallback = mvep16->dwCallback;
2592 mvep32w->lpstrCommand = MCI_strdupAtoW(MapSL(mvep16->lpstrCommand));
2593 } else {
2594 return WINMM_MAP_NOMEM;
2596 *lParam = (DWORD)mvep32w;
2598 return WINMM_MAP_OKMEM;
2599 case MCI_INFO:
2601 LPMCI_INFO_PARMSW mip32w = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_INFO_PARMSW));
2602 LPMCI_INFO_PARMS16 mip16 = MapSL(*lParam);
2604 /* FIXME this is wrong if device is of type
2605 * MCI_DEVTYPE_DIGITAL_VIDEO, some members are not mapped
2607 if (mip32w) {
2608 *(LPMCI_INFO_PARMS16*)(mip32w) = mip16;
2609 mip32w = (LPMCI_INFO_PARMSW)((char*)mip32w + sizeof(LPMCI_INFO_PARMS16));
2610 mip32w->dwCallback = mip16->dwCallback;
2611 mip32w->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mip16->dwRetSize * sizeof(WCHAR));
2612 mip32w->dwRetSize = mip16->dwRetSize * sizeof(WCHAR);
2613 } else {
2614 return WINMM_MAP_NOMEM;
2616 *lParam = (DWORD)mip32w;
2618 return WINMM_MAP_OKMEM;
2619 case MCI_OPEN:
2620 case MCI_OPEN_DRIVER:
2622 LPMCI_OPEN_PARMSW mop32w = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_OPEN_PARMSW) + 2 * sizeof(DWORD));
2623 LPMCI_OPEN_PARMS16 mop16 = MapSL(*lParam);
2625 if (mop32w) {
2626 *(LPMCI_OPEN_PARMS16*)(mop32w) = mop16;
2627 mop32w = (LPMCI_OPEN_PARMSW)((char*)mop32w + sizeof(LPMCI_OPEN_PARMS16));
2628 mop32w->dwCallback = mop16->dwCallback;
2629 mop32w->wDeviceID = mop16->wDeviceID;
2630 if( ( dwFlags & ( MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID)) == MCI_OPEN_TYPE)
2631 mop32w->lpstrDeviceType = MCI_strdupAtoW(MapSL(mop16->lpstrDeviceType));
2632 else
2633 mop32w->lpstrDeviceType = (LPWSTR) mop16->lpstrDeviceType;
2634 if( ( dwFlags & ( MCI_OPEN_ELEMENT | MCI_OPEN_ELEMENT_ID)) == MCI_OPEN_ELEMENT)
2635 mop32w->lpstrElementName = MCI_strdupAtoW(MapSL(mop16->lpstrElementName));
2636 else
2637 mop32w->lpstrElementName = (LPWSTR) mop16->lpstrElementName;
2638 if( ( dwFlags & MCI_OPEN_ALIAS))
2639 mop32w->lpstrAlias = MCI_strdupAtoW(MapSL(mop16->lpstrAlias));
2640 else
2641 mop32w->lpstrAlias = (LPWSTR) mop16->lpstrAlias;
2642 /* copy extended information if any...
2643 * FIXME: this may seg fault if initial structure does not contain them and
2644 * the reads after msip16 fail under LDT limits...
2645 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
2646 * should not take care of extended parameters, and should be used by MCI_Open
2647 * to fetch uDevType. When, this is known, the mapping for sending the
2648 * MCI_OPEN_DRIVER shall be done depending on uDevType.
2650 memcpy(mop32w + 1, mop16 + 1, 2 * sizeof(DWORD));
2651 } else {
2652 return WINMM_MAP_NOMEM;
2654 *lParam = (DWORD)mop32w;
2656 return WINMM_MAP_OKMEM;
2657 case MCI_SYSINFO:
2659 LPMCI_SYSINFO_PARMSW msip32w = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_SYSINFO_PARMSW));
2660 LPMCI_SYSINFO_PARMS16 msip16 = MapSL(*lParam);
2662 if (msip32w) {
2663 *(LPMCI_SYSINFO_PARMS16*)(msip32w) = msip16;
2664 msip32w = (LPMCI_SYSINFO_PARMSW)((char*)msip32w + sizeof(LPMCI_OPEN_PARMS16));
2665 msip32w->dwCallback = msip16->dwCallback;
2666 msip32w->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, msip16->dwRetSize * sizeof(WCHAR));
2667 msip32w->dwRetSize = msip16->dwRetSize;
2668 msip32w->dwNumber = msip16->dwNumber;
2669 msip32w->wDeviceType = msip16->wDeviceType;
2670 } else {
2671 return WINMM_MAP_NOMEM;
2673 *lParam = (DWORD)msip32w;
2675 return WINMM_MAP_OKMEM;
2676 case MCI_SOUND:
2678 LPMCI_SOUND_PARMSW mbp32 = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_SOUND_PARMSW));
2679 LPMCI_SOUND_PARMS16 mbp16 = MapSL(*lParam);
2681 if (mbp32) {
2682 mbp32->dwCallback = mbp16->dwCallback;
2683 mbp32->lpstrSoundName = MCI_strdupAtoW(MapSL(mbp16->lpstrSoundName));
2684 } else {
2685 return WINMM_MAP_NOMEM;
2687 *lParam = (DWORD)mbp32;
2689 return WINMM_MAP_OKMEM;
2690 case DRV_LOAD:
2691 case DRV_ENABLE:
2692 case DRV_OPEN:
2693 case DRV_CLOSE:
2694 case DRV_DISABLE:
2695 case DRV_FREE:
2696 case DRV_CONFIGURE:
2697 case DRV_QUERYCONFIGURE:
2698 case DRV_INSTALL:
2699 case DRV_REMOVE:
2700 case DRV_EXITSESSION:
2701 case DRV_EXITAPPLICATION:
2702 case DRV_POWER:
2703 FIXME("This is a hack\n");
2704 return WINMM_MAP_OK;
2705 default:
2706 FIXME("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2708 return WINMM_MAP_MSGERROR;
2711 /**************************************************************************
2712 * MCI_UnMapMsg16To32W [internal]
2714 static WINMM_MapType MCI_UnMapMsg16To32W(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR lParam)
2716 switch (wMsg) {
2717 /* case MCI_CAPTURE */
2718 case MCI_CLOSE:
2719 case MCI_CLOSE_DRIVER:
2720 case MCI_CONFIGURE:
2721 case MCI_COPY:
2722 case MCI_CUE:
2723 case MCI_CUT:
2724 case MCI_DELETE:
2725 case MCI_FREEZE:
2726 case MCI_GETDEVCAPS:
2727 /* case MCI_INDEX: */
2728 /* case MCI_MARK: */
2729 /* case MCI_MONITOR: */
2730 case MCI_PASTE:
2731 case MCI_PAUSE:
2732 case MCI_PLAY:
2733 case MCI_PUT:
2734 case MCI_REALIZE:
2735 case MCI_RECORD:
2736 case MCI_RESUME:
2737 case MCI_SEEK:
2738 case MCI_SET:
2739 /* case MCI_SETTIMECODE:*/
2740 /* case MCI_SIGNAL:*/
2741 case MCI_SPIN:
2742 case MCI_STATUS:
2743 case MCI_STEP:
2744 case MCI_STOP:
2745 /* case MCI_UNDO: */
2746 case MCI_UNFREEZE:
2747 case MCI_UPDATE:
2748 case MCI_WHERE:
2749 return WINMM_MAP_OK;
2751 case MCI_WINDOW:
2752 /* FIXME ?? see Map function */
2753 return WINMM_MAP_OK;
2755 case MCI_BREAK:
2756 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2757 return WINMM_MAP_OK;
2758 case MCI_ESCAPE:
2759 if (lParam) {
2760 LPMCI_VD_ESCAPE_PARMSW mvep32W = (LPMCI_VD_ESCAPE_PARMSW)lParam;
2761 HeapFree(GetProcessHeap(), 0, (LPVOID)mvep32W->lpstrCommand);
2762 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2764 return WINMM_MAP_OK;
2765 case MCI_INFO:
2766 if (lParam) {
2767 LPMCI_INFO_PARMSW mip32w = (LPMCI_INFO_PARMSW)lParam;
2768 LPMCI_INFO_PARMS16 mip16 = *(LPMCI_INFO_PARMS16*)((char*)mip32w - sizeof(LPMCI_INFO_PARMS16));
2770 WideCharToMultiByte(CP_ACP, 0,
2771 mip32w->lpstrReturn, mip32w->dwRetSize / sizeof(WCHAR),
2772 MapSL(mip16->lpstrReturn), mip16->dwRetSize,
2773 NULL, NULL);
2774 HeapFree(GetProcessHeap(), 0, (LPVOID)mip32w->lpstrReturn);
2775 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2777 return WINMM_MAP_OK;
2778 case MCI_SYSINFO:
2779 if (lParam) {
2780 LPMCI_SYSINFO_PARMSW msip32w = (LPMCI_SYSINFO_PARMSW)lParam;
2781 LPMCI_SYSINFO_PARMS16 msip16 = *(LPMCI_SYSINFO_PARMS16*)((char*)msip32w - sizeof(LPMCI_SYSINFO_PARMS16));
2783 WideCharToMultiByte(CP_ACP, 0,
2784 msip32w->lpstrReturn, msip32w->dwRetSize,
2785 MapSL(msip16->lpstrReturn), msip16->dwRetSize,
2786 NULL, NULL);
2787 HeapFree(GetProcessHeap(), 0, (LPVOID)msip32w->lpstrReturn);
2788 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2790 return WINMM_MAP_OK;
2791 case MCI_SOUND:
2792 if (lParam) {
2793 LPMCI_SOUND_PARMSW msp32W = (LPMCI_SOUND_PARMSW)lParam;
2794 HeapFree(GetProcessHeap(), 0, (LPVOID)msp32W->lpstrSoundName);
2795 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2797 return WINMM_MAP_OK;
2798 case MCI_OPEN:
2799 case MCI_OPEN_DRIVER:
2800 if (lParam) {
2801 LPMCI_OPEN_PARMSW mop32w = (LPMCI_OPEN_PARMSW)lParam;
2802 LPMCI_OPEN_PARMS16 mop16 = *(LPMCI_OPEN_PARMS16*)((char*)mop32w - sizeof(LPMCI_OPEN_PARMS16));
2804 mop16->wDeviceID = mop32w->wDeviceID;
2805 if( ( dwFlags & ( MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID)) == MCI_OPEN_TYPE)
2806 HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrDeviceType);
2807 if( ( dwFlags & ( MCI_OPEN_ELEMENT | MCI_OPEN_ELEMENT_ID)) == MCI_OPEN_ELEMENT)
2808 HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrElementName);
2809 if( ( dwFlags & MCI_OPEN_ALIAS))
2810 HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrAlias);
2811 if (!HeapFree(GetProcessHeap(), 0, (LPVOID)(lParam - sizeof(LPMCI_OPEN_PARMS16))))
2812 FIXME("bad free line=%d\n", __LINE__);
2814 return WINMM_MAP_OK;
2815 case DRV_LOAD:
2816 case DRV_ENABLE:
2817 case DRV_OPEN:
2818 case DRV_CLOSE:
2819 case DRV_DISABLE:
2820 case DRV_FREE:
2821 case DRV_CONFIGURE:
2822 case DRV_QUERYCONFIGURE:
2823 case DRV_INSTALL:
2824 case DRV_REMOVE:
2825 case DRV_EXITSESSION:
2826 case DRV_EXITAPPLICATION:
2827 case DRV_POWER:
2828 FIXME("This is a hack\n");
2829 return WINMM_MAP_OK;
2830 default:
2831 FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2833 return WINMM_MAP_MSGERROR;
2837 * 0000 stop
2838 * 0001 squeeze signed 4 bytes to 2 bytes *( LPINT16)D = ( INT16)*( LPINT16)S; D += 2; S += 4
2839 * 0010 squeeze unsigned 4 bytes to 2 bytes *(LPUINT16)D = (UINT16)*(LPUINT16)S; D += 2; S += 4
2840 * 0100
2841 * 0101
2842 * 0110 zero 4 bytes *(DWORD)D = 0 D += 4; S += 4
2843 * 0111 copy string *(LPSTR*)D = seg dup(*(LPSTR*)S) D += 4; S += 4
2844 * 1xxx copy xxx + 1 bytes memcpy(D, S, xxx + 1); D += xxx+1; S += xxx+1
2847 /**************************************************************************
2848 * MCI_MsgMapper32WTo16_Create [internal]
2850 * Helper for MCI_MapMsg32WTo16.
2851 * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit
2852 * segmented pointer.
2853 * map contains a list of action to be performed for the mapping (see list
2854 * above)
2855 * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area.
2857 static WINMM_MapType MCI_MsgMapper32WTo16_Create(void** ptr, int size16, DWORD map, BOOLEAN keep)
2859 void* lp = HeapAlloc( GetProcessHeap(), 0, (keep ? sizeof(void**) : 0) + size16 );
2860 LPBYTE p16, p32;
2862 if (!lp) {
2863 return WINMM_MAP_NOMEM;
2865 p32 = (LPBYTE)(*ptr);
2866 if (keep) {
2867 *(void**)lp = *ptr;
2868 p16 = (LPBYTE)lp + sizeof(void**);
2869 *ptr = (char*)MapLS(lp) + sizeof(void**);
2870 } else {
2871 p16 = lp;
2872 *ptr = (void*)MapLS(lp);
2875 if (map == 0) {
2876 memcpy(p16, p32, size16);
2877 } else {
2878 unsigned nibble;
2879 unsigned sz;
2881 while (map & 0xF) {
2882 nibble = map & 0xF;
2883 if (nibble & 0x8) {
2884 sz = (nibble & 7) + 1;
2885 memcpy(p16, p32, sz);
2886 p16 += sz;
2887 p32 += sz;
2888 size16 -= sz; /* DEBUG only */
2889 } else {
2890 switch (nibble) {
2891 case 0x1:
2892 *(LPINT16)p16 = *(LPINT)p32;
2893 p16 += sizeof(INT16);
2894 p32 += sizeof(INT);
2895 size16 -= sizeof(INT16);
2896 break;
2897 case 0x2:
2898 *(LPUINT16)p16 = *(LPUINT)p32;
2899 p16 += sizeof(UINT16);
2900 p32 += sizeof(UINT);
2901 size16 -= sizeof(UINT16);
2902 break;
2903 case 0x6:
2904 *(LPDWORD)p16 = 0;
2905 p16 += sizeof(DWORD);
2906 p32 += sizeof(DWORD);
2907 size16 -= sizeof(DWORD);
2908 break;
2909 case 0x7:
2910 *(SEGPTR *)p16 = MapLS( MCI_strdupWtoA( *(LPCWSTR *)p32 ) );
2911 p16 += sizeof(SEGPTR);
2912 p32 += sizeof(LPSTR);
2913 size16 -= sizeof(SEGPTR);
2914 break;
2915 default:
2916 FIXME("Unknown nibble for mapping (%x)\n", nibble);
2919 map >>= 4;
2921 if (size16 != 0) /* DEBUG only */
2922 FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2924 return WINMM_MAP_OKMEM;
2927 /**************************************************************************
2928 * MCI_MsgMapper32WTo16_Destroy [internal]
2930 * Helper for MCI_UnMapMsg32WTo16.
2932 static WINMM_MapType MCI_MsgMapper32WTo16_Destroy(void* ptr, int size16, DWORD map, BOOLEAN kept)
2934 if (ptr) {
2935 void* msg16 = MapSL((SEGPTR)ptr);
2936 void* alloc;
2937 LPBYTE p32, p16;
2938 unsigned nibble;
2940 UnMapLS( (SEGPTR)ptr );
2941 if (kept) {
2942 alloc = (char*)msg16 - sizeof(void**);
2943 p32 = *(void**)alloc;
2944 p16 = msg16;
2946 if (map == 0) {
2947 memcpy(p32, p16, size16);
2948 } else {
2949 while (map & 0xF) {
2950 nibble = map & 0xF;
2951 if (nibble & 0x8) {
2952 memcpy(p32, p16, (nibble & 7) + 1);
2953 p16 += (nibble & 7) + 1;
2954 p32 += (nibble & 7) + 1;
2955 size16 -= (nibble & 7) + 1;
2956 } else {
2957 switch (nibble) {
2958 case 0x1:
2959 *(LPINT)p32 = *(LPINT16)p16;
2960 p16 += sizeof(INT16);
2961 p32 += sizeof(INT);
2962 size16 -= sizeof(INT16);
2963 break;
2964 case 0x2:
2965 *(LPUINT)p32 = *(LPUINT16)p16;
2966 p16 += sizeof(UINT16);
2967 p32 += sizeof(UINT);
2968 size16 -= sizeof(UINT16);
2969 break;
2970 case 0x6:
2971 p16 += sizeof(UINT);
2972 p32 += sizeof(UINT);
2973 size16 -= sizeof(UINT);
2974 break;
2975 case 0x7:
2976 HeapFree(GetProcessHeap(), 0, MapSL(*(SEGPTR *)p16));
2977 UnMapLS( *(SEGPTR *)p16 );
2978 p16 += sizeof(SEGPTR);
2979 p32 += sizeof(char*);
2980 size16 -= sizeof(SEGPTR);
2981 break;
2982 default:
2983 FIXME("Unknown nibble for mapping (%x)\n", nibble);
2986 map >>= 4;
2988 if (size16 != 0) /* DEBUG only */
2989 FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2991 } else {
2992 alloc = msg16;
2995 HeapFree( GetProcessHeap(), 0, alloc );
2997 return WINMM_MAP_OK;
3000 /**************************************************************************
3001 * MCI_MapMsg32WTo16 [internal]
3003 * Map a 32W bit MCI message to a 16 bit MCI message.
3005 static WINMM_MapType MCI_MapMsg32WTo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR* lParam)
3007 int size;
3008 BOOLEAN keep = FALSE;
3009 DWORD map = 0;
3011 if (*lParam == 0)
3012 return WINMM_MAP_OK;
3014 /* FIXME: to add also (with seg/linear modifications to do):
3015 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
3016 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
3018 switch (wMsg) {
3019 case MCI_BREAK:
3020 size = sizeof(MCI_BREAK_PARMS);
3021 break;
3022 /* case MCI_CAPTURE */
3023 case MCI_CLOSE:
3024 case MCI_CLOSE_DRIVER:
3025 case MCI_CONFIGURE:
3026 size = sizeof(MCI_GENERIC_PARMS);
3027 break;
3028 /* case MCI_COPY: */
3029 case MCI_CUE:
3030 switch (uDevType) {
3031 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_CUE_PARMS); break;
3032 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_CUE_PARMS); break;*/ FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3033 default: size = sizeof(MCI_GENERIC_PARMS); break;
3035 break;
3036 /* case MCI_CUT:*/
3037 case MCI_DELETE:
3038 switch (uDevType) {
3039 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_DELETE_PARMS16); map = 0x0F1111FB; break;
3040 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_DELETE_PARMS); break;
3041 default: size = sizeof(MCI_GENERIC_PARMS); break;
3043 break;
3044 /* case MCI_ESCAPE: */
3045 case MCI_FREEZE:
3046 switch (uDevType) {
3047 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_FREEZE_PARMS); map = 0x0001111B; break;
3048 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break;
3049 default: size = sizeof(MCI_GENERIC_PARMS); break;
3051 break;
3052 case MCI_GETDEVCAPS:
3053 keep = TRUE;
3054 size = sizeof(MCI_GETDEVCAPS_PARMS);
3055 break;
3056 /* case MCI_INDEX: */
3057 case MCI_INFO:
3059 LPMCI_INFO_PARMSW mip32w = (LPMCI_INFO_PARMSW)(*lParam);
3060 char* ptr;
3061 LPMCI_INFO_PARMS16 mip16;
3063 switch (uDevType) {
3064 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_INFO_PARMS16); break;
3065 default: size = sizeof(MCI_INFO_PARMS16); break;
3067 ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMCI_INFO_PARMSW) + size);
3068 if (ptr)
3070 *(LPMCI_INFO_PARMSW*)ptr = mip32w;
3071 mip16 = (LPMCI_INFO_PARMS16)(ptr + sizeof(LPMCI_INFO_PARMSW));
3072 mip16->dwCallback = mip32w->dwCallback;
3073 mip16->lpstrReturn = MapLS( HeapAlloc(GetProcessHeap(), 0, mip32w->dwRetSize / sizeof(WCHAR)) );
3074 mip16->dwRetSize = mip32w->dwRetSize / sizeof(WCHAR);
3075 if (uDevType == MCI_DEVTYPE_DIGITAL_VIDEO) {
3076 ((LPMCI_DGV_INFO_PARMS16)mip16)->dwItem = ((LPMCI_DGV_INFO_PARMSW)mip32w)->dwItem;
3078 } else {
3079 return WINMM_MAP_NOMEM;
3081 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_INFO_PARMSW);
3083 return WINMM_MAP_OKMEM;
3084 /* case MCI_MARK: */
3085 /* case MCI_MONITOR: */
3086 case MCI_OPEN:
3087 case MCI_OPEN_DRIVER:
3089 LPMCI_OPEN_PARMSW mop32w = (LPMCI_OPEN_PARMSW)(*lParam);
3090 char* ptr = HeapAlloc( GetProcessHeap(), 0,
3091 sizeof(LPMCI_OPEN_PARMSW) + sizeof(MCI_OPEN_PARMS16) + 2 * sizeof(DWORD));
3092 LPMCI_OPEN_PARMS16 mop16;
3095 if (ptr) {
3096 *(LPMCI_OPEN_PARMSW*)(ptr) = mop32w;
3097 mop16 = (LPMCI_OPEN_PARMS16)(ptr + sizeof(LPMCI_OPEN_PARMSW));
3098 mop16->dwCallback = mop32w->dwCallback;
3099 mop16->wDeviceID = mop32w->wDeviceID;
3100 if (dwFlags & MCI_OPEN_TYPE) {
3101 if (dwFlags & MCI_OPEN_TYPE_ID) {
3102 /* dword "transparent" value */
3103 mop16->lpstrDeviceType = (SEGPTR)mop32w->lpstrDeviceType;
3104 } else {
3105 /* string */
3106 mop16->lpstrDeviceType = MapLS( MCI_strdupWtoA(mop32w->lpstrDeviceType) );
3108 } else {
3109 /* nuthin' */
3110 mop16->lpstrDeviceType = 0;
3112 if (dwFlags & MCI_OPEN_ELEMENT) {
3113 if (dwFlags & MCI_OPEN_ELEMENT_ID) {
3114 mop16->lpstrElementName = (SEGPTR)mop32w->lpstrElementName;
3115 } else {
3116 mop16->lpstrElementName = MapLS( MCI_strdupWtoA(mop32w->lpstrElementName) );
3118 } else {
3119 mop16->lpstrElementName = 0;
3121 if (dwFlags & MCI_OPEN_ALIAS) {
3122 mop16->lpstrAlias = MapLS( MCI_strdupWtoA(mop32w->lpstrAlias) );
3123 } else {
3124 mop16->lpstrAlias = 0;
3126 /* copy extended information if any...
3127 * FIXME: this may seg fault if initial structure does not contain them and
3128 * the reads after msip16 fail under LDT limits...
3129 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
3130 * should not take care of extended parameters, and should be used by MCI_Open
3131 * to fetch uDevType. When, this is known, the mapping for sending the
3132 * MCI_OPEN_DRIVER shall be done depending on uDevType.
3134 memcpy(mop16 + 1, mop32w + 1, 2 * sizeof(DWORD));
3135 } else {
3136 return WINMM_MAP_NOMEM;
3138 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_PARMSW);
3140 return WINMM_MAP_OKMEM;
3141 /* case MCI_PASTE:*/
3142 case MCI_PAUSE:
3143 size = sizeof(MCI_GENERIC_PARMS);
3144 break;
3145 case MCI_PLAY:
3146 size = sizeof(MCI_PLAY_PARMS);
3147 break;
3148 case MCI_PUT:
3149 switch (uDevType) {
3150 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break;
3151 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break;
3152 default: size = sizeof(MCI_GENERIC_PARMS); break;
3154 break;
3155 case MCI_REALIZE:
3156 size = sizeof(MCI_GENERIC_PARMS);
3157 break;
3158 case MCI_RECORD:
3159 switch (uDevType) {
3160 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECORD_PARMS16); map = 0x0F1111FB; break;
3161 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_RECORD_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3162 default: size = sizeof(MCI_RECORD_PARMS); break;
3164 break;
3165 case MCI_RESUME:
3166 size = sizeof(MCI_GENERIC_PARMS);
3167 break;
3168 case MCI_SEEK:
3169 switch (uDevType) {
3170 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SEEK_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3171 default: size = sizeof(MCI_SEEK_PARMS); break;
3173 break;
3174 case MCI_SET:
3175 switch (uDevType) {
3176 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SET_PARMS); break;
3177 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SET_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3178 case MCI_DEVTYPE_SEQUENCER: size = sizeof(MCI_SEQ_SET_PARMS); break;
3179 /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned,
3180 * so not doing anything should work...
3182 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_SET_PARMS); break;
3183 default: size = sizeof(MCI_SET_PARMS); break;
3185 break;
3186 case MCI_SETAUDIO:
3187 switch (uDevType) {
3188 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SETAUDIO_PARMS16);map = 0x0000077FF; break;
3189 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3190 default: size = sizeof(MCI_GENERIC_PARMS); break;
3192 break;
3193 /* case MCI_SETTIMECODE:*/
3194 /* case MCI_SIGNAL:*/
3195 /* case MCI_SOUND:*/
3196 case MCI_SPIN:
3197 size = sizeof(MCI_SET_PARMS);
3198 break;
3199 case MCI_STATUS:
3200 keep = TRUE;
3201 switch (uDevType) {
3202 /* FIXME:
3203 * don't know if buffer for value is the one passed through lpstrDevice
3204 * or is provided by MCI driver.
3205 * Assuming solution 2: provided by MCI driver, so zeroing on entry
3207 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16); map = 0x0B6FF; break;
3208 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3209 default: size = sizeof(MCI_STATUS_PARMS); break;
3211 break;
3212 case MCI_STEP:
3213 switch (uDevType) {
3214 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STEP_PARMS); break;
3215 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STEP_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3216 case MCI_DEVTYPE_VIDEODISC: size = sizeof(MCI_VD_STEP_PARMS); break;
3217 default: size = sizeof(MCI_GENERIC_PARMS); break;
3219 break;
3220 case MCI_STOP:
3221 size = sizeof(MCI_SET_PARMS);
3222 break;
3223 case MCI_SYSINFO:
3225 LPMCI_SYSINFO_PARMSW msip32w = (LPMCI_SYSINFO_PARMSW)(*lParam);
3226 LPMCI_SYSINFO_PARMS16 msip16;
3227 char* ptr = HeapAlloc( GetProcessHeap(), 0,
3228 sizeof(LPMCI_SYSINFO_PARMSW) + sizeof(MCI_SYSINFO_PARMS16) );
3230 if (ptr) {
3231 *(LPMCI_SYSINFO_PARMSW*)(ptr) = msip32w;
3232 msip16 = (LPMCI_SYSINFO_PARMS16)(ptr + sizeof(LPMCI_SYSINFO_PARMSW));
3234 msip16->dwCallback = msip32w->dwCallback;
3235 msip16->lpstrReturn = MapLS( HeapAlloc(GetProcessHeap(), 0, msip32w->dwRetSize) );
3236 msip16->dwRetSize = msip32w->dwRetSize;
3237 msip16->dwNumber = msip32w->dwNumber;
3238 msip16->wDeviceType = msip32w->wDeviceType;
3239 } else {
3240 return WINMM_MAP_NOMEM;
3242 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_SYSINFO_PARMSW);
3244 return WINMM_MAP_OKMEM;
3245 /* case MCI_UNDO: */
3246 case MCI_UNFREEZE:
3247 switch (uDevType) {
3248 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break;
3249 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; break;
3250 default: size = sizeof(MCI_GENERIC_PARMS); break;
3252 break;
3253 case MCI_UPDATE:
3254 switch (uDevType) {
3255 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_UPDATE_PARMS16); map = 0x000B1111B; break;
3256 default: size = sizeof(MCI_GENERIC_PARMS); break;
3258 break;
3259 case MCI_WHERE:
3260 switch (uDevType) {
3261 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break;
3262 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break;
3263 default: size = sizeof(MCI_GENERIC_PARMS); break;
3265 break;
3266 case MCI_WINDOW:
3267 switch (uDevType) {
3268 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7FB; break;
3269 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7FB; break;
3270 default: size = sizeof(MCI_GENERIC_PARMS); break;
3272 break;
3273 case DRV_OPEN:
3275 LPMCI_OPEN_DRIVER_PARMSW modp32w = (LPMCI_OPEN_DRIVER_PARMSW)(*lParam);
3276 LPMCI_OPEN_DRIVER_PARMS16 modp16;
3277 char *ptr = HeapAlloc( GetProcessHeap(), 0,
3278 sizeof(LPMCI_OPEN_DRIVER_PARMSW) + sizeof(MCI_OPEN_DRIVER_PARMS16));
3280 if (ptr) {
3281 *(LPMCI_OPEN_DRIVER_PARMSW*)(ptr) = modp32w;
3282 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSW));
3283 modp16->wDeviceID = modp32w->wDeviceID;
3284 modp16->lpstrParams = MapLS( MCI_strdupWtoA(modp32w->lpstrParams) );
3285 /* other fields are gonna be filled by the driver, don't copy them */
3286 } else {
3287 return WINMM_MAP_NOMEM;
3289 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_DRIVER_PARMSW);
3291 return WINMM_MAP_OKMEM;
3292 case DRV_LOAD:
3293 case DRV_ENABLE:
3294 case DRV_CLOSE:
3295 case DRV_DISABLE:
3296 case DRV_FREE:
3297 case DRV_CONFIGURE:
3298 case DRV_QUERYCONFIGURE:
3299 case DRV_INSTALL:
3300 case DRV_REMOVE:
3301 case DRV_EXITSESSION:
3302 case DRV_EXITAPPLICATION:
3303 case DRV_POWER:
3304 return WINMM_MAP_OK;
3306 default:
3307 FIXME("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
3308 return WINMM_MAP_MSGERROR;
3310 return MCI_MsgMapper32WTo16_Create((void**)lParam, size, map, keep);
3313 /**************************************************************************
3314 * MCI_UnMapMsg32WTo16 [internal]
3316 static WINMM_MapType MCI_UnMapMsg32WTo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD_PTR lParam)
3318 int size = 0;
3319 BOOLEAN kept = FALSE; /* there is no need to compute size when kept is FALSE */
3320 DWORD map = 0;
3322 switch (wMsg) {
3323 case MCI_BREAK:
3324 break;
3325 /* case MCI_CAPTURE */
3326 case MCI_CLOSE:
3327 case MCI_CLOSE_DRIVER:
3328 case MCI_CONFIGURE:
3329 break;
3330 /* case MCI_COPY: */
3331 case MCI_CUE:
3332 break;
3333 /* case MCI_CUT: */
3334 case MCI_DELETE:
3335 break;
3336 /* case MCI_ESCAPE: */
3337 case MCI_FREEZE:
3338 break;
3339 case MCI_GETDEVCAPS:
3340 kept = TRUE;
3341 size = sizeof(MCI_GETDEVCAPS_PARMS);
3342 break;
3343 /* case MCI_INDEX: */
3344 case MCI_INFO:
3345 if (lParam) {
3346 LPMCI_INFO_PARMS16 mip16 = (LPMCI_INFO_PARMS16)MapSL(lParam);
3347 LPMCI_INFO_PARMSW mip32w = *(LPMCI_INFO_PARMSW*)((char*)mip16 - sizeof(LPMCI_INFO_PARMSW));
3349 MultiByteToWideChar(CP_ACP, 0, MapSL(mip16->lpstrReturn), mip16->dwRetSize,
3350 mip32w->lpstrReturn, mip32w->dwRetSize / sizeof(WCHAR));
3351 UnMapLS( lParam );
3352 UnMapLS( mip16->lpstrReturn );
3353 HeapFree( GetProcessHeap(), 0, (void*)MapSL(mip16->lpstrReturn) );
3354 HeapFree( GetProcessHeap(), 0, (char*)mip16 - sizeof(LPMCI_OPEN_PARMSW) );
3356 return WINMM_MAP_OK;
3357 /* case MCI_MARK: */
3358 /* case MCI_MONITOR: */
3359 case MCI_OPEN:
3360 case MCI_OPEN_DRIVER:
3361 if (lParam) {
3362 LPMCI_OPEN_PARMS16 mop16 = (LPMCI_OPEN_PARMS16)MapSL(lParam);
3363 LPMCI_OPEN_PARMSW mop32w = *(LPMCI_OPEN_PARMSW*)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSW));
3364 UnMapLS( lParam );
3365 mop32w->wDeviceID = mop16->wDeviceID;
3366 if ((dwFlags & MCI_OPEN_TYPE) && !(dwFlags & MCI_OPEN_TYPE_ID))
3368 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrDeviceType));
3369 UnMapLS( mop16->lpstrDeviceType );
3371 if ((dwFlags & MCI_OPEN_ELEMENT) && !(dwFlags & MCI_OPEN_ELEMENT_ID))
3373 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrElementName));
3374 UnMapLS( mop16->lpstrElementName );
3376 if (dwFlags & MCI_OPEN_ALIAS)
3378 HeapFree(GetProcessHeap(), 0, MapSL(mop16->lpstrAlias));
3379 UnMapLS( mop16->lpstrAlias );
3381 HeapFree( GetProcessHeap(), 0, (char*)mop16 - sizeof(LPMCI_OPEN_PARMSW) );
3383 return WINMM_MAP_OK;
3384 /* case MCI_PASTE:*/
3385 case MCI_PAUSE:
3386 break;
3387 case MCI_PLAY:
3388 break;
3389 case MCI_PUT:
3390 break;
3391 case MCI_REALIZE:
3392 break;
3393 case MCI_RECORD:
3394 break;
3395 case MCI_RESUME:
3396 break;
3397 case MCI_SEEK:
3398 break;
3399 case MCI_SET:
3400 break;
3401 case MCI_SETAUDIO:
3402 switch (uDevType) {
3403 case MCI_DEVTYPE_DIGITAL_VIDEO: map = 0x0000077FF; break;
3404 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3406 break;
3407 /* case MCI_SETTIMECODE:*/
3408 /* case MCI_SIGNAL:*/
3409 /* case MCI_SOUND:*/
3410 case MCI_SPIN:
3411 break;
3412 case MCI_STATUS:
3413 kept = TRUE;
3414 switch (uDevType) {
3415 case MCI_DEVTYPE_DIGITAL_VIDEO:
3416 if (lParam) {
3417 LPMCI_DGV_STATUS_PARMS16 mdsp16 = (LPMCI_DGV_STATUS_PARMS16)MapSL(lParam);
3418 LPMCI_DGV_STATUS_PARMSA mdsp32a = *(LPMCI_DGV_STATUS_PARMSA*)((char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA));
3420 UnMapLS( lParam );
3421 if (mdsp16) {
3422 mdsp32a->dwReturn = mdsp16->dwReturn;
3423 if (dwFlags & MCI_DGV_STATUS_DISKSPACE) {
3424 TRACE("MCI_STATUS (DGV) lpstrDrive=%08x\n", mdsp16->lpstrDrive);
3425 TRACE("MCI_STATUS (DGV) lpstrDrive=%s\n", (LPSTR)MapSL(mdsp16->lpstrDrive));
3426 UnMapLS( mdsp16->lpstrDrive );
3428 HeapFree( GetProcessHeap(), 0, (char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA) );
3429 } else {
3430 return WINMM_MAP_NOMEM;
3433 return WINMM_MAP_OKMEM;
3434 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
3435 default: size = sizeof(MCI_STATUS_PARMS); break;
3437 break;
3438 case MCI_STEP:
3439 break;
3440 case MCI_STOP:
3441 break;
3442 case MCI_SYSINFO:
3443 if (lParam) {
3444 LPMCI_SYSINFO_PARMS16 msip16 = (LPMCI_SYSINFO_PARMS16)MapSL(lParam);
3445 LPMCI_SYSINFO_PARMSW msip32w = *(LPMCI_SYSINFO_PARMSW*)((char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSW));
3447 UnMapLS( lParam );
3448 if (msip16) {
3449 MultiByteToWideChar(CP_ACP, 0, MapSL(msip16->lpstrReturn), msip16->dwRetSize,
3450 msip32w->lpstrReturn, msip32w->dwRetSize/sizeof(WCHAR));
3451 UnMapLS( msip16->lpstrReturn );
3452 HeapFree( GetProcessHeap(), 0, MapSL(msip16->lpstrReturn) );
3453 HeapFree( GetProcessHeap(), 0, (char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSW) );
3454 } else {
3455 return WINMM_MAP_NOMEM;
3458 return WINMM_MAP_OKMEM;
3459 /* case MCI_UNDO: */
3460 case MCI_UNFREEZE:
3461 break;
3462 case MCI_UPDATE:
3463 break;
3464 case MCI_WHERE:
3465 switch (uDevType) {
3466 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break;
3467 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break;
3468 default: break;
3470 break;
3471 case MCI_WINDOW:
3472 switch (uDevType) {
3473 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7666; break;
3474 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7666; break;
3475 default: break;
3477 /* FIXME: see map function */
3478 break;
3479 case DRV_OPEN:
3480 if (lParam) {
3481 LPMCI_OPEN_DRIVER_PARMS16 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)MapSL(lParam);
3482 LPMCI_OPEN_DRIVER_PARMSW modp32w = *(LPMCI_OPEN_DRIVER_PARMSW*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSW));
3484 UnMapLS( lParam );
3485 modp32w->wCustomCommandTable = modp16->wCustomCommandTable;
3486 modp32w->wType = modp16->wType;
3487 HeapFree(GetProcessHeap(), 0, MapSL(modp16->lpstrParams));
3488 UnMapLS( modp16->lpstrParams );
3489 HeapFree( GetProcessHeap(), 0, (char *)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSW) );
3491 return WINMM_MAP_OK;
3492 case DRV_LOAD:
3493 case DRV_ENABLE:
3494 case DRV_CLOSE:
3495 case DRV_DISABLE:
3496 case DRV_FREE:
3497 case DRV_CONFIGURE:
3498 case DRV_QUERYCONFIGURE:
3499 case DRV_INSTALL:
3500 case DRV_REMOVE:
3501 case DRV_EXITSESSION:
3502 case DRV_EXITAPPLICATION:
3503 case DRV_POWER:
3504 FIXME("This is a hack\n");
3505 return WINMM_MAP_OK;
3507 default:
3508 FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
3509 return WINMM_MAP_MSGERROR;
3511 return MCI_MsgMapper32WTo16_Destroy((void*)lParam, size, map, kept);
3514 void MMDRV_Init16(void)
3516 #define A(_x,_y) MMDRV_InstallMap(_x, \
3517 MMDRV_##_y##_Map16To32W, MMDRV_##_y##_UnMap16To32W, \
3518 MMDRV_##_y##_Map32WTo16, MMDRV_##_y##_UnMap32WTo16, \
3519 MMDRV_##_y##_Callback)
3520 A(MMDRV_AUX, Aux);
3521 A(MMDRV_MIXER, Mixer);
3522 A(MMDRV_MIDIIN, MidiIn);
3523 A(MMDRV_MIDIOUT, MidiOut);
3524 A(MMDRV_WAVEIN, WaveIn);
3525 A(MMDRV_WAVEOUT, WaveOut);
3526 #undef A
3528 pFnCallMMDrvFunc16 = MMDRV_CallMMDrvFunc16;
3529 pFnLoadMMDrvFunc16 = MMDRV_LoadMMDrvFunc16;
3531 pFnMciMapMsg16To32W = MCI_MapMsg16To32W;
3532 pFnMciUnMapMsg16To32W = MCI_UnMapMsg16To32W;
3533 pFnMciMapMsg32WTo16 = MCI_MapMsg32WTo16;
3534 pFnMciUnMapMsg32WTo16 = MCI_UnMapMsg32WTo16;