Release 20030408.
[wine/gsoc-2012-control.git] / dlls / winmm / message16.c
blob08282dee0c6e4754b754cf583bb7ee9e969e774c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * MMSYTEM MCI and low level mapping functions
6 * Copyright 1999 Eric Pouech
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <string.h>
24 #include <stdio.h>
25 #include <assert.h>
26 #include "wine/winbase16.h"
27 #include "winreg.h"
28 #include "winver.h"
29 #include "wownt32.h"
30 #include "winemm.h"
31 #include "digitalv.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(winmm);
36 /**************************************************************************
37 * MMDRV_Callback [internal]
39 static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
41 TRACE("CB (*%08lx)(%p %08x %08lx %08lx %08lx\n",
42 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
44 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION)
46 WORD args[8];
47 /* 16 bit func, call it */
48 TRACE("Function (16 bit) !\n");
50 args[7] = HDRVR_16(hDev);
51 args[6] = uMsg;
52 args[5] = HIWORD(mld->dwClientInstance);
53 args[4] = LOWORD(mld->dwClientInstance);
54 args[3] = HIWORD(dwParam1);
55 args[2] = LOWORD(dwParam1);
56 args[1] = HIWORD(dwParam2);
57 args[0] = LOWORD(dwParam2);
58 WOWCallback16Ex( mld->dwCallback, WCB16_PASCAL, sizeof(args), args, NULL );
59 } else {
60 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
61 mld->dwClientInstance, dwParam1, dwParam2);
65 /* =================================
66 * A U X M A P P E R S
67 * ================================= */
69 /**************************************************************************
70 * MMDRV_Aux_Map16To32A [internal]
72 static WINMM_MapType MMDRV_Aux_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
74 return WINMM_MAP_MSGERROR;
77 /**************************************************************************
78 * MMDRV_Aux_UnMap16To32A [internal]
80 static WINMM_MapType MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
82 return WINMM_MAP_MSGERROR;
85 /**************************************************************************
86 * MMDRV_Aux_Map32ATo16 [internal]
88 static WINMM_MapType MMDRV_Aux_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
90 return WINMM_MAP_MSGERROR;
93 /**************************************************************************
94 * MMDRV_Aux_UnMap32ATo16 [internal]
96 static WINMM_MapType MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
98 #if 0
99 case AUXDM_GETDEVCAPS:
100 lpCaps->wMid = ac16.wMid;
101 lpCaps->wPid = ac16.wPid;
102 lpCaps->vDriverVersion = ac16.vDriverVersion;
103 strcpy(lpCaps->szPname, ac16.szPname);
104 lpCaps->wTechnology = ac16.wTechnology;
105 lpCaps->dwSupport = ac16.dwSupport;
106 #endif
107 return WINMM_MAP_MSGERROR;
110 /**************************************************************************
111 * MMDRV_Aux_Callback [internal]
113 static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
115 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
117 FIXME("NIY\n");
118 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
121 /* =================================
122 * M I X E R M A P P E R S
123 * ================================= */
125 /**************************************************************************
126 * xMMDRV_Mixer_Map16To32A [internal]
128 static WINMM_MapType MMDRV_Mixer_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
130 return WINMM_MAP_MSGERROR;
133 /**************************************************************************
134 * MMDRV_Mixer_UnMap16To32A [internal]
136 static WINMM_MapType MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
138 #if 0
139 MIXERCAPSA micA;
140 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
142 if (ret == MMSYSERR_NOERROR) {
143 mixcaps->wMid = micA.wMid;
144 mixcaps->wPid = micA.wPid;
145 mixcaps->vDriverVersion = micA.vDriverVersion;
146 strcpy(mixcaps->szPname, micA.szPname);
147 mixcaps->fdwSupport = micA.fdwSupport;
148 mixcaps->cDestinations = micA.cDestinations;
150 return ret;
151 #endif
152 return WINMM_MAP_MSGERROR;
155 /**************************************************************************
156 * MMDRV_Mixer_Map32ATo16 [internal]
158 static WINMM_MapType MMDRV_Mixer_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
160 return WINMM_MAP_MSGERROR;
163 /**************************************************************************
164 * MMDRV_Mixer_UnMap32ATo16 [internal]
166 static WINMM_MapType MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
168 return WINMM_MAP_MSGERROR;
171 /**************************************************************************
172 * MMDRV_Mixer_Callback [internal]
174 static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
176 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
178 FIXME("NIY\n");
179 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
182 /* =================================
183 * M I D I I N M A P P E R S
184 * ================================= */
186 /**************************************************************************
187 * MMDRV_MidiIn_Map16To32A [internal]
189 static WINMM_MapType MMDRV_MidiIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
191 return WINMM_MAP_MSGERROR;
194 /**************************************************************************
195 * MMDRV_MidiIn_UnMap16To32A [internal]
197 static WINMM_MapType MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
199 return WINMM_MAP_MSGERROR;
202 /**************************************************************************
203 * MMDRV_MidiIn_Map32ATo16 [internal]
205 static WINMM_MapType MMDRV_MidiIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
207 return WINMM_MAP_MSGERROR;
210 /**************************************************************************
211 * MMDRV_MidiIn_UnMap32ATo16 [internal]
213 static WINMM_MapType MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
215 return WINMM_MAP_MSGERROR;
218 /**************************************************************************
219 * MMDRV_MidiIn_Callback [internal]
221 static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
223 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
225 switch (uMsg) {
226 case MIM_OPEN:
227 case MIM_CLOSE:
228 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
230 case MIM_DATA:
231 case MIM_MOREDATA:
232 case MIM_ERROR:
233 /* dwParam1 & dwParam2 are are data, nothing to do */
234 break;
235 case MIM_LONGDATA:
236 case MIM_LONGERROR:
237 /* dwParam1 points to a MidiHdr, work to be done !!! */
238 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
239 /* initial map is: 32 => 16 */
240 LPMIDIHDR mh16 = MapSL(dwParam1);
241 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
243 dwParam1 = (DWORD)mh32;
244 mh32->dwFlags = mh16->dwFlags;
245 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
246 if (mh32->reserved >= sizeof(MIDIHDR))
247 mh32->dwOffset = mh16->dwOffset;
248 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
249 /* initial map is: 16 => 32 */
250 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
251 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
252 LPMIDIHDR mh16 = MapSL(segmh16);
254 dwParam1 = (DWORD)segmh16;
255 mh16->dwFlags = mh32->dwFlags;
256 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
257 if (mh16->reserved >= sizeof(MIDIHDR))
258 mh16->dwOffset = mh32->dwOffset;
260 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
261 break;
262 /* case MOM_POSITIONCB: */
263 default:
264 ERR("Unknown msg %u\n", uMsg);
267 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
270 /* =================================
271 * M I D I O U T M A P P E R S
272 * ================================= */
274 /**************************************************************************
275 * MMDRV_MidiOut_Map16To32A [internal]
277 static WINMM_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
279 WINMM_MapType ret = WINMM_MAP_MSGERROR;
281 switch (wMsg) {
282 case MODM_GETNUMDEVS:
283 case MODM_DATA:
284 case MODM_RESET:
285 case MODM_SETVOLUME:
286 ret = WINMM_MAP_OK;
287 break;
289 case MODM_OPEN:
290 case MODM_CLOSE:
291 case MODM_GETVOLUME:
292 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
293 break;
295 case MODM_GETDEVCAPS:
297 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
298 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
300 if (moc32) {
301 *(LPMIDIOUTCAPS16*)moc32 = moc16;
302 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
303 *lpParam1 = (DWORD)moc32;
304 *lpParam2 = sizeof(MIDIOUTCAPSA);
306 ret = WINMM_MAP_OKMEM;
307 } else {
308 ret = WINMM_MAP_NOMEM;
311 break;
312 case MODM_PREPARE:
314 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
315 LPMIDIHDR mh16 = MapSL(*lpParam1);
317 if (mh32) {
318 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
319 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
320 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
321 mh32->dwBufferLength = mh16->dwBufferLength;
322 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
323 mh32->dwUser = mh16->dwUser;
324 mh32->dwFlags = mh16->dwFlags;
325 /* FIXME: nothing on mh32->lpNext */
326 /* could link the mh32->lpNext at this level for memory house keeping */
327 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
328 mh16->lpNext = mh32; /* for reuse in unprepare and write */
329 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
330 mh16->reserved = *lpParam2;
331 *lpParam1 = (DWORD)mh32;
332 *lpParam2 = sizeof(MIDIHDR);
334 ret = WINMM_MAP_OKMEM;
335 } else {
336 ret = WINMM_MAP_NOMEM;
339 break;
340 case MODM_UNPREPARE:
341 case MODM_LONGDATA:
343 LPMIDIHDR mh16 = MapSL(*lpParam1);
344 LPMIDIHDR mh32 = (LPMIDIHDR)mh16->lpNext;
346 *lpParam1 = (DWORD)mh32;
347 *lpParam2 = sizeof(MIDIHDR);
348 /* dwBufferLength can be reduced between prepare & write */
349 if (wMsg == MODM_LONGDATA && mh32->dwBufferLength < mh16->dwBufferLength) {
350 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
351 mh32->dwBufferLength, mh16->dwBufferLength);
352 } else
353 mh32->dwBufferLength = mh16->dwBufferLength;
354 ret = WINMM_MAP_OKMEM;
356 break;
358 case MODM_CACHEPATCHES:
359 case MODM_CACHEDRUMPATCHES:
360 default:
361 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
362 break;
364 return ret;
367 /**************************************************************************
368 * MMDRV_MidiOut_UnMap16To32A [internal]
370 static WINMM_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
372 WINMM_MapType ret = WINMM_MAP_MSGERROR;
374 switch (wMsg) {
375 case MODM_GETNUMDEVS:
376 case MODM_DATA:
377 case MODM_RESET:
378 case MODM_SETVOLUME:
379 ret = WINMM_MAP_OK;
380 break;
382 case MODM_OPEN:
383 case MODM_CLOSE:
384 case MODM_GETVOLUME:
385 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
386 break;
388 case MODM_GETDEVCAPS:
390 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
391 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
393 moc16->wMid = moc32->wMid;
394 moc16->wPid = moc32->wPid;
395 moc16->vDriverVersion = moc32->vDriverVersion;
396 strcpy(moc16->szPname, moc32->szPname);
397 moc16->wTechnology = moc32->wTechnology;
398 moc16->wVoices = moc32->wVoices;
399 moc16->wNotes = moc32->wNotes;
400 moc16->wChannelMask = moc32->wChannelMask;
401 moc16->dwSupport = moc32->dwSupport;
402 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
403 ret = WINMM_MAP_OK;
405 break;
406 case MODM_PREPARE:
407 case MODM_UNPREPARE:
408 case MODM_LONGDATA:
410 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
411 LPMIDIHDR mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
413 assert(mh16->lpNext == mh32);
414 mh16->dwBufferLength = mh32->dwBufferLength;
415 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
416 mh16->dwUser = mh32->dwUser;
417 mh16->dwFlags = mh32->dwFlags;
418 if (mh16->reserved >= sizeof(MIDIHDR))
419 mh16->dwOffset = mh32->dwOffset;
421 if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
422 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
423 mh16->lpNext = 0;
425 ret = WINMM_MAP_OK;
427 break;
429 case MODM_CACHEPATCHES:
430 case MODM_CACHEDRUMPATCHES:
431 default:
432 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
433 break;
435 return ret;
438 /**************************************************************************
439 * MMDRV_MidiOut_Map32ATo16 [internal]
441 static WINMM_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
443 WINMM_MapType ret = WINMM_MAP_MSGERROR;
445 switch (wMsg) {
446 case MODM_CLOSE:
447 case MODM_GETNUMDEVS:
448 case MODM_DATA:
449 case MODM_RESET:
450 case MODM_SETVOLUME:
451 ret = WINMM_MAP_OK;
452 break;
453 case MODM_GETDEVCAPS:
455 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
456 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA)+sizeof(MIDIOUTCAPS16));
458 if (ptr) {
459 *(LPMIDIOUTCAPSA*)ptr = moc32;
460 ret = WINMM_MAP_OKMEM;
461 } else {
462 ret = WINMM_MAP_NOMEM;
464 *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSA);
465 *lpParam2 = sizeof(MIDIOUTCAPS16);
467 break;
468 case MODM_PREPARE:
470 LPMIDIHDR mh32 = (LPMIDIHDR)*lpParam1;
471 LPMIDIHDR mh16;
472 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
473 sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
475 if (ptr) {
476 *(LPMIDIHDR*)ptr = mh32;
477 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
478 *lpParam1 = MapLS(mh16);
479 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
480 /* data will be copied on WODM_WRITE */
481 mh16->dwBufferLength = mh32->dwBufferLength;
482 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
483 mh16->dwUser = mh32->dwUser;
484 mh16->dwFlags = mh32->dwFlags;
485 /* FIXME: nothing on mh32->lpNext */
486 /* could link the mh32->lpNext at this level for memory house keeping */
487 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
489 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
490 mh32->reserved = *lpParam2;
492 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
493 *lpParam1, (DWORD)mh16->lpData,
494 mh32->dwBufferLength, (DWORD)mh32->lpData);
495 *lpParam2 = sizeof(MIDIHDR);
497 ret = WINMM_MAP_OKMEM;
498 } else {
499 ret = WINMM_MAP_NOMEM;
502 break;
503 case MODM_UNPREPARE:
504 case MODM_LONGDATA:
506 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
507 LPMIDIHDR mh16 = (LPMIDIHDR)mh32->lpNext;
508 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
510 assert(*(LPMIDIHDR*)ptr == mh32);
512 if (wMsg == MODM_LONGDATA)
513 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
515 *lpParam1 = MapLS(mh16);
516 *lpParam2 = sizeof(MIDIHDR);
517 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
518 *lpParam1, (DWORD)mh16->lpData, mh32->dwBufferLength, (DWORD)mh32->lpData);
520 /* dwBufferLength can be reduced between prepare & write */
521 if (wMsg == MODM_LONGDATA && mh16->dwBufferLength < mh32->dwBufferLength) {
522 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
523 mh16->dwBufferLength, mh32->dwBufferLength);
524 } else
525 mh16->dwBufferLength = mh32->dwBufferLength;
526 ret = WINMM_MAP_OKMEM;
528 break;
529 case MODM_OPEN:
531 LPMIDIOPENDESC mod32 = (LPMIDIOPENDESC)*lpParam1;
532 LPVOID ptr;
533 LPMIDIOPENDESC16 mod16;
535 /* allocated data are mapped as follows:
536 LPMIDIOPENDESC ptr to orig lParam1
537 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
538 DWORD dwUser passed to driver
539 MIDIOPENDESC16 mod16: openDesc passed to driver
540 MIDIOPENSTRMID cIds
542 ptr = HeapAlloc( GetProcessHeap(), 0,
543 sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
544 mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
546 if (ptr) {
547 SEGPTR segptr = MapLS(ptr);
548 *(LPMIDIOPENDESC*)ptr = mod32;
549 *(LPDWORD)((char*)ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
550 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
552 mod16->hMidi = HMIDI_16(mod32->hMidi);
553 mod16->dwCallback = mod32->dwCallback;
554 mod16->dwInstance = mod32->dwInstance;
555 mod16->dnDevNode = mod32->dnDevNode;
556 mod16->cIds = mod32->cIds;
557 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
559 *lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
560 *lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
562 ret = WINMM_MAP_OKMEM;
563 } else {
564 ret = WINMM_MAP_NOMEM;
567 break;
568 case MODM_GETVOLUME:
569 case MODM_CACHEPATCHES:
570 case MODM_CACHEDRUMPATCHES:
571 default:
572 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
573 break;
575 return ret;
578 /**************************************************************************
579 * MMDRV_MidiOut_UnMap32ATo16 [internal]
581 static WINMM_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
583 WINMM_MapType ret = WINMM_MAP_MSGERROR;
585 switch (wMsg) {
586 case MODM_CLOSE:
587 case MODM_GETNUMDEVS:
588 case MODM_DATA:
589 case MODM_RESET:
590 case MODM_SETVOLUME:
591 ret = WINMM_MAP_OK;
592 break;
593 case MODM_GETDEVCAPS:
595 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
596 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
597 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
599 moc32->wMid = moc16->wMid;
600 moc32->wPid = moc16->wPid;
601 moc32->vDriverVersion = moc16->vDriverVersion;
602 strcpy(moc32->szPname, moc16->szPname);
603 moc32->wTechnology = moc16->wTechnology;
604 moc32->wVoices = moc16->wVoices;
605 moc32->wNotes = moc16->wNotes;
606 moc32->wChannelMask = moc16->wChannelMask;
607 moc32->dwSupport = moc16->dwSupport;
608 UnMapLS( *lpParam1 );
609 HeapFree( GetProcessHeap(), 0, ptr );
610 ret = WINMM_MAP_OK;
612 break;
613 case MODM_PREPARE:
614 case MODM_UNPREPARE:
615 case MODM_LONGDATA:
617 LPMIDIHDR mh16 = MapSL(*lpParam1);
618 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
619 LPMIDIHDR mh32 = *(LPMIDIHDR*)ptr;
621 assert(mh32->lpNext == (LPMIDIHDR)mh16);
622 UnMapLS( *lpParam1 );
623 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
624 mh32->dwUser = mh16->dwUser;
625 mh32->dwFlags = mh16->dwFlags;
627 if (wMsg == MODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
628 HeapFree( GetProcessHeap(), 0, ptr );
629 mh32->lpNext = 0;
631 ret = WINMM_MAP_OK;
633 break;
634 case MODM_OPEN:
636 LPMIDIOPENDESC16 mod16 = MapSL(*lpParam1);
637 LPSTR ptr = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
638 UnMapLS( *lpParam1 );
639 **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
641 HeapFree( GetProcessHeap(), 0, ptr );
642 ret = WINMM_MAP_OK;
644 break;
645 case MODM_GETVOLUME:
646 case MODM_CACHEPATCHES:
647 case MODM_CACHEDRUMPATCHES:
648 default:
649 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
650 break;
652 return ret;
655 /**************************************************************************
656 * MMDRV_MidiOut_Callback [internal]
658 static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
660 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
662 switch (uMsg) {
663 case MOM_OPEN:
664 case MOM_CLOSE:
665 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
666 break;
667 case MOM_DONE:
668 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
669 /* initial map is: 32 => 16 */
670 LPMIDIHDR mh16 = MapSL(dwParam1);
671 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
673 dwParam1 = (DWORD)mh32;
674 mh32->dwFlags = mh16->dwFlags;
675 mh32->dwOffset = mh16->dwOffset;
676 if (mh32->reserved >= sizeof(MIDIHDR))
677 mh32->dwOffset = mh16->dwOffset;
678 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
679 /* initial map is: 16 => 32 */
680 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
681 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
682 LPMIDIHDR mh16 = MapSL(segmh16);
684 dwParam1 = (DWORD)segmh16;
685 mh16->dwFlags = mh32->dwFlags;
686 if (mh16->reserved >= sizeof(MIDIHDR))
687 mh16->dwOffset = mh32->dwOffset;
689 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
690 break;
691 /* case MOM_POSITIONCB: */
692 default:
693 ERR("Unknown msg %u\n", uMsg);
696 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
699 /* =================================
700 * W A V E I N M A P P E R S
701 * ================================= */
703 /**************************************************************************
704 * MMDRV_WaveIn_Map16To32A [internal]
706 static WINMM_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
708 WINMM_MapType ret = WINMM_MAP_MSGERROR;
710 switch (wMsg) {
711 case WIDM_GETNUMDEVS:
712 case WIDM_RESET:
713 case WIDM_START:
714 case WIDM_STOP:
715 ret = WINMM_MAP_OK;
716 break;
717 case WIDM_OPEN:
718 case WIDM_CLOSE:
719 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
720 break;
721 case WIDM_GETDEVCAPS:
723 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
724 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
726 if (wic32) {
727 *(LPWAVEINCAPS16*)wic32 = wic16;
728 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
729 *lpParam1 = (DWORD)wic32;
730 *lpParam2 = sizeof(WAVEINCAPSA);
732 ret = WINMM_MAP_OKMEM;
733 } else {
734 ret = WINMM_MAP_NOMEM;
737 break;
738 case WIDM_GETPOS:
740 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
741 LPMMTIME16 mmt16 = MapSL(*lpParam1);
743 if (mmt32) {
744 *(LPMMTIME16*)mmt32 = mmt16;
745 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
747 mmt32->wType = mmt16->wType;
748 *lpParam1 = (DWORD)mmt32;
749 *lpParam2 = sizeof(MMTIME);
751 ret = WINMM_MAP_OKMEM;
752 } else {
753 ret = WINMM_MAP_NOMEM;
756 break;
757 case WIDM_PREPARE:
759 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
760 LPWAVEHDR wh16 = MapSL(*lpParam1);
762 if (wh32) {
763 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
764 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
765 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
766 wh32->dwBufferLength = wh16->dwBufferLength;
767 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
768 wh32->dwUser = wh16->dwUser;
769 wh32->dwFlags = wh16->dwFlags;
770 wh32->dwLoops = wh16->dwLoops;
771 /* FIXME: nothing on wh32->lpNext */
772 /* could link the wh32->lpNext at this level for memory house keeping */
773 wh16->lpNext = wh32; /* for reuse in unprepare and write */
774 *lpParam1 = (DWORD)wh32;
775 *lpParam2 = sizeof(WAVEHDR);
777 ret = WINMM_MAP_OKMEM;
778 } else {
779 ret = WINMM_MAP_NOMEM;
782 break;
783 case WIDM_ADDBUFFER:
784 case WIDM_UNPREPARE:
786 LPWAVEHDR wh16 = MapSL(*lpParam1);
787 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
789 *lpParam1 = (DWORD)wh32;
790 *lpParam2 = sizeof(WAVEHDR);
791 /* dwBufferLength can be reduced between prepare & write */
792 if (wMsg == WIDM_ADDBUFFER && wh32->dwBufferLength < wh16->dwBufferLength) {
793 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
794 wh32->dwBufferLength, wh16->dwBufferLength);
795 } else
796 wh32->dwBufferLength = wh16->dwBufferLength;
797 ret = WINMM_MAP_OKMEM;
799 break;
800 case WIDM_MAPPER_STATUS:
801 /* just a single DWORD */
802 *lpParam2 = (DWORD)MapSL(*lpParam2);
803 ret = WINMM_MAP_OK;
804 break;
805 default:
806 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
807 break;
809 return ret;
812 /**************************************************************************
813 * MMDRV_WaveIn_UnMap16To32A [internal]
815 static WINMM_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
817 WINMM_MapType ret = WINMM_MAP_MSGERROR;
819 switch (wMsg) {
820 case WIDM_GETNUMDEVS:
821 case WIDM_RESET:
822 case WIDM_START:
823 case WIDM_STOP:
824 case WIDM_MAPPER_STATUS:
825 ret = WINMM_MAP_OK;
826 break;
827 case WIDM_OPEN:
828 case WIDM_CLOSE:
829 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
830 break;
831 case WIDM_GETDEVCAPS:
833 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
834 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
836 wic16->wMid = wic32->wMid;
837 wic16->wPid = wic32->wPid;
838 wic16->vDriverVersion = wic32->vDriverVersion;
839 strcpy(wic16->szPname, wic32->szPname);
840 wic16->dwFormats = wic32->dwFormats;
841 wic16->wChannels = wic32->wChannels;
842 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
843 ret = WINMM_MAP_OK;
845 break;
846 case WIDM_GETPOS:
848 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
849 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
851 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
852 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
853 ret = WINMM_MAP_OK;
855 break;
856 case WIDM_ADDBUFFER:
857 case WIDM_PREPARE:
858 case WIDM_UNPREPARE:
860 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
861 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
863 assert(wh16->lpNext == wh32);
864 wh16->dwBufferLength = wh32->dwBufferLength;
865 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
866 wh16->dwUser = wh32->dwUser;
867 wh16->dwFlags = wh32->dwFlags;
868 wh16->dwLoops = wh32->dwLoops;
870 if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
871 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
872 wh16->lpNext = 0;
874 ret = WINMM_MAP_OK;
876 break;
877 default:
878 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
879 break;
881 return ret;
884 /**************************************************************************
885 * MMDRV_WaveIn_Map32ATo16 [internal]
887 static WINMM_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
889 WINMM_MapType ret = WINMM_MAP_MSGERROR;
891 switch (wMsg) {
892 case WIDM_CLOSE:
893 case WIDM_GETNUMDEVS:
894 case WIDM_RESET:
895 case WIDM_START:
896 case WIDM_STOP:
897 ret = WINMM_MAP_OK;
898 break;
900 case WIDM_OPEN:
902 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
903 int sz = sizeof(WAVEFORMATEX);
904 LPVOID ptr;
905 LPWAVEOPENDESC16 wod16;
907 /* allocated data are mapped as follows:
908 LPWAVEOPENDESC ptr to orig lParam1
909 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
910 DWORD dwUser passed to driver
911 WAVEOPENDESC16 wod16: openDesc passed to driver
912 WAVEFORMATEX openDesc->lpFormat passed to driver
913 xxx extra bytes to WAVEFORMATEX
915 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
916 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
917 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
920 ptr = HeapAlloc( GetProcessHeap(), 0,
921 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
923 if (ptr) {
924 SEGPTR seg_ptr = MapLS( ptr );
925 *(LPWAVEOPENDESC*)ptr = wod32;
926 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
927 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
929 wod16->hWave = HWAVE_16(wod32->hWave);
930 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
931 memcpy(wod16 + 1, wod32->lpFormat, sz);
933 wod16->dwCallback = wod32->dwCallback;
934 wod16->dwInstance = wod32->dwInstance;
935 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
936 wod16->dnDevNode = wod32->dnDevNode;
938 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
939 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
941 ret = WINMM_MAP_OKMEM;
942 } else {
943 ret = WINMM_MAP_NOMEM;
946 break;
947 case WIDM_PREPARE:
949 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
950 LPWAVEHDR wh16;
951 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
952 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
954 if (ptr) {
955 SEGPTR seg_ptr = MapLS( ptr );
956 *(LPWAVEHDR*)ptr = wh32;
957 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
958 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
959 /* data will be copied on WODM_WRITE */
960 wh16->dwBufferLength = wh32->dwBufferLength;
961 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
962 wh16->dwUser = wh32->dwUser;
963 wh16->dwFlags = wh32->dwFlags;
964 wh16->dwLoops = wh32->dwLoops;
965 /* FIXME: nothing on wh32->lpNext */
966 /* could link the wh32->lpNext at this level for memory house keeping */
967 wh32->lpNext = wh16; /* for reuse in unprepare and write */
968 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
969 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
970 wh32->dwBufferLength, (DWORD)wh32->lpData);
971 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
972 *lpParam2 = sizeof(WAVEHDR);
974 ret = WINMM_MAP_OKMEM;
975 } else {
976 ret = WINMM_MAP_NOMEM;
979 break;
980 case WIDM_ADDBUFFER:
981 case WIDM_UNPREPARE:
983 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
984 LPWAVEHDR wh16 = wh32->lpNext;
985 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
986 SEGPTR seg_ptr = MapLS( ptr );
988 assert(*(LPWAVEHDR*)ptr == wh32);
990 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
991 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
992 wh32->dwBufferLength, (DWORD)wh32->lpData);
994 if (wMsg == WIDM_ADDBUFFER)
995 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
997 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
998 *lpParam2 = sizeof(WAVEHDR);
999 /* dwBufferLength can be reduced between prepare & write */
1000 if (wMsg == WIDM_ADDBUFFER && wh16->dwBufferLength < wh32->dwBufferLength) {
1001 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1002 wh16->dwBufferLength, wh32->dwBufferLength);
1003 } else
1004 wh16->dwBufferLength = wh32->dwBufferLength;
1005 ret = WINMM_MAP_OKMEM;
1007 break;
1008 case WIDM_GETDEVCAPS:
1010 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
1011 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
1013 if (ptr) {
1014 *(LPWAVEINCAPSA*)ptr = wic32;
1015 ret = WINMM_MAP_OKMEM;
1016 } else {
1017 ret = WINMM_MAP_NOMEM;
1019 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSA);
1020 *lpParam2 = sizeof(WAVEINCAPS16);
1022 break;
1023 case WIDM_GETPOS:
1025 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1026 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1027 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1029 if (ptr) {
1030 *(LPMMTIME*)ptr = mmt32;
1031 mmt16->wType = mmt32->wType;
1032 ret = WINMM_MAP_OKMEM;
1033 } else {
1034 ret = WINMM_MAP_NOMEM;
1036 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1037 *lpParam2 = sizeof(MMTIME16);
1039 break;
1040 case DRVM_MAPPER_STATUS:
1042 LPDWORD p32 = (LPDWORD)*lpParam2;
1043 *lpParam2 = MapLS(p32);
1044 ret = WINMM_MAP_OKMEM;
1046 break;
1047 default:
1048 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1049 break;
1051 return ret;
1054 /**************************************************************************
1055 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1057 static WINMM_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
1059 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1061 switch (wMsg) {
1062 case WIDM_CLOSE:
1063 case WIDM_GETNUMDEVS:
1064 case WIDM_RESET:
1065 case WIDM_START:
1066 case WIDM_STOP:
1067 ret = WINMM_MAP_OK;
1068 break;
1070 case WIDM_OPEN:
1072 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1073 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1074 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1076 UnMapLS( *lpParam1 );
1077 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1078 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1079 HeapFree( GetProcessHeap(), 0, ptr );
1080 ret = WINMM_MAP_OK;
1082 break;
1084 case WIDM_ADDBUFFER:
1085 case WIDM_PREPARE:
1086 case WIDM_UNPREPARE:
1088 LPWAVEHDR wh16 = MapSL(*lpParam1);
1089 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1090 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1092 assert(wh32->lpNext == wh16);
1093 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1094 wh32->dwUser = wh16->dwUser;
1095 wh32->dwFlags = wh16->dwFlags;
1096 wh32->dwLoops = wh16->dwLoops;
1097 UnMapLS( *lpParam1 );
1099 if (wMsg == WIDM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1100 HeapFree( GetProcessHeap(), 0, ptr );
1101 wh32->lpNext = 0;
1103 ret = WINMM_MAP_OK;
1105 break;
1106 case WIDM_GETDEVCAPS:
1108 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
1109 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1110 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
1112 wic32->wMid = wic16->wMid;
1113 wic32->wPid = wic16->wPid;
1114 wic32->vDriverVersion = wic16->vDriverVersion;
1115 strcpy(wic32->szPname, wic16->szPname);
1116 wic32->dwFormats = wic16->dwFormats;
1117 wic32->wChannels = wic16->wChannels;
1118 UnMapLS( *lpParam1 );
1119 HeapFree( GetProcessHeap(), 0, ptr );
1120 ret = WINMM_MAP_OK;
1122 break;
1123 case WIDM_GETPOS:
1125 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1126 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1127 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1129 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1130 UnMapLS( *lpParam1 );
1131 HeapFree( GetProcessHeap(), 0, ptr );
1132 ret = WINMM_MAP_OK;
1134 break;
1135 case DRVM_MAPPER_STATUS:
1137 UnMapLS( *lpParam2 );
1138 ret = WINMM_MAP_OK;
1140 break;
1141 default:
1142 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1143 break;
1145 return ret;
1148 /**************************************************************************
1149 * MMDRV_WaveIn_Callback [internal]
1151 static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1153 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1155 switch (uMsg) {
1156 case WIM_OPEN:
1157 case WIM_CLOSE:
1158 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1159 break;
1160 case WIM_DATA:
1161 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1162 /* initial map is: 32 => 16 */
1163 LPWAVEHDR wh16 = MapSL(dwParam1);
1164 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1166 dwParam1 = (DWORD)wh32;
1167 wh32->dwFlags = wh16->dwFlags;
1168 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1169 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1170 /* initial map is: 16 => 32 */
1171 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1172 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1173 LPWAVEHDR wh16 = MapSL(segwh16);
1175 dwParam1 = (DWORD)segwh16;
1176 wh16->dwFlags = wh32->dwFlags;
1177 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1179 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1180 break;
1181 default:
1182 ERR("Unknown msg %u\n", uMsg);
1185 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1188 /* =================================
1189 * W A V E O U T M A P P E R S
1190 * ================================= */
1192 /**************************************************************************
1193 * MMDRV_WaveOut_Map16To32A [internal]
1195 static WINMM_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1197 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1199 switch (wMsg) {
1200 /* nothing to do */
1201 case WODM_BREAKLOOP:
1202 case WODM_CLOSE:
1203 case WODM_GETNUMDEVS:
1204 case WODM_PAUSE:
1205 case WODM_RESET:
1206 case WODM_RESTART:
1207 case WODM_SETPITCH:
1208 case WODM_SETPLAYBACKRATE:
1209 case WODM_SETVOLUME:
1210 ret = WINMM_MAP_OK;
1211 break;
1213 case WODM_GETPITCH:
1214 case WODM_GETPLAYBACKRATE:
1215 case WODM_GETVOLUME:
1216 case WODM_OPEN:
1217 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1218 break;
1220 case WODM_GETDEVCAPS:
1222 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1223 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1225 if (woc32) {
1226 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1227 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1228 *lpParam1 = (DWORD)woc32;
1229 *lpParam2 = sizeof(WAVEOUTCAPSA);
1231 ret = WINMM_MAP_OKMEM;
1232 } else {
1233 ret = WINMM_MAP_NOMEM;
1236 break;
1237 case WODM_GETPOS:
1239 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1240 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1242 if (mmt32) {
1243 *(LPMMTIME16*)mmt32 = mmt16;
1244 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1246 mmt32->wType = mmt16->wType;
1247 *lpParam1 = (DWORD)mmt32;
1248 *lpParam2 = sizeof(MMTIME);
1250 ret = WINMM_MAP_OKMEM;
1251 } else {
1252 ret = WINMM_MAP_NOMEM;
1255 break;
1256 case WODM_PREPARE:
1258 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1259 LPWAVEHDR wh16 = MapSL(*lpParam1);
1261 if (wh32) {
1262 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1263 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1264 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1265 wh32->dwBufferLength = wh16->dwBufferLength;
1266 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1267 wh32->dwUser = wh16->dwUser;
1268 wh32->dwFlags = wh16->dwFlags;
1269 wh32->dwLoops = wh16->dwLoops;
1270 /* FIXME: nothing on wh32->lpNext */
1271 /* could link the wh32->lpNext at this level for memory house keeping */
1272 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1273 *lpParam1 = (DWORD)wh32;
1274 *lpParam2 = sizeof(WAVEHDR);
1276 ret = WINMM_MAP_OKMEM;
1277 } else {
1278 ret = WINMM_MAP_NOMEM;
1281 break;
1282 case WODM_UNPREPARE:
1283 case WODM_WRITE:
1285 LPWAVEHDR wh16 = MapSL(*lpParam1);
1286 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1288 *lpParam1 = (DWORD)wh32;
1289 *lpParam2 = sizeof(WAVEHDR);
1290 /* dwBufferLength can be reduced between prepare & write */
1291 if (wMsg == WODM_WRITE && wh32->dwBufferLength < wh16->dwBufferLength) {
1292 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1293 wh32->dwBufferLength, wh16->dwBufferLength);
1294 } else
1295 wh32->dwBufferLength = wh16->dwBufferLength;
1296 ret = WINMM_MAP_OKMEM;
1298 break;
1299 case WODM_MAPPER_STATUS:
1300 *lpParam2 = (DWORD)MapSL(*lpParam2);
1301 ret = WINMM_MAP_OK;
1302 break;
1303 default:
1304 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1305 break;
1307 return ret;
1310 /**************************************************************************
1311 * MMDRV_WaveOut_UnMap16To32A [internal]
1313 static WINMM_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
1315 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1317 switch (wMsg) {
1318 /* nothing to do */
1319 case WODM_BREAKLOOP:
1320 case WODM_CLOSE:
1321 case WODM_GETNUMDEVS:
1322 case WODM_PAUSE:
1323 case WODM_RESET:
1324 case WODM_RESTART:
1325 case WODM_SETPITCH:
1326 case WODM_SETPLAYBACKRATE:
1327 case WODM_SETVOLUME:
1328 case WODM_MAPPER_STATUS:
1329 ret = WINMM_MAP_OK;
1330 break;
1332 case WODM_GETPITCH:
1333 case WODM_GETPLAYBACKRATE:
1334 case WODM_GETVOLUME:
1335 case WODM_OPEN:
1336 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1337 break;
1339 case WODM_GETDEVCAPS:
1341 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1342 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1344 woc16->wMid = woc32->wMid;
1345 woc16->wPid = woc32->wPid;
1346 woc16->vDriverVersion = woc32->vDriverVersion;
1347 strcpy(woc16->szPname, woc32->szPname);
1348 woc16->dwFormats = woc32->dwFormats;
1349 woc16->wChannels = woc32->wChannels;
1350 woc16->dwSupport = woc32->dwSupport;
1351 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1352 ret = WINMM_MAP_OK;
1354 break;
1355 case WODM_GETPOS:
1357 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1358 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1360 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1361 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1362 ret = WINMM_MAP_OK;
1364 break;
1365 case WODM_PREPARE:
1366 case WODM_UNPREPARE:
1367 case WODM_WRITE:
1369 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1370 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1372 assert(wh16->lpNext == wh32);
1373 wh16->dwBufferLength = wh32->dwBufferLength;
1374 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1375 wh16->dwUser = wh32->dwUser;
1376 wh16->dwFlags = wh32->dwFlags;
1377 wh16->dwLoops = wh32->dwLoops;
1379 if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1380 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1381 wh16->lpNext = 0;
1383 ret = WINMM_MAP_OK;
1385 break;
1386 default:
1387 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1388 break;
1390 return ret;
1393 /**************************************************************************
1394 * MMDRV_WaveOut_Map32ATo16 [internal]
1396 static WINMM_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1398 WINMM_MapType ret;
1400 switch (wMsg) {
1401 /* nothing to do */
1402 case WODM_BREAKLOOP:
1403 case WODM_CLOSE:
1404 case WODM_GETNUMDEVS:
1405 case WODM_PAUSE:
1406 case WODM_RESET:
1407 case WODM_RESTART:
1408 case WODM_SETPITCH:
1409 case WODM_SETPLAYBACKRATE:
1410 case WODM_SETVOLUME:
1411 ret = WINMM_MAP_OK;
1412 break;
1414 case WODM_GETDEVCAPS:
1416 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1417 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1418 sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1420 if (ptr) {
1421 *(LPWAVEOUTCAPSA*)ptr = woc32;
1422 ret = WINMM_MAP_OKMEM;
1423 } else {
1424 ret = WINMM_MAP_NOMEM;
1426 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSA);
1427 *lpParam2 = sizeof(WAVEOUTCAPS16);
1429 break;
1430 case WODM_GETPITCH:
1431 FIXME("NIY: no conversion yet\n");
1432 ret = WINMM_MAP_MSGERROR;
1433 break;
1434 case WODM_GETPLAYBACKRATE:
1435 FIXME("NIY: no conversion yet\n");
1436 ret = WINMM_MAP_MSGERROR;
1437 break;
1438 case WODM_GETPOS:
1440 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1441 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1442 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1444 if (ptr) {
1445 *(LPMMTIME*)ptr = mmt32;
1446 mmt16->wType = mmt32->wType;
1447 ret = WINMM_MAP_OKMEM;
1448 } else {
1449 ret = WINMM_MAP_NOMEM;
1451 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1452 *lpParam2 = sizeof(MMTIME16);
1454 break;
1455 case WODM_GETVOLUME:
1456 FIXME("NIY: no conversion yet\n");
1457 ret = WINMM_MAP_MSGERROR;
1458 break;
1459 case WODM_OPEN:
1461 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1462 int sz = sizeof(WAVEFORMATEX);
1463 LPVOID ptr;
1464 LPWAVEOPENDESC16 wod16;
1466 /* allocated data are mapped as follows:
1467 LPWAVEOPENDESC ptr to orig lParam1
1468 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1469 DWORD dwUser passed to driver
1470 WAVEOPENDESC16 wod16: openDesc passed to driver
1471 WAVEFORMATEX openDesc->lpFormat passed to driver
1472 xxx extra bytes to WAVEFORMATEX
1474 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1475 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1476 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1479 ptr = HeapAlloc( GetProcessHeap(), 0,
1480 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1482 if (ptr) {
1483 SEGPTR seg_ptr = MapLS( ptr );
1484 *(LPWAVEOPENDESC*)ptr = wod32;
1485 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1486 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1488 wod16->hWave = HWAVE_16(wod32->hWave);
1489 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1490 memcpy(wod16 + 1, wod32->lpFormat, sz);
1492 wod16->dwCallback = wod32->dwCallback;
1493 wod16->dwInstance = wod32->dwInstance;
1494 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1495 wod16->dnDevNode = wod32->dnDevNode;
1497 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1498 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1500 ret = WINMM_MAP_OKMEM;
1501 } else {
1502 ret = WINMM_MAP_NOMEM;
1505 break;
1506 case WODM_PREPARE:
1508 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1509 LPWAVEHDR wh16;
1510 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1511 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1513 if (ptr) {
1514 SEGPTR seg_ptr = MapLS( ptr );
1515 *(LPWAVEHDR*)ptr = wh32;
1516 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1517 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1518 /* data will be copied on WODM_WRITE */
1519 wh16->dwBufferLength = wh32->dwBufferLength;
1520 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1521 wh16->dwUser = wh32->dwUser;
1522 wh16->dwFlags = wh32->dwFlags;
1523 wh16->dwLoops = wh32->dwLoops;
1524 /* FIXME: nothing on wh32->lpNext */
1525 /* could link the wh32->lpNext at this level for memory house keeping */
1526 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1527 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1528 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1529 wh32->dwBufferLength, (DWORD)wh32->lpData);
1530 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1531 *lpParam2 = sizeof(WAVEHDR);
1533 ret = WINMM_MAP_OKMEM;
1534 } else {
1535 ret = WINMM_MAP_NOMEM;
1538 break;
1539 case WODM_UNPREPARE:
1540 case WODM_WRITE:
1542 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1543 LPWAVEHDR wh16 = wh32->lpNext;
1544 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1545 SEGPTR seg_ptr = MapLS( ptr );
1547 assert(*(LPWAVEHDR*)ptr == wh32);
1549 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1550 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1551 wh32->dwBufferLength, (DWORD)wh32->lpData);
1553 if (wMsg == WODM_WRITE)
1554 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1556 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1557 *lpParam2 = sizeof(WAVEHDR);
1558 /* dwBufferLength can be reduced between prepare & write */
1559 if (wMsg == WODM_WRITE && wh16->dwBufferLength < wh32->dwBufferLength) {
1560 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1561 wh16->dwBufferLength, wh32->dwBufferLength);
1562 } else
1563 wh16->dwBufferLength = wh32->dwBufferLength;
1564 ret = WINMM_MAP_OKMEM;
1566 break;
1567 case DRVM_MAPPER_STATUS:
1569 LPDWORD p32 = (LPDWORD)*lpParam2;
1570 *lpParam2 = MapLS(p32);
1571 ret = WINMM_MAP_OKMEM;
1573 break;
1574 default:
1575 FIXME("NIY: no conversion yet\n");
1576 ret = WINMM_MAP_MSGERROR;
1577 break;
1579 return ret;
1582 /**************************************************************************
1583 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1585 static WINMM_MapType MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2, MMRESULT fn_ret)
1587 WINMM_MapType ret;
1589 switch (wMsg) {
1590 /* nothing to do */
1591 case WODM_BREAKLOOP:
1592 case WODM_CLOSE:
1593 case WODM_GETNUMDEVS:
1594 case WODM_PAUSE:
1595 case WODM_RESET:
1596 case WODM_RESTART:
1597 case WODM_SETPITCH:
1598 case WODM_SETPLAYBACKRATE:
1599 case WODM_SETVOLUME:
1600 ret = WINMM_MAP_OK;
1601 break;
1603 case WODM_GETDEVCAPS:
1605 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1606 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1607 LPWAVEOUTCAPSA woc32 = *(LPWAVEOUTCAPSA*)ptr;
1609 woc32->wMid = woc16->wMid;
1610 woc32->wPid = woc16->wPid;
1611 woc32->vDriverVersion = woc16->vDriverVersion;
1612 strcpy(woc32->szPname, woc16->szPname);
1613 woc32->dwFormats = woc16->dwFormats;
1614 woc32->wChannels = woc16->wChannels;
1615 woc32->dwSupport = woc16->dwSupport;
1616 UnMapLS( *lpParam1 );
1617 HeapFree( GetProcessHeap(), 0, ptr );
1618 ret = WINMM_MAP_OK;
1620 break;
1621 case WODM_GETPITCH:
1622 FIXME("NIY: no conversion yet\n");
1623 ret = WINMM_MAP_MSGERROR;
1624 break;
1625 case WODM_GETPLAYBACKRATE:
1626 FIXME("NIY: no conversion yet\n");
1627 ret = WINMM_MAP_MSGERROR;
1628 break;
1629 case WODM_GETPOS:
1631 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1632 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1633 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1635 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1636 UnMapLS( *lpParam1 );
1637 HeapFree( GetProcessHeap(), 0, ptr );
1638 ret = WINMM_MAP_OK;
1640 break;
1641 case WODM_OPEN:
1643 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1644 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1645 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1647 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1648 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1649 UnMapLS( *lpParam1 );
1650 HeapFree( GetProcessHeap(), 0, ptr );
1651 ret = WINMM_MAP_OK;
1653 break;
1654 case WODM_PREPARE:
1655 case WODM_UNPREPARE:
1656 case WODM_WRITE:
1658 LPWAVEHDR wh16 = MapSL(*lpParam1);
1659 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1660 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1662 assert(wh32->lpNext == wh16);
1663 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1664 wh32->dwUser = wh16->dwUser;
1665 wh32->dwFlags = wh16->dwFlags;
1666 wh32->dwLoops = wh16->dwLoops;
1668 UnMapLS( *lpParam1 );
1669 if (wMsg == WODM_UNPREPARE && fn_ret == MMSYSERR_NOERROR) {
1670 HeapFree( GetProcessHeap(), 0, ptr );
1671 wh32->lpNext = 0;
1673 ret = WINMM_MAP_OK;
1675 break;
1676 case WODM_GETVOLUME:
1677 FIXME("NIY: no conversion yet\n");
1678 ret = WINMM_MAP_MSGERROR;
1679 break;
1680 case DRVM_MAPPER_STATUS:
1682 UnMapLS( *lpParam2 );
1683 ret = WINMM_MAP_OK;
1685 break;
1686 default:
1687 FIXME("NIY: no conversion yet\n");
1688 ret = WINMM_MAP_MSGERROR;
1689 break;
1691 return ret;
1694 /**************************************************************************
1695 * MMDRV_WaveOut_Callback [internal]
1697 static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1699 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1701 switch (uMsg) {
1702 case WOM_OPEN:
1703 case WOM_CLOSE:
1704 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1705 break;
1706 case WOM_DONE:
1707 if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
1708 /* initial map is: 32 => 16 */
1709 LPWAVEHDR wh16 = MapSL(dwParam1);
1710 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1712 dwParam1 = (DWORD)wh32;
1713 wh32->dwFlags = wh16->dwFlags;
1714 } else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
1715 /* initial map is: 16 => 32 */
1716 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1717 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1718 LPWAVEHDR wh16 = MapSL(segwh16);
1720 dwParam1 = (DWORD)segwh16;
1721 wh16->dwFlags = wh32->dwFlags;
1723 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1724 break;
1725 default:
1726 ERR("Unknown msg %u\n", uMsg);
1729 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1732 /* =================================
1733 * M A P P E R S H A N D L I N G
1734 * ================================= */
1736 static LRESULT MMDRV_CallMMDrvFunc16(FARPROC16 fp16, WORD dev, WORD msg, LONG instance,
1737 LONG lp1, LONG lp2)
1739 WORD args[8];
1740 DWORD ret;
1742 args[7] = dev;
1743 args[6] = msg;
1744 args[5] = HIWORD(instance);
1745 args[4] = LOWORD(instance);
1746 args[3] = HIWORD(lp1);
1747 args[2] = LOWORD(lp1);
1748 args[1] = HIWORD(lp2);
1749 args[0] = LOWORD(lp2);
1750 WOWCallback16Ex( (DWORD)fp16, WCB16_PASCAL, sizeof(args), args, &ret );
1751 return LOWORD(ret);
1754 /**************************************************************************
1755 * MMDRV_GetDescription16 [internal]
1757 static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
1759 OFSTRUCT ofs;
1760 HFILE hFile;
1761 WORD w;
1762 DWORD dw;
1763 BOOL ret = FALSE;
1765 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
1766 ERR("Can't open file %s (builtin driver ?)\n", fname);
1767 return FALSE;
1770 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
1772 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
1773 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
1774 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
1775 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
1776 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
1777 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
1778 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %lu\n", dw));
1779 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
1780 buflen = min((int)(unsigned)(BYTE)buf[0], buflen - 1);
1781 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
1782 buf[buflen] = '\0';
1783 ret = TRUE;
1784 TRACE("Got '%s' [%d]\n", buf, buflen);
1785 theEnd:
1786 _lclose(hFile);
1787 return ret;
1790 /******************************************************************
1791 * MMDRV_LoadMMDrvFunc16
1794 unsigned MMDRV_LoadMMDrvFunc16(LPCSTR drvName, LPWINE_DRIVER d,
1795 LPWINE_MM_DRIVER lpDrv)
1797 WINEMM_msgFunc16 func;
1798 unsigned count = 0;
1799 char buffer[128];
1801 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
1802 * The beginning of the module description indicates the driver supports
1803 * waveform, auxiliary, and mixer devices. Use one of the following
1804 * device-type names, followed by a colon (:) to indicate the type of
1805 * device your driver supports. If the driver supports more than one
1806 * type of device, separate each device-type name with a comma (,).
1808 * wave for waveform audio devices
1809 * wavemapper for wave mappers
1810 * midi for MIDI audio devices
1811 * midimapper for midi mappers
1812 * aux for auxiliary audio devices
1813 * mixer for mixer devices
1816 if (d->d.d16.hDriver16) {
1817 HMODULE16 hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
1819 #define AA(_h,_w,_x,_y,_z) \
1820 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
1821 if (func != NULL) \
1822 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
1823 TRACE("Got %d bit func '%s'\n", _y, #_x); }
1825 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
1826 A(MMDRV_AUX, auxMessage);
1827 A(MMDRV_MIXER, mxdMessage);
1828 A(MMDRV_MIDIIN, midMessage);
1829 A(MMDRV_MIDIOUT,modMessage);
1830 A(MMDRV_WAVEIN, widMessage);
1831 A(MMDRV_WAVEOUT,wodMessage);
1832 #undef A
1833 #undef AA
1835 if (TRACE_ON(winmm)) {
1836 if (MMDRV_GetDescription16(drvName, buffer, sizeof(buffer)))
1837 TRACE("%s => %s\n", drvName, buffer);
1838 else
1839 TRACE("%s => No description\n", drvName);
1842 return count;
1845 /* =================================
1846 * M C I
1847 * ================================= */
1849 /**************************************************************************
1850 * MCI_MapMsg16To32A [internal]
1852 static WINMM_MapType MCI_MapMsg16To32A(WORD uDevType, WORD wMsg, DWORD* lParam)
1854 if (*lParam == 0)
1855 return WINMM_MAP_OK;
1856 /* FIXME: to add also (with seg/linear modifications to do):
1857 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
1858 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
1860 switch (wMsg) {
1861 /* case MCI_CAPTURE */
1862 case MCI_CLOSE:
1863 case MCI_CLOSE_DRIVER:
1864 case MCI_CONFIGURE:
1865 case MCI_COPY:
1866 case MCI_CUE:
1867 case MCI_CUT:
1868 case MCI_DELETE:
1869 case MCI_FREEZE:
1870 case MCI_GETDEVCAPS:
1871 /* case MCI_INDEX: */
1872 /* case MCI_MARK: */
1873 /* case MCI_MONITOR: */
1874 case MCI_PASTE:
1875 case MCI_PAUSE:
1876 case MCI_PLAY:
1877 case MCI_PUT:
1878 case MCI_REALIZE:
1879 case MCI_RECORD:
1880 case MCI_RESUME:
1881 case MCI_SEEK:
1882 case MCI_SET:
1883 /* case MCI_SETTIMECODE:*/
1884 /* case MCI_SIGNAL:*/
1885 case MCI_SPIN:
1886 case MCI_STATUS: /* FIXME: is wrong for digital video */
1887 case MCI_STEP:
1888 case MCI_STOP:
1889 /* case MCI_UNDO: */
1890 case MCI_UNFREEZE:
1891 case MCI_UPDATE:
1892 case MCI_WHERE:
1893 *lParam = (DWORD)MapSL(*lParam);
1894 return WINMM_MAP_OK;
1895 case MCI_WINDOW:
1896 /* in fact, I would also need the dwFlags... to see
1897 * which members of lParam are effectively used
1899 *lParam = (DWORD)MapSL(*lParam);
1900 FIXME("Current mapping may be wrong\n");
1901 break;
1902 case MCI_BREAK:
1904 LPMCI_BREAK_PARMS mbp32 = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_BREAK_PARMS));
1905 LPMCI_BREAK_PARMS16 mbp16 = MapSL(*lParam);
1907 if (mbp32) {
1908 mbp32->dwCallback = mbp16->dwCallback;
1909 mbp32->nVirtKey = mbp16->nVirtKey;
1910 mbp32->hwndBreak = HWND_32(mbp16->hwndBreak);
1911 } else {
1912 return WINMM_MAP_NOMEM;
1914 *lParam = (DWORD)mbp32;
1916 return WINMM_MAP_OKMEM;
1917 case MCI_ESCAPE:
1919 LPMCI_VD_ESCAPE_PARMSA mvep32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_VD_ESCAPE_PARMSA));
1920 LPMCI_VD_ESCAPE_PARMS16 mvep16 = MapSL(*lParam);
1922 if (mvep32a) {
1923 mvep32a->dwCallback = mvep16->dwCallback;
1924 mvep32a->lpstrCommand = MapSL(mvep16->lpstrCommand);
1925 } else {
1926 return WINMM_MAP_NOMEM;
1928 *lParam = (DWORD)mvep32a;
1930 return WINMM_MAP_OKMEM;
1931 case MCI_INFO:
1933 LPMCI_INFO_PARMSA mip32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_INFO_PARMSA));
1934 LPMCI_INFO_PARMS16 mip16 = MapSL(*lParam);
1936 /* FIXME this is wrong if device is of type
1937 * MCI_DEVTYPE_DIGITAL_VIDEO, some members are not mapped
1939 if (mip32a) {
1940 mip32a->dwCallback = mip16->dwCallback;
1941 mip32a->lpstrReturn = MapSL(mip16->lpstrReturn);
1942 mip32a->dwRetSize = mip16->dwRetSize;
1943 } else {
1944 return WINMM_MAP_NOMEM;
1946 *lParam = (DWORD)mip32a;
1948 return WINMM_MAP_OKMEM;
1949 case MCI_OPEN:
1950 case MCI_OPEN_DRIVER:
1952 LPMCI_OPEN_PARMSA mop32a = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_OPEN_PARMSA) + 2 * sizeof(DWORD));
1953 LPMCI_OPEN_PARMS16 mop16 = MapSL(*lParam);
1955 if (mop32a) {
1956 *(LPMCI_OPEN_PARMS16*)(mop32a) = mop16;
1957 mop32a = (LPMCI_OPEN_PARMSA)((char*)mop32a + sizeof(LPMCI_OPEN_PARMS16));
1958 mop32a->dwCallback = mop16->dwCallback;
1959 mop32a->wDeviceID = mop16->wDeviceID;
1960 mop32a->lpstrDeviceType = MapSL(mop16->lpstrDeviceType);
1961 mop32a->lpstrElementName = MapSL(mop16->lpstrElementName);
1962 mop32a->lpstrAlias = MapSL(mop16->lpstrAlias);
1963 /* copy extended information if any...
1964 * FIXME: this may seg fault if initial structure does not contain them and
1965 * the reads after msip16 fail under LDT limits...
1966 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
1967 * should not take care of extended parameters, and should be used by MCI_Open
1968 * to fetch uDevType. When, this is known, the mapping for sending the
1969 * MCI_OPEN_DRIVER shall be done depending on uDevType.
1971 memcpy(mop32a + 1, mop16 + 1, 2 * sizeof(DWORD));
1972 } else {
1973 return WINMM_MAP_NOMEM;
1975 *lParam = (DWORD)mop32a;
1977 return WINMM_MAP_OKMEM;
1978 case MCI_SYSINFO:
1980 LPMCI_SYSINFO_PARMSA msip32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_SYSINFO_PARMSA));
1981 LPMCI_SYSINFO_PARMS16 msip16 = MapSL(*lParam);
1983 if (msip32a) {
1984 msip32a->dwCallback = msip16->dwCallback;
1985 msip32a->lpstrReturn = MapSL(msip16->lpstrReturn);
1986 msip32a->dwRetSize = msip16->dwRetSize;
1987 msip32a->dwNumber = msip16->dwNumber;
1988 msip32a->wDeviceType = msip16->wDeviceType;
1989 } else {
1990 return WINMM_MAP_NOMEM;
1992 *lParam = (DWORD)msip32a;
1994 return WINMM_MAP_OKMEM;
1995 case DRV_LOAD:
1996 case DRV_ENABLE:
1997 case DRV_OPEN:
1998 case DRV_CLOSE:
1999 case DRV_DISABLE:
2000 case DRV_FREE:
2001 case DRV_CONFIGURE:
2002 case DRV_QUERYCONFIGURE:
2003 case DRV_INSTALL:
2004 case DRV_REMOVE:
2005 case DRV_EXITSESSION:
2006 case DRV_EXITAPPLICATION:
2007 case DRV_POWER:
2008 FIXME("This is a hack\n");
2009 return WINMM_MAP_OK;
2011 default:
2012 WARN("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2014 return WINMM_MAP_MSGERROR;
2017 /**************************************************************************
2018 * MCI_UnMapMsg16To32A [internal]
2020 static WINMM_MapType MCI_UnMapMsg16To32A(WORD uDevType, WORD wMsg, DWORD lParam)
2022 switch (wMsg) {
2023 /* case MCI_CAPTURE */
2024 case MCI_CLOSE:
2025 case MCI_CLOSE_DRIVER:
2026 case MCI_CONFIGURE:
2027 case MCI_COPY:
2028 case MCI_CUE:
2029 case MCI_CUT:
2030 case MCI_DELETE:
2031 case MCI_FREEZE:
2032 case MCI_GETDEVCAPS:
2033 /* case MCI_INDEX: */
2034 /* case MCI_MARK: */
2035 /* case MCI_MONITOR: */
2036 case MCI_PASTE:
2037 case MCI_PAUSE:
2038 case MCI_PLAY:
2039 case MCI_PUT:
2040 case MCI_REALIZE:
2041 case MCI_RECORD:
2042 case MCI_RESUME:
2043 case MCI_SEEK:
2044 case MCI_SET:
2045 /* case MCI_SETTIMECODE:*/
2046 /* case MCI_SIGNAL:*/
2047 case MCI_SPIN:
2048 case MCI_STATUS:
2049 case MCI_STEP:
2050 case MCI_STOP:
2051 /* case MCI_UNDO: */
2052 case MCI_UNFREEZE:
2053 case MCI_UPDATE:
2054 case MCI_WHERE:
2055 return WINMM_MAP_OK;
2057 case MCI_WINDOW:
2058 /* FIXME ?? see Map function */
2059 return WINMM_MAP_OK;
2061 case MCI_BREAK:
2062 case MCI_ESCAPE:
2063 case MCI_INFO:
2064 case MCI_SYSINFO:
2065 HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
2066 return WINMM_MAP_OK;
2067 case MCI_OPEN:
2068 case MCI_OPEN_DRIVER:
2069 if (lParam) {
2070 LPMCI_OPEN_PARMSA mop32a = (LPMCI_OPEN_PARMSA)lParam;
2071 LPMCI_OPEN_PARMS16 mop16 = *(LPMCI_OPEN_PARMS16*)((char*)mop32a - sizeof(LPMCI_OPEN_PARMS16));
2073 mop16->wDeviceID = mop32a->wDeviceID;
2074 if (!HeapFree(GetProcessHeap(), 0, (LPVOID)(lParam - sizeof(LPMCI_OPEN_PARMS16))))
2075 FIXME("bad free line=%d\n", __LINE__);
2077 return WINMM_MAP_OK;
2078 case DRV_LOAD:
2079 case DRV_ENABLE:
2080 case DRV_OPEN:
2081 case DRV_CLOSE:
2082 case DRV_DISABLE:
2083 case DRV_FREE:
2084 case DRV_CONFIGURE:
2085 case DRV_QUERYCONFIGURE:
2086 case DRV_INSTALL:
2087 case DRV_REMOVE:
2088 case DRV_EXITSESSION:
2089 case DRV_EXITAPPLICATION:
2090 case DRV_POWER:
2091 FIXME("This is a hack\n");
2092 return WINMM_MAP_OK;
2093 default:
2094 FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2096 return WINMM_MAP_MSGERROR;
2100 * 0000 stop
2101 * 0001 squeeze signed 4 bytes to 2 bytes *( LPINT16)D = ( INT16)*( LPINT16)S; D += 2; S += 4
2102 * 0010 squeeze unsigned 4 bytes to 2 bytes *(LPUINT16)D = (UINT16)*(LPUINT16)S; D += 2; S += 4
2103 * 0100
2104 * 0101
2105 * 0110 zero 4 bytes *(DWORD)D = 0 D += 4; S += 4
2106 * 0111 copy string *(LPSTR*)D = seg dup(*(LPSTR*)S) D += 4; S += 4
2107 * 1xxx copy xxx + 1 bytes memcpy(D, S, xxx + 1); D += xxx+1; S += xxx+1
2110 /**************************************************************************
2111 * MCI_MsgMapper32To16_Create [internal]
2113 * Helper for MCI_MapMsg32ATo16.
2114 * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit
2115 * segmented pointer.
2116 * map contains a list of action to be performed for the mapping (see list
2117 * above)
2118 * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area.
2120 static WINMM_MapType MCI_MsgMapper32To16_Create(void** ptr, int size16, DWORD map, BOOLEAN keep)
2122 void* lp = HeapAlloc( GetProcessHeap(), 0, (keep ? sizeof(void**) : 0) + size16 );
2123 LPBYTE p16, p32;
2125 if (!lp) {
2126 return WINMM_MAP_NOMEM;
2128 p32 = (LPBYTE)(*ptr);
2129 if (keep) {
2130 *(void**)lp = *ptr;
2131 p16 = (LPBYTE)lp + sizeof(void**);
2132 *ptr = (char*)MapLS(lp) + sizeof(void**);
2133 } else {
2134 p16 = lp;
2135 *ptr = (void*)MapLS(lp);
2138 if (map == 0) {
2139 memcpy(p16, p32, size16);
2140 } else {
2141 unsigned nibble;
2142 unsigned sz;
2144 while (map & 0xF) {
2145 nibble = map & 0xF;
2146 if (nibble & 0x8) {
2147 sz = (nibble & 7) + 1;
2148 memcpy(p16, p32, sz);
2149 p16 += sz;
2150 p32 += sz;
2151 size16 -= sz; /* DEBUG only */
2152 } else {
2153 switch (nibble) {
2154 case 0x1:
2155 *(LPINT16)p16 = *(LPINT)p32;
2156 p16 += sizeof(INT16);
2157 p32 += sizeof(INT);
2158 size16 -= sizeof(INT16);
2159 break;
2160 case 0x2:
2161 *(LPUINT16)p16 = *(LPUINT)p32;
2162 p16 += sizeof(UINT16);
2163 p32 += sizeof(UINT);
2164 size16 -= sizeof(UINT16);
2165 break;
2166 case 0x6:
2167 *(LPDWORD)p16 = 0;
2168 p16 += sizeof(DWORD);
2169 p32 += sizeof(DWORD);
2170 size16 -= sizeof(DWORD);
2171 break;
2172 case 0x7:
2173 *(SEGPTR *)p16 = MapLS( *(LPSTR *)p32 );
2174 p16 += sizeof(SEGPTR);
2175 p32 += sizeof(LPSTR);
2176 size16 -= sizeof(SEGPTR);
2177 break;
2178 default:
2179 FIXME("Unknown nibble for mapping (%x)\n", nibble);
2182 map >>= 4;
2184 if (size16 != 0) /* DEBUG only */
2185 FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2187 return WINMM_MAP_OKMEM;
2190 /**************************************************************************
2191 * MCI_MsgMapper32To16_Destroy [internal]
2193 * Helper for MCI_UnMapMsg32ATo16.
2195 static WINMM_MapType MCI_MsgMapper32To16_Destroy(void* ptr, int size16, DWORD map, BOOLEAN kept)
2197 if (ptr) {
2198 void* msg16 = MapSL((SEGPTR)ptr);
2199 void* alloc;
2200 LPBYTE p32, p16;
2201 unsigned nibble;
2203 UnMapLS( (SEGPTR)ptr );
2204 if (kept) {
2205 alloc = (char*)msg16 - sizeof(void**);
2206 p32 = *(void**)alloc;
2207 p16 = msg16;
2209 if (map == 0) {
2210 memcpy(p32, p16, size16);
2211 } else {
2212 while (map & 0xF) {
2213 nibble = map & 0xF;
2214 if (nibble & 0x8) {
2215 memcpy(p32, p16, (nibble & 7) + 1);
2216 p16 += (nibble & 7) + 1;
2217 p32 += (nibble & 7) + 1;
2218 size16 -= (nibble & 7) + 1;
2219 } else {
2220 switch (nibble) {
2221 case 0x1:
2222 *(LPINT)p32 = *(LPINT16)p16;
2223 p16 += sizeof(INT16);
2224 p32 += sizeof(INT);
2225 size16 -= sizeof(INT16);
2226 break;
2227 case 0x2:
2228 *(LPUINT)p32 = *(LPUINT16)p16;
2229 p16 += sizeof(UINT16);
2230 p32 += sizeof(UINT);
2231 size16 -= sizeof(UINT16);
2232 break;
2233 case 0x6:
2234 p16 += sizeof(UINT);
2235 p32 += sizeof(UINT);
2236 size16 -= sizeof(UINT);
2237 break;
2238 case 0x7:
2239 UnMapLS( *(SEGPTR *)p16 );
2240 p16 += sizeof(SEGPTR);
2241 p32 += sizeof(char*);
2242 size16 -= sizeof(SEGPTR);
2243 break;
2244 default:
2245 FIXME("Unknown nibble for mapping (%x)\n", nibble);
2248 map >>= 4;
2250 if (size16 != 0) /* DEBUG only */
2251 FIXME("Mismatch between 16 bit struct size and map nibbles serie\n");
2253 } else {
2254 alloc = msg16;
2257 HeapFree( GetProcessHeap(), 0, alloc );
2259 return WINMM_MAP_OK;
2262 /**************************************************************************
2263 * MCI_MapMsg32ATo16 [internal]
2265 * Map a 32-A bit MCI message to a 16 bit MCI message.
2267 static WINMM_MapType MCI_MapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD* lParam)
2269 int size;
2270 BOOLEAN keep = FALSE;
2271 DWORD map = 0;
2273 if (*lParam == 0)
2274 return WINMM_MAP_OK;
2276 /* FIXME: to add also (with seg/linear modifications to do):
2277 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
2278 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
2280 switch (wMsg) {
2281 case MCI_BREAK:
2282 size = sizeof(MCI_BREAK_PARMS);
2283 break;
2284 /* case MCI_CAPTURE */
2285 case MCI_CLOSE:
2286 case MCI_CLOSE_DRIVER:
2287 case MCI_CONFIGURE:
2288 size = sizeof(MCI_GENERIC_PARMS);
2289 break;
2290 /* case MCI_COPY: */
2291 case MCI_CUE:
2292 switch (uDevType) {
2293 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_CUE_PARMS); break;
2294 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_CUE_PARMS); break;*/ FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2295 default: size = sizeof(MCI_GENERIC_PARMS); break;
2297 break;
2298 /* case MCI_CUT:*/
2299 case MCI_DELETE:
2300 switch (uDevType) {
2301 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_DELETE_PARMS16); map = 0x0F1111FB; break;
2302 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_DELETE_PARMS); break;
2303 default: size = sizeof(MCI_GENERIC_PARMS); break;
2305 break;
2306 /* case MCI_ESCAPE: */
2307 case MCI_FREEZE:
2308 switch (uDevType) {
2309 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_FREEZE_PARMS); map = 0x0001111B; break;
2310 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break;
2311 default: size = sizeof(MCI_GENERIC_PARMS); break;
2313 break;
2314 case MCI_GETDEVCAPS:
2315 keep = TRUE;
2316 size = sizeof(MCI_GETDEVCAPS_PARMS);
2317 break;
2318 /* case MCI_INDEX: */
2319 case MCI_INFO:
2321 LPMCI_INFO_PARMSA mip32a = (LPMCI_INFO_PARMSA)(*lParam);
2322 LPMCI_INFO_PARMS16 mip16;
2324 switch (uDevType) {
2325 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_INFO_PARMS16); break;
2326 default: size = sizeof(MCI_INFO_PARMS16); break;
2328 mip16 = HeapAlloc( GetProcessHeap(), 0, size);
2329 if (mip16)
2331 mip16->dwCallback = mip32a->dwCallback;
2332 mip16->lpstrReturn = MapLS( mip32a->lpstrReturn );
2333 mip16->dwRetSize = mip32a->dwRetSize;
2334 if (uDevType == MCI_DEVTYPE_DIGITAL_VIDEO) {
2335 ((LPMCI_DGV_INFO_PARMS16)mip16)->dwItem = ((LPMCI_DGV_INFO_PARMSA)mip32a)->dwItem;
2337 } else {
2338 return WINMM_MAP_NOMEM;
2340 *lParam = MapLS(mip16);
2342 return WINMM_MAP_OKMEM;
2343 /* case MCI_MARK: */
2344 /* case MCI_MONITOR: */
2345 case MCI_OPEN:
2346 case MCI_OPEN_DRIVER:
2348 LPMCI_OPEN_PARMSA mop32a = (LPMCI_OPEN_PARMSA)(*lParam);
2349 char* ptr = HeapAlloc( GetProcessHeap(), 0,
2350 sizeof(LPMCI_OPEN_PARMSA) + sizeof(MCI_OPEN_PARMS16) + 2 * sizeof(DWORD));
2351 LPMCI_OPEN_PARMS16 mop16;
2354 if (ptr) {
2355 *(LPMCI_OPEN_PARMSA*)(ptr) = mop32a;
2356 mop16 = (LPMCI_OPEN_PARMS16)(ptr + sizeof(LPMCI_OPEN_PARMSA));
2357 mop16->dwCallback = mop32a->dwCallback;
2358 mop16->wDeviceID = mop32a->wDeviceID;
2359 if (dwFlags & MCI_OPEN_TYPE) {
2360 if (dwFlags & MCI_OPEN_TYPE_ID) {
2361 /* dword "transparent" value */
2362 mop16->lpstrDeviceType = (SEGPTR)mop32a->lpstrDeviceType;
2363 } else {
2364 /* string */
2365 mop16->lpstrDeviceType = MapLS( mop32a->lpstrDeviceType );
2367 } else {
2368 /* nuthin' */
2369 mop16->lpstrDeviceType = 0;
2371 if (dwFlags & MCI_OPEN_ELEMENT) {
2372 if (dwFlags & MCI_OPEN_ELEMENT_ID) {
2373 mop16->lpstrElementName = (SEGPTR)mop32a->lpstrElementName;
2374 } else {
2375 mop16->lpstrElementName = MapLS( mop32a->lpstrElementName );
2377 } else {
2378 mop16->lpstrElementName = 0;
2380 if (dwFlags & MCI_OPEN_ALIAS) {
2381 mop16->lpstrAlias = MapLS( mop32a->lpstrAlias );
2382 } else {
2383 mop16->lpstrAlias = 0;
2385 /* copy extended information if any...
2386 * FIXME: this may seg fault if initial structure does not contain them and
2387 * the reads after msip16 fail under LDT limits...
2388 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
2389 * should not take care of extended parameters, and should be used by MCI_Open
2390 * to fetch uDevType. When, this is known, the mapping for sending the
2391 * MCI_OPEN_DRIVER shall be done depending on uDevType.
2393 memcpy(mop16 + 1, mop32a + 1, 2 * sizeof(DWORD));
2394 } else {
2395 return WINMM_MAP_NOMEM;
2397 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_PARMSA);
2399 return WINMM_MAP_OKMEM;
2400 /* case MCI_PASTE:*/
2401 case MCI_PAUSE:
2402 size = sizeof(MCI_GENERIC_PARMS);
2403 break;
2404 case MCI_PLAY:
2405 size = sizeof(MCI_PLAY_PARMS);
2406 break;
2407 case MCI_PUT:
2408 switch (uDevType) {
2409 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break;
2410 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break;
2411 default: size = sizeof(MCI_GENERIC_PARMS); break;
2413 break;
2414 case MCI_REALIZE:
2415 size = sizeof(MCI_GENERIC_PARMS);
2416 break;
2417 case MCI_RECORD:
2418 switch (uDevType) {
2419 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECORD_PARMS16); map = 0x0F1111FB; break;
2420 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_RECORD_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2421 default: size = sizeof(MCI_RECORD_PARMS); break;
2423 break;
2424 case MCI_RESUME:
2425 size = sizeof(MCI_GENERIC_PARMS);
2426 break;
2427 case MCI_SEEK:
2428 switch (uDevType) {
2429 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SEEK_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2430 default: size = sizeof(MCI_SEEK_PARMS); break;
2432 break;
2433 case MCI_SET:
2434 switch (uDevType) {
2435 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SET_PARMS); break;
2436 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SET_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2437 case MCI_DEVTYPE_SEQUENCER: size = sizeof(MCI_SEQ_SET_PARMS); break;
2438 /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned,
2439 * so not doing anything should work...
2441 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_SET_PARMS); break;
2442 default: size = sizeof(MCI_SET_PARMS); break;
2444 break;
2445 case MCI_SETAUDIO:
2446 switch (uDevType) {
2447 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SETAUDIO_PARMS16);map = 0x0000077FF; break;
2448 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2449 default: size = sizeof(MCI_GENERIC_PARMS); break;
2451 break;
2452 /* case MCI_SETTIMECODE:*/
2453 /* case MCI_SIGNAL:*/
2454 case MCI_SPIN:
2455 size = sizeof(MCI_SET_PARMS);
2456 break;
2457 case MCI_STATUS:
2458 keep = TRUE;
2459 switch (uDevType) {
2460 /* FIXME:
2461 * don't know if buffer for value is the one passed through lpstrDevice
2462 * or is provided by MCI driver.
2463 * Assuming solution 2: provided by MCI driver, so zeroing on entry
2465 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16); map = 0x0B6FF; break;
2466 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2467 default: size = sizeof(MCI_STATUS_PARMS); break;
2469 break;
2470 case MCI_STEP:
2471 switch (uDevType) {
2472 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STEP_PARMS); break;
2473 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STEP_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2474 case MCI_DEVTYPE_VIDEODISC: size = sizeof(MCI_VD_STEP_PARMS); break;
2475 default: size = sizeof(MCI_GENERIC_PARMS); break;
2477 break;
2478 case MCI_STOP:
2479 size = sizeof(MCI_SET_PARMS);
2480 break;
2481 case MCI_SYSINFO:
2483 LPMCI_SYSINFO_PARMSA msip32a = (LPMCI_SYSINFO_PARMSA)(*lParam);
2484 LPMCI_SYSINFO_PARMS16 msip16;
2485 char* ptr = HeapAlloc( GetProcessHeap(), 0,
2486 sizeof(LPMCI_SYSINFO_PARMSA) + sizeof(MCI_SYSINFO_PARMS16) );
2488 if (ptr) {
2489 *(LPMCI_SYSINFO_PARMSA*)(ptr) = msip32a;
2490 msip16 = (LPMCI_SYSINFO_PARMS16)(ptr + sizeof(LPMCI_SYSINFO_PARMSA));
2492 msip16->dwCallback = msip32a->dwCallback;
2493 msip16->lpstrReturn = MapLS( msip32a->lpstrReturn );
2494 msip16->dwRetSize = msip32a->dwRetSize;
2495 msip16->dwNumber = msip32a->dwNumber;
2496 msip16->wDeviceType = msip32a->wDeviceType;
2497 } else {
2498 return WINMM_MAP_NOMEM;
2500 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_SYSINFO_PARMSA);
2502 return WINMM_MAP_OKMEM;
2503 /* case MCI_UNDO: */
2504 case MCI_UNFREEZE:
2505 switch (uDevType) {
2506 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break;
2507 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; break;
2508 default: size = sizeof(MCI_GENERIC_PARMS); break;
2510 break;
2511 case MCI_UPDATE:
2512 switch (uDevType) {
2513 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_UPDATE_PARMS16); map = 0x000B1111B; break;
2514 default: size = sizeof(MCI_GENERIC_PARMS); break;
2516 break;
2517 case MCI_WHERE:
2518 switch (uDevType) {
2519 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break;
2520 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break;
2521 default: size = sizeof(MCI_GENERIC_PARMS); break;
2523 break;
2524 case MCI_WINDOW:
2525 switch (uDevType) {
2526 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7FB; break;
2527 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7FB; break;
2528 default: size = sizeof(MCI_GENERIC_PARMS); break;
2530 break;
2531 case DRV_OPEN:
2533 LPMCI_OPEN_DRIVER_PARMSA modp32a = (LPMCI_OPEN_DRIVER_PARMSA)(*lParam);
2534 LPMCI_OPEN_DRIVER_PARMS16 modp16;
2535 char *ptr = HeapAlloc( GetProcessHeap(), 0,
2536 sizeof(LPMCI_OPEN_DRIVER_PARMSA) + sizeof(MCI_OPEN_DRIVER_PARMS16));
2538 if (ptr) {
2539 *(LPMCI_OPEN_DRIVER_PARMSA*)(ptr) = modp32a;
2540 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSA));
2541 modp16->wDeviceID = modp32a->wDeviceID;
2542 modp16->lpstrParams = MapLS( modp32a->lpstrParams );
2543 /* other fields are gonna be filled by the driver, don't copy them */
2544 } else {
2545 return WINMM_MAP_NOMEM;
2547 *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_DRIVER_PARMSA);
2549 return WINMM_MAP_OKMEM;
2550 case DRV_LOAD:
2551 case DRV_ENABLE:
2552 case DRV_CLOSE:
2553 case DRV_DISABLE:
2554 case DRV_FREE:
2555 case DRV_CONFIGURE:
2556 case DRV_QUERYCONFIGURE:
2557 case DRV_INSTALL:
2558 case DRV_REMOVE:
2559 case DRV_EXITSESSION:
2560 case DRV_EXITAPPLICATION:
2561 case DRV_POWER:
2562 return WINMM_MAP_OK;
2564 default:
2565 WARN("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
2566 return WINMM_MAP_MSGERROR;
2568 return MCI_MsgMapper32To16_Create((void**)lParam, size, map, keep);
2571 /**************************************************************************
2572 * MCI_UnMapMsg32ATo16 [internal]
2574 static WINMM_MapType MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD lParam)
2576 int size = 0;
2577 BOOLEAN kept = FALSE; /* there is no need to compute size when kept is FALSE */
2578 DWORD map = 0;
2580 switch (wMsg) {
2581 case MCI_BREAK:
2582 break;
2583 /* case MCI_CAPTURE */
2584 case MCI_CLOSE:
2585 case MCI_CLOSE_DRIVER:
2586 case MCI_CONFIGURE:
2587 break;
2588 /* case MCI_COPY: */
2589 case MCI_CUE:
2590 break;
2591 /* case MCI_CUT: */
2592 case MCI_DELETE:
2593 break;
2594 /* case MCI_ESCAPE: */
2595 case MCI_FREEZE:
2596 break;
2597 case MCI_GETDEVCAPS:
2598 kept = TRUE;
2599 size = sizeof(MCI_GETDEVCAPS_PARMS);
2600 break;
2601 /* case MCI_INDEX: */
2602 case MCI_INFO:
2604 LPMCI_INFO_PARMS16 mip16 = (LPMCI_INFO_PARMS16)MapSL(lParam);
2605 UnMapLS( lParam );
2606 UnMapLS( mip16->lpstrReturn );
2607 HeapFree( GetProcessHeap(), 0, mip16 );
2609 return WINMM_MAP_OK;
2610 /* case MCI_MARK: */
2611 /* case MCI_MONITOR: */
2612 case MCI_OPEN:
2613 case MCI_OPEN_DRIVER:
2614 if (lParam) {
2615 LPMCI_OPEN_PARMS16 mop16 = (LPMCI_OPEN_PARMS16)MapSL(lParam);
2616 LPMCI_OPEN_PARMSA mop32a = *(LPMCI_OPEN_PARMSA*)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSA));
2617 UnMapLS( lParam );
2618 mop32a->wDeviceID = mop16->wDeviceID;
2619 if ((dwFlags & MCI_OPEN_TYPE) && !(dwFlags & MCI_OPEN_TYPE_ID))
2620 UnMapLS( mop16->lpstrDeviceType );
2621 if ((dwFlags & MCI_OPEN_ELEMENT) && !(dwFlags & MCI_OPEN_ELEMENT_ID))
2622 UnMapLS( mop16->lpstrElementName );
2623 if (dwFlags & MCI_OPEN_ALIAS)
2624 UnMapLS( mop16->lpstrAlias );
2625 HeapFree( GetProcessHeap(), 0, (char*)mop16 - sizeof(LPMCI_OPEN_PARMSA) );
2627 return WINMM_MAP_OK;
2628 /* case MCI_PASTE:*/
2629 case MCI_PAUSE:
2630 break;
2631 case MCI_PLAY:
2632 break;
2633 case MCI_PUT:
2634 break;
2635 case MCI_REALIZE:
2636 break;
2637 case MCI_RECORD:
2638 break;
2639 case MCI_RESUME:
2640 break;
2641 case MCI_SEEK:
2642 break;
2643 case MCI_SET:
2644 break;
2645 case MCI_SETAUDIO:
2646 switch (uDevType) {
2647 case MCI_DEVTYPE_DIGITAL_VIDEO: map = 0x0000077FF; break;
2648 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2650 break;
2651 /* case MCI_SETTIMECODE:*/
2652 /* case MCI_SIGNAL:*/
2653 case MCI_SPIN:
2654 break;
2655 case MCI_STATUS:
2656 kept = TRUE;
2657 switch (uDevType) {
2658 case MCI_DEVTYPE_DIGITAL_VIDEO:
2659 if (lParam) {
2660 LPMCI_DGV_STATUS_PARMS16 mdsp16 = (LPMCI_DGV_STATUS_PARMS16)MapSL(lParam);
2661 LPMCI_DGV_STATUS_PARMSA mdsp32a = *(LPMCI_DGV_STATUS_PARMSA*)((char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA));
2663 UnMapLS( lParam );
2664 if (mdsp16) {
2665 mdsp32a->dwReturn = mdsp16->dwReturn;
2666 if (dwFlags & MCI_DGV_STATUS_DISKSPACE) {
2667 TRACE("MCI_STATUS (DGV) lpstrDrive=%08lx\n", mdsp16->lpstrDrive);
2668 TRACE("MCI_STATUS (DGV) lpstrDrive=%s\n", (LPSTR)MapSL(mdsp16->lpstrDrive));
2669 UnMapLS( mdsp16->lpstrDrive );
2671 HeapFree( GetProcessHeap(), 0, (char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA) );
2672 } else {
2673 return WINMM_MAP_NOMEM;
2676 return WINMM_MAP_OKMEM;
2677 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM;
2678 default: size = sizeof(MCI_STATUS_PARMS); break;
2680 break;
2681 case MCI_STEP:
2682 break;
2683 case MCI_STOP:
2684 break;
2685 case MCI_SYSINFO:
2686 if (lParam) {
2687 LPMCI_SYSINFO_PARMS16 msip16 = (LPMCI_SYSINFO_PARMS16)MapSL(lParam);
2688 LPMCI_SYSINFO_PARMSA msip32a = *(LPMCI_SYSINFO_PARMSA*)((char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA));
2690 UnMapLS( lParam );
2691 if (msip16) {
2692 msip16->dwCallback = msip32a->dwCallback;
2693 UnMapLS( msip16->lpstrReturn );
2694 HeapFree( GetProcessHeap(), 0, (char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA) );
2695 } else {
2696 return WINMM_MAP_NOMEM;
2699 return WINMM_MAP_OKMEM;
2700 /* case MCI_UNDO: */
2701 case MCI_UNFREEZE:
2702 break;
2703 case MCI_UPDATE:
2704 break;
2705 case MCI_WHERE:
2706 switch (uDevType) {
2707 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break;
2708 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break;
2709 default: break;
2711 break;
2712 case MCI_WINDOW:
2713 switch (uDevType) {
2714 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7666; break;
2715 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7666; break;
2716 default: break;
2718 /* FIXME: see map function */
2719 break;
2721 case DRV_OPEN:
2722 if (lParam) {
2723 LPMCI_OPEN_DRIVER_PARMS16 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)MapSL(lParam);
2724 LPMCI_OPEN_DRIVER_PARMSA modp32a = *(LPMCI_OPEN_DRIVER_PARMSA*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA));
2726 UnMapLS( lParam );
2727 modp32a->wCustomCommandTable = modp16->wCustomCommandTable;
2728 modp32a->wType = modp16->wType;
2729 UnMapLS( modp16->lpstrParams );
2730 HeapFree( GetProcessHeap(), 0, (char *)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA) );
2732 return WINMM_MAP_OK;
2733 case DRV_LOAD:
2734 case DRV_ENABLE:
2735 case DRV_CLOSE:
2736 case DRV_DISABLE:
2737 case DRV_FREE:
2738 case DRV_CONFIGURE:
2739 case DRV_QUERYCONFIGURE:
2740 case DRV_INSTALL:
2741 case DRV_REMOVE:
2742 case DRV_EXITSESSION:
2743 case DRV_EXITAPPLICATION:
2744 case DRV_POWER:
2745 FIXME("This is a hack\n");
2746 return WINMM_MAP_OK;
2747 default:
2748 FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
2749 return WINMM_MAP_MSGERROR;
2751 return MCI_MsgMapper32To16_Destroy((void*)lParam, size, map, kept);
2754 void MMDRV_Init16(void)
2756 #define A(_x,_y) MMDRV_InstallMap(_x, \
2757 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
2758 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
2759 MMDRV_##_y##_Callback)
2760 A(MMDRV_AUX, Aux);
2761 A(MMDRV_MIXER, Mixer);
2762 A(MMDRV_MIDIIN, MidiIn);
2763 A(MMDRV_MIDIOUT, MidiOut);
2764 A(MMDRV_WAVEIN, WaveIn);
2765 A(MMDRV_WAVEOUT, WaveOut);
2766 #undef A
2768 pFnCallMMDrvFunc16 = MMDRV_CallMMDrvFunc16;
2769 pFnLoadMMDrvFunc16 = MMDRV_LoadMMDrvFunc16;
2771 pFnMciMapMsg16To32A = MCI_MapMsg16To32A;
2772 pFnMciUnMapMsg16To32A = MCI_UnMapMsg16To32A;
2773 pFnMciMapMsg32ATo16 = MCI_MapMsg32ATo16;
2774 pFnMciUnMapMsg32ATo16 = MCI_UnMapMsg32ATo16;