1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * MMSYTEM low level drivers handling 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
26 #include "wine/winbase16.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
34 typedef DWORD (CALLBACK *WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
35 typedef DWORD (CALLBACK *WINEMM_msgFunc32)(UINT , UINT, DWORD, DWORD, DWORD);
37 /* for each loaded driver and each known type of driver, this structure contains
38 * the information needed to access it
40 typedef struct tagWINE_MM_DRIVER_PART {
41 int nIDMin; /* lower bound of global indexes for this type */
42 int nIDMax; /* hhigher bound of global indexes for this type */
44 WINEMM_msgFunc32 fnMessage32; /* pointer to fonction */
45 WINEMM_msgFunc16 fnMessage16;
47 } WINE_MM_DRIVER_PART;
49 /* each low-level .drv will be associated with an instance of this structure */
50 typedef struct tagWINE_MM_DRIVER {
52 LPSTR drvname; /* name of the driver */
53 BOOL bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */
54 bIsMapper : 1; /* TRUE if mapper */
55 WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */
56 } WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
59 MMDRV_MAP_NOMEM, /* ko, memory problem */
60 MMDRV_MAP_MSGERROR, /* ko, unknown message */
61 MMDRV_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
62 MMDRV_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
63 MMDRV_MAP_PASS /* not handled (no memory allocated) to be sent to the driver */
66 typedef MMDRV_MapType (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
68 /* each known type of driver has an instance of this structure */
69 typedef struct tagWINE_LLTYPE {
70 /* those attributes depend on the specification of the type */
71 LPSTR typestr; /* name (for debugging) */
72 BOOL bSupportMapper; /* if type is allowed to support mapper */
73 MMDRV_MAPFUNC Map16To32A; /* those are function pointers to handle */
74 MMDRV_MAPFUNC UnMap16To32A; /* the parameter conversion (16 vs 32 bit) */
75 MMDRV_MAPFUNC Map32ATo16; /* when hi-func (in mmsystem or winmm) and */
76 MMDRV_MAPFUNC UnMap32ATo16; /* low-func (in .drv) do not match */
77 LPDRVCALLBACK Callback; /* handles callback for a specified type */
78 /* those attributes reflect the loaded/current situation for the type */
79 UINT wMaxId; /* number of loaded devices (sum across all loaded drivers */
80 LPWINE_MLD lpMlds; /* "static" mlds to access the part though device IDs */
81 int nMapper; /* index to mapper */
84 static int MMDrvsHi /* = 0 */;
85 static WINE_MM_DRIVER MMDrvs[3];
86 static LPWINE_MLD MM_MLDrvs[40];
87 #define MAX_MM_MLDRVS (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
89 /* ### start build ### */
90 extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
91 /* ### stop build ### */
93 /**************************************************************************
94 * MMDRV_GetDescription16 [internal]
96 static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
104 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
105 ERR("Can't open file %s (builtin driver ?)\n", fname);
109 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
111 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
112 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
113 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
114 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
115 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
116 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
117 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %lu\n", dw));
118 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
119 buflen = min((BYTE)buf[0], buflen - 1);
120 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
123 TRACE("Got '%s' [%d]\n", buf, buflen);
129 /**************************************************************************
130 * MMDRV_GetDescription32 [internal]
132 static BOOL MMDRV_GetDescription32(const char* fname, char* buf, int buflen)
141 FARPROC pGetFileVersionInfoSizeA;
142 FARPROC pGetFileVersionInfoA;
143 FARPROC pVerQueryValueA;
146 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
148 if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR) E(("Can't find file %s\n", fname));
150 if (!(hmodule = LoadLibraryA( "version.dll" ))) goto theEnd;
151 if (!(pGetFileVersionInfoSizeA = GetProcAddress( hmodule, "GetFileVersionInfoSizeA" )))
153 if (!(pGetFileVersionInfoA = GetProcAddress( hmodule, "GetFileVersionInfoA" )))
155 if (!(pVerQueryValueA = GetProcAddress( hmodule, "pVerQueryValueA" )))
158 if (!(dw = pGetFileVersionInfoSizeA(ofs.szPathName, &h))) E(("Can't get FVIS\n"));
159 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw))) E(("OOM\n"));
160 if (!pGetFileVersionInfoA(ofs.szPathName, h, dw, ptr)) E(("Can't get FVI\n"));
162 #define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
163 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
179 if (!pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
180 lstrcpynA(buf, val, buflen);
185 HeapFree(GetProcessHeap(), 0, ptr);
186 if (hmodule) FreeLibrary( hmodule );
190 /**************************************************************************
191 * MMDRV_Callback [internal]
193 static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
195 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
196 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
198 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
199 /* 16 bit func, call it */
200 TRACE("Function (16 bit) !\n");
201 MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, hDev, uMsg,
202 mld->dwClientInstance, dwParam1, dwParam2);
204 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
205 mld->dwClientInstance, dwParam1, dwParam2);
209 /* =================================
210 * A U X M A P P E R S
211 * ================================= */
213 /**************************************************************************
214 * MMDRV_Aux_Map16To32A [internal]
216 static MMDRV_MapType MMDRV_Aux_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
218 return MMDRV_MAP_MSGERROR;
221 /**************************************************************************
222 * MMDRV_Aux_UnMap16To32A [internal]
224 static MMDRV_MapType MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
226 return MMDRV_MAP_MSGERROR;
229 /**************************************************************************
230 * MMDRV_Aux_Map32ATo16 [internal]
232 static MMDRV_MapType MMDRV_Aux_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
234 return MMDRV_MAP_MSGERROR;
237 /**************************************************************************
238 * MMDRV_Aux_UnMap32ATo16 [internal]
240 static MMDRV_MapType MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
243 case AUXDM_GETDEVCAPS:
244 lpCaps->wMid = ac16.wMid;
245 lpCaps->wPid = ac16.wPid;
246 lpCaps->vDriverVersion = ac16.vDriverVersion;
247 strcpy(lpCaps->szPname, ac16.szPname);
248 lpCaps->wTechnology = ac16.wTechnology;
249 lpCaps->dwSupport = ac16.dwSupport;
251 return MMDRV_MAP_MSGERROR;
254 /**************************************************************************
255 * MMDRV_Aux_Callback [internal]
257 static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
259 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
262 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
265 /* =================================
266 * M I X E R M A P P E R S
267 * ================================= */
269 /**************************************************************************
270 * xMMDRV_Mixer_Map16To32A [internal]
272 static MMDRV_MapType MMDRV_Mixer_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
274 return MMDRV_MAP_MSGERROR;
277 /**************************************************************************
278 * MMDRV_Mixer_UnMap16To32A [internal]
280 static MMDRV_MapType MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
284 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
286 if (ret == MMSYSERR_NOERROR) {
287 mixcaps->wMid = micA.wMid;
288 mixcaps->wPid = micA.wPid;
289 mixcaps->vDriverVersion = micA.vDriverVersion;
290 strcpy(mixcaps->szPname, micA.szPname);
291 mixcaps->fdwSupport = micA.fdwSupport;
292 mixcaps->cDestinations = micA.cDestinations;
296 return MMDRV_MAP_MSGERROR;
299 /**************************************************************************
300 * MMDRV_Mixer_Map32ATo16 [internal]
302 static MMDRV_MapType MMDRV_Mixer_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
304 return MMDRV_MAP_MSGERROR;
307 /**************************************************************************
308 * MMDRV_Mixer_UnMap32ATo16 [internal]
310 static MMDRV_MapType MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
312 return MMDRV_MAP_MSGERROR;
315 /**************************************************************************
316 * MMDRV_Mixer_Callback [internal]
318 static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
320 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
323 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
326 /* =================================
327 * M I D I I N M A P P E R S
328 * ================================= */
330 /**************************************************************************
331 * MMDRV_MidiIn_Map16To32A [internal]
333 static MMDRV_MapType MMDRV_MidiIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
335 return MMDRV_MAP_MSGERROR;
338 /**************************************************************************
339 * MMDRV_MidiIn_UnMap16To32A [internal]
341 static MMDRV_MapType MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
343 return MMDRV_MAP_MSGERROR;
346 /**************************************************************************
347 * MMDRV_MidiIn_Map32ATo16 [internal]
349 static MMDRV_MapType MMDRV_MidiIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
351 return MMDRV_MAP_MSGERROR;
354 /**************************************************************************
355 * MMDRV_MidiIn_UnMap32ATo16 [internal]
357 static MMDRV_MapType MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
359 return MMDRV_MAP_MSGERROR;
362 /**************************************************************************
363 * MMDRV_MidiIn_Callback [internal]
365 static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
367 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
372 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
377 /* dwParam1 & dwParam2 are are data, nothing to do */
381 /* dwParam1 points to a MidiHdr, work to be done !!! */
382 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
383 /* initial map is: 32 => 16 */
384 LPMIDIHDR mh16 = MapSL(dwParam1);
385 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
387 dwParam1 = (DWORD)mh32;
388 mh32->dwFlags = mh16->dwFlags;
389 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
390 if (mh32->reserved >= sizeof(MIDIHDR))
391 mh32->dwOffset = mh16->dwOffset;
392 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
393 /* initial map is: 16 => 32 */
394 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
395 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
396 LPMIDIHDR mh16 = MapSL(segmh16);
398 dwParam1 = (DWORD)segmh16;
399 mh16->dwFlags = mh32->dwFlags;
400 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
401 if (mh16->reserved >= sizeof(MIDIHDR))
402 mh16->dwOffset = mh32->dwOffset;
404 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
406 /* case MOM_POSITIONCB: */
408 ERR("Unknown msg %u\n", uMsg);
411 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
414 /* =================================
415 * M I D I O U T M A P P E R S
416 * ================================= */
418 /**************************************************************************
419 * MMDRV_MidiOut_Map16To32A [internal]
421 static MMDRV_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
423 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
426 case MODM_GETNUMDEVS:
436 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
439 case MODM_GETDEVCAPS:
441 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
442 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
445 *(LPMIDIOUTCAPS16*)moc32 = moc16;
446 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
447 *lpParam1 = (DWORD)moc32;
448 *lpParam2 = sizeof(MIDIOUTCAPSA);
450 ret = MMDRV_MAP_OKMEM;
452 ret = MMDRV_MAP_NOMEM;
458 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
459 LPMIDIHDR mh16 = MapSL(*lpParam1);
462 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
463 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
464 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
465 mh32->dwBufferLength = mh16->dwBufferLength;
466 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
467 mh32->dwUser = mh16->dwUser;
468 mh32->dwFlags = mh16->dwFlags;
469 /* FIXME: nothing on mh32->lpNext */
470 /* could link the mh32->lpNext at this level for memory house keeping */
471 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
472 mh16->lpNext = mh32; /* for reuse in unprepare and write */
473 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
474 mh16->reserved = *lpParam2;
475 *lpParam1 = (DWORD)mh32;
476 *lpParam2 = sizeof(MIDIHDR);
478 ret = MMDRV_MAP_OKMEM;
480 ret = MMDRV_MAP_NOMEM;
487 LPMIDIHDR mh16 = MapSL(*lpParam1);
488 LPMIDIHDR mh32 = (LPMIDIHDR)mh16->lpNext;
490 *lpParam1 = (DWORD)mh32;
491 *lpParam2 = sizeof(MIDIHDR);
492 /* dwBufferLength can be reduced between prepare & write */
493 if (mh32->dwBufferLength < mh16->dwBufferLength) {
494 ERR("Size of buffer has been increased (%ld, %ld)\n",
495 mh32->dwBufferLength, mh16->dwBufferLength);
496 return MMDRV_MAP_MSGERROR;
498 mh32->dwBufferLength = mh16->dwBufferLength;
499 ret = MMDRV_MAP_OKMEM;
503 case MODM_CACHEPATCHES:
504 case MODM_CACHEDRUMPATCHES:
506 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
512 /**************************************************************************
513 * MMDRV_MidiOut_UnMap16To32A [internal]
515 static MMDRV_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
517 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
520 case MODM_GETNUMDEVS:
530 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
533 case MODM_GETDEVCAPS:
535 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
536 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
538 moc16->wMid = moc32->wMid;
539 moc16->wPid = moc32->wPid;
540 moc16->vDriverVersion = moc32->vDriverVersion;
541 strcpy(moc16->szPname, moc32->szPname);
542 moc16->wTechnology = moc32->wTechnology;
543 moc16->wVoices = moc32->wVoices;
544 moc16->wNotes = moc32->wNotes;
545 moc16->wChannelMask = moc32->wChannelMask;
546 moc16->dwSupport = moc32->dwSupport;
547 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
555 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
556 LPMIDIHDR mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
558 assert(mh16->lpNext == mh32);
559 mh16->dwBufferLength = mh32->dwBufferLength;
560 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
561 mh16->dwUser = mh32->dwUser;
562 mh16->dwFlags = mh32->dwFlags;
563 if (mh16->reserved >= sizeof(MIDIHDR))
564 mh16->dwOffset = mh32->dwOffset;
566 if (wMsg == MODM_UNPREPARE) {
567 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
574 case MODM_CACHEPATCHES:
575 case MODM_CACHEDRUMPATCHES:
577 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
583 /**************************************************************************
584 * MMDRV_MidiOut_Map32ATo16 [internal]
586 static MMDRV_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
588 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
592 case MODM_GETNUMDEVS:
598 case MODM_GETDEVCAPS:
600 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
601 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA)+sizeof(MIDIOUTCAPS16));
604 *(LPMIDIOUTCAPSA*)ptr = moc32;
605 ret = MMDRV_MAP_OKMEM;
607 ret = MMDRV_MAP_NOMEM;
609 *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSA);
610 *lpParam2 = sizeof(MIDIOUTCAPS16);
615 LPMIDIHDR mh32 = (LPMIDIHDR)*lpParam1;
617 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
618 sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
621 *(LPMIDIHDR*)ptr = mh32;
622 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
623 *lpParam1 = MapLS(mh16);
624 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
625 /* data will be copied on WODM_WRITE */
626 mh16->dwBufferLength = mh32->dwBufferLength;
627 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
628 mh16->dwUser = mh32->dwUser;
629 mh16->dwFlags = mh32->dwFlags;
630 /* FIXME: nothing on mh32->lpNext */
631 /* could link the mh32->lpNext at this level for memory house keeping */
632 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
634 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
635 mh32->reserved = *lpParam2;
637 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
638 *lpParam1, (DWORD)mh16->lpData,
639 mh32->dwBufferLength, (DWORD)mh32->lpData);
640 *lpParam2 = sizeof(MIDIHDR);
642 ret = MMDRV_MAP_OKMEM;
644 ret = MMDRV_MAP_NOMEM;
651 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
652 LPMIDIHDR mh16 = (LPMIDIHDR)mh32->lpNext;
653 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
655 assert(*(LPMIDIHDR*)ptr == mh32);
657 if (wMsg == MODM_LONGDATA)
658 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
660 *lpParam1 = MapLS(mh16);
661 *lpParam2 = sizeof(MIDIHDR);
662 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
663 *lpParam1, (DWORD)mh16->lpData, mh32->dwBufferLength, (DWORD)mh32->lpData);
665 /* dwBufferLength can be reduced between prepare & write */
666 if (mh16->dwBufferLength < mh32->dwBufferLength) {
667 ERR("Size of buffer has been increased (%ld, %ld)\n",
668 mh16->dwBufferLength, mh32->dwBufferLength);
669 return MMDRV_MAP_MSGERROR;
671 mh16->dwBufferLength = mh32->dwBufferLength;
672 ret = MMDRV_MAP_OKMEM;
677 LPMIDIOPENDESC mod32 = (LPMIDIOPENDESC)*lpParam1;
679 LPMIDIOPENDESC16 mod16;
681 /* allocated data are mapped as follows:
682 LPMIDIOPENDESC ptr to orig lParam1
683 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
684 DWORD dwUser passed to driver
685 MIDIOPENDESC16 mod16: openDesc passed to driver
688 ptr = HeapAlloc( GetProcessHeap(), 0,
689 sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
690 mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
693 SEGPTR segptr = MapLS(ptr);
694 *(LPMIDIOPENDESC*)ptr = mod32;
695 *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
696 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
698 mod16->hMidi = mod32->hMidi;
699 mod16->dwCallback = mod32->dwCallback;
700 mod16->dwInstance = mod32->dwInstance;
701 mod16->dnDevNode = mod32->dnDevNode;
702 mod16->cIds = mod32->cIds;
703 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
705 *lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
706 *lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
708 ret = MMDRV_MAP_OKMEM;
710 ret = MMDRV_MAP_NOMEM;
715 case MODM_CACHEPATCHES:
716 case MODM_CACHEDRUMPATCHES:
718 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
724 /**************************************************************************
725 * MMDRV_MidiOut_UnMap32ATo16 [internal]
727 static MMDRV_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
729 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
733 case MODM_GETNUMDEVS:
739 case MODM_GETDEVCAPS:
741 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
742 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
743 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
745 moc32->wMid = moc16->wMid;
746 moc32->wPid = moc16->wPid;
747 moc32->vDriverVersion = moc16->vDriverVersion;
748 strcpy(moc32->szPname, moc16->szPname);
749 moc32->wTechnology = moc16->wTechnology;
750 moc32->wVoices = moc16->wVoices;
751 moc32->wNotes = moc16->wNotes;
752 moc32->wChannelMask = moc16->wChannelMask;
753 moc32->dwSupport = moc16->dwSupport;
754 UnMapLS( *lpParam1 );
755 HeapFree( GetProcessHeap(), 0, ptr );
763 LPMIDIHDR mh16 = MapSL(*lpParam1);
764 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
765 LPMIDIHDR mh32 = *(LPMIDIHDR*)ptr;
767 assert(mh32->lpNext == (LPMIDIHDR)mh16);
768 UnMapLS( *lpParam1 );
769 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
770 mh32->dwUser = mh16->dwUser;
771 mh32->dwFlags = mh16->dwFlags;
773 if (wMsg == MODM_UNPREPARE) {
774 HeapFree( GetProcessHeap(), 0, ptr );
782 LPMIDIOPENDESC16 mod16 = MapSL(*lpParam1);
783 LPSTR ptr = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
784 UnMapLS( *lpParam1 );
785 **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
787 HeapFree( GetProcessHeap(), 0, ptr );
792 case MODM_CACHEPATCHES:
793 case MODM_CACHEDRUMPATCHES:
795 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
801 /**************************************************************************
802 * MMDRV_MidiOut_Callback [internal]
804 static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
806 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
811 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
814 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
815 /* initial map is: 32 => 16 */
816 LPMIDIHDR mh16 = MapSL(dwParam1);
817 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
819 dwParam1 = (DWORD)mh32;
820 mh32->dwFlags = mh16->dwFlags;
821 mh32->dwOffset = mh16->dwOffset;
822 if (mh32->reserved >= sizeof(MIDIHDR))
823 mh32->dwOffset = mh16->dwOffset;
824 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
825 /* initial map is: 16 => 32 */
826 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
827 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
828 LPMIDIHDR mh16 = MapSL(segmh16);
830 dwParam1 = (DWORD)segmh16;
831 mh16->dwFlags = mh32->dwFlags;
832 if (mh16->reserved >= sizeof(MIDIHDR))
833 mh16->dwOffset = mh32->dwOffset;
835 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
837 /* case MOM_POSITIONCB: */
839 ERR("Unknown msg %u\n", uMsg);
842 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
845 /* =================================
846 * W A V E I N M A P P E R S
847 * ================================= */
849 /**************************************************************************
850 * MMDRV_WaveIn_Map16To32A [internal]
852 static MMDRV_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
854 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
857 case WIDM_GETNUMDEVS:
865 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
867 case WIDM_GETDEVCAPS:
869 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
870 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
873 *(LPWAVEINCAPS16*)wic32 = wic16;
874 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
875 *lpParam1 = (DWORD)wic32;
876 *lpParam2 = sizeof(WAVEINCAPSA);
878 ret = MMDRV_MAP_OKMEM;
880 ret = MMDRV_MAP_NOMEM;
886 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
887 LPMMTIME16 mmt16 = MapSL(*lpParam1);
890 *(LPMMTIME16*)mmt32 = mmt16;
891 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
893 mmt32->wType = mmt16->wType;
894 *lpParam1 = (DWORD)mmt32;
895 *lpParam2 = sizeof(MMTIME);
897 ret = MMDRV_MAP_OKMEM;
899 ret = MMDRV_MAP_NOMEM;
905 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
906 LPWAVEHDR wh16 = MapSL(*lpParam1);
909 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
910 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
911 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
912 wh32->dwBufferLength = wh16->dwBufferLength;
913 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
914 wh32->dwUser = wh16->dwUser;
915 wh32->dwFlags = wh16->dwFlags;
916 wh32->dwLoops = wh16->dwLoops;
917 /* FIXME: nothing on wh32->lpNext */
918 /* could link the wh32->lpNext at this level for memory house keeping */
919 wh16->lpNext = wh32; /* for reuse in unprepare and write */
920 *lpParam1 = (DWORD)wh32;
921 *lpParam2 = sizeof(WAVEHDR);
923 ret = MMDRV_MAP_OKMEM;
925 ret = MMDRV_MAP_NOMEM;
932 LPWAVEHDR wh16 = MapSL(*lpParam1);
933 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
935 *lpParam1 = (DWORD)wh32;
936 *lpParam2 = sizeof(WAVEHDR);
937 /* dwBufferLength can be reduced between prepare & write */
938 if (wh32->dwBufferLength < wh16->dwBufferLength) {
939 ERR("Size of buffer has been increased (%ld, %ld)\n",
940 wh32->dwBufferLength, wh16->dwBufferLength);
941 return MMDRV_MAP_MSGERROR;
943 wh32->dwBufferLength = wh16->dwBufferLength;
944 ret = MMDRV_MAP_OKMEM;
947 case WIDM_MAPPER_STATUS:
948 /* just a single DWORD */
949 *lpParam2 = (DWORD)MapSL(*lpParam2);
953 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
959 /**************************************************************************
960 * MMDRV_WaveIn_UnMap16To32A [internal]
962 static MMDRV_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
964 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
967 case WIDM_GETNUMDEVS:
971 case WIDM_MAPPER_STATUS:
976 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
978 case WIDM_GETDEVCAPS:
980 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
981 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
983 wic16->wMid = wic32->wMid;
984 wic16->wPid = wic32->wPid;
985 wic16->vDriverVersion = wic32->vDriverVersion;
986 strcpy(wic16->szPname, wic32->szPname);
987 wic16->dwFormats = wic32->dwFormats;
988 wic16->wChannels = wic32->wChannels;
989 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
995 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
996 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
998 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
999 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1003 case WIDM_ADDBUFFER:
1005 case WIDM_UNPREPARE:
1007 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1008 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1010 assert(wh16->lpNext == wh32);
1011 wh16->dwBufferLength = wh32->dwBufferLength;
1012 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1013 wh16->dwUser = wh32->dwUser;
1014 wh16->dwFlags = wh32->dwFlags;
1015 wh16->dwLoops = wh32->dwLoops;
1017 if (wMsg == WIDM_UNPREPARE) {
1018 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1025 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1031 /**************************************************************************
1032 * MMDRV_WaveIn_Map32ATo16 [internal]
1034 static MMDRV_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1036 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1040 case WIDM_GETNUMDEVS:
1049 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1050 int sz = sizeof(WAVEFORMATEX);
1052 LPWAVEOPENDESC16 wod16;
1054 /* allocated data are mapped as follows:
1055 LPWAVEOPENDESC ptr to orig lParam1
1056 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1057 DWORD dwUser passed to driver
1058 WAVEOPENDESC16 wod16: openDesc passed to driver
1059 WAVEFORMATEX openDesc->lpFormat passed to driver
1060 xxx extra bytes to WAVEFORMATEX
1062 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1063 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1064 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1067 ptr = HeapAlloc( GetProcessHeap(), 0,
1068 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1071 SEGPTR seg_ptr = MapLS( ptr );
1072 *(LPWAVEOPENDESC*)ptr = wod32;
1073 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1074 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1076 wod16->hWave = wod32->hWave;
1077 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1078 memcpy(wod16 + 1, wod32->lpFormat, sz);
1080 wod16->dwCallback = wod32->dwCallback;
1081 wod16->dwInstance = wod32->dwInstance;
1082 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1083 wod16->dnDevNode = wod32->dnDevNode;
1085 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1086 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1088 ret = MMDRV_MAP_OKMEM;
1090 ret = MMDRV_MAP_NOMEM;
1096 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1098 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1099 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1102 SEGPTR seg_ptr = MapLS( ptr );
1103 *(LPWAVEHDR*)ptr = wh32;
1104 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1105 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1106 /* data will be copied on WODM_WRITE */
1107 wh16->dwBufferLength = wh32->dwBufferLength;
1108 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1109 wh16->dwUser = wh32->dwUser;
1110 wh16->dwFlags = wh32->dwFlags;
1111 wh16->dwLoops = wh32->dwLoops;
1112 /* FIXME: nothing on wh32->lpNext */
1113 /* could link the wh32->lpNext at this level for memory house keeping */
1114 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1115 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1116 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1117 wh32->dwBufferLength, (DWORD)wh32->lpData);
1118 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1119 *lpParam2 = sizeof(WAVEHDR);
1121 ret = MMDRV_MAP_OKMEM;
1123 ret = MMDRV_MAP_NOMEM;
1127 case WIDM_ADDBUFFER:
1128 case WIDM_UNPREPARE:
1130 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1131 LPWAVEHDR wh16 = wh32->lpNext;
1132 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1133 SEGPTR seg_ptr = MapLS( ptr );
1135 assert(*(LPWAVEHDR*)ptr == wh32);
1137 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1138 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1139 wh32->dwBufferLength, (DWORD)wh32->lpData);
1141 if (wMsg == WIDM_ADDBUFFER)
1142 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1144 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1145 *lpParam2 = sizeof(WAVEHDR);
1146 /* dwBufferLength can be reduced between prepare & write */
1147 if (wh32->dwBufferLength < wh16->dwBufferLength) {
1148 ERR("Size of buffer has been increased (%ld, %ld)\n",
1149 wh32->dwBufferLength, wh16->dwBufferLength);
1150 return MMDRV_MAP_MSGERROR;
1152 wh32->dwBufferLength = wh16->dwBufferLength;
1153 ret = MMDRV_MAP_OKMEM;
1156 case WIDM_GETDEVCAPS:
1158 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
1159 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
1162 *(LPWAVEINCAPSA*)ptr = wic32;
1163 ret = MMDRV_MAP_OKMEM;
1165 ret = MMDRV_MAP_NOMEM;
1167 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSA);
1168 *lpParam2 = sizeof(WAVEINCAPS16);
1173 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1174 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1175 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1178 *(LPMMTIME*)ptr = mmt32;
1179 mmt16->wType = mmt32->wType;
1180 ret = MMDRV_MAP_OKMEM;
1182 ret = MMDRV_MAP_NOMEM;
1184 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1185 *lpParam2 = sizeof(MMTIME16);
1188 case DRVM_MAPPER_STATUS:
1190 LPDWORD p32 = (LPDWORD)*lpParam2;
1191 *lpParam2 = MapLS(p32);
1192 ret = MMDRV_MAP_OKMEM;
1196 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1202 /**************************************************************************
1203 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1205 static MMDRV_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1207 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1211 case WIDM_GETNUMDEVS:
1220 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1221 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1222 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1224 UnMapLS( *lpParam1 );
1225 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1226 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1227 HeapFree( GetProcessHeap(), 0, ptr );
1232 case WIDM_ADDBUFFER:
1234 case WIDM_UNPREPARE:
1236 LPWAVEHDR wh16 = MapSL(*lpParam1);
1237 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1238 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1240 assert(wh32->lpNext == wh16);
1241 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1242 wh32->dwUser = wh16->dwUser;
1243 wh32->dwFlags = wh16->dwFlags;
1244 wh32->dwLoops = wh16->dwLoops;
1245 UnMapLS( *lpParam1 );
1247 if (wMsg == WIDM_UNPREPARE) {
1248 HeapFree( GetProcessHeap(), 0, ptr );
1254 case WIDM_GETDEVCAPS:
1256 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
1257 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1258 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
1260 wic32->wMid = wic16->wMid;
1261 wic32->wPid = wic16->wPid;
1262 wic32->vDriverVersion = wic16->vDriverVersion;
1263 strcpy(wic32->szPname, wic16->szPname);
1264 wic32->dwFormats = wic16->dwFormats;
1265 wic32->wChannels = wic16->wChannels;
1266 UnMapLS( *lpParam1 );
1267 HeapFree( GetProcessHeap(), 0, ptr );
1273 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1274 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1275 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1277 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1278 UnMapLS( *lpParam1 );
1279 HeapFree( GetProcessHeap(), 0, ptr );
1283 case DRVM_MAPPER_STATUS:
1285 UnMapLS( *lpParam2 );
1290 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1296 /**************************************************************************
1297 * MMDRV_WaveIn_Callback [internal]
1299 static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1301 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1306 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1309 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1310 /* initial map is: 32 => 16 */
1311 LPWAVEHDR wh16 = MapSL(dwParam1);
1312 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1314 dwParam1 = (DWORD)wh32;
1315 wh32->dwFlags = wh16->dwFlags;
1316 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1317 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1318 /* initial map is: 16 => 32 */
1319 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1320 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1321 LPWAVEHDR wh16 = MapSL(segwh16);
1323 dwParam1 = (DWORD)segwh16;
1324 wh16->dwFlags = wh32->dwFlags;
1325 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1327 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1330 ERR("Unknown msg %u\n", uMsg);
1333 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1336 /* =================================
1337 * W A V E O U T M A P P E R S
1338 * ================================= */
1340 /**************************************************************************
1341 * MMDRV_WaveOut_Map16To32A [internal]
1343 static MMDRV_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1345 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1349 case WODM_BREAKLOOP:
1351 case WODM_GETNUMDEVS:
1356 case WODM_SETPLAYBACKRATE:
1357 case WODM_SETVOLUME:
1362 case WODM_GETPLAYBACKRATE:
1363 case WODM_GETVOLUME:
1365 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1368 case WODM_GETDEVCAPS:
1370 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1371 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1374 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1375 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1376 *lpParam1 = (DWORD)woc32;
1377 *lpParam2 = sizeof(WAVEOUTCAPSA);
1379 ret = MMDRV_MAP_OKMEM;
1381 ret = MMDRV_MAP_NOMEM;
1387 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1388 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1391 *(LPMMTIME16*)mmt32 = mmt16;
1392 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1394 mmt32->wType = mmt16->wType;
1395 *lpParam1 = (DWORD)mmt32;
1396 *lpParam2 = sizeof(MMTIME);
1398 ret = MMDRV_MAP_OKMEM;
1400 ret = MMDRV_MAP_NOMEM;
1406 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1407 LPWAVEHDR wh16 = MapSL(*lpParam1);
1410 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1411 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1412 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1413 wh32->dwBufferLength = wh16->dwBufferLength;
1414 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1415 wh32->dwUser = wh16->dwUser;
1416 wh32->dwFlags = wh16->dwFlags;
1417 wh32->dwLoops = wh16->dwLoops;
1418 /* FIXME: nothing on wh32->lpNext */
1419 /* could link the wh32->lpNext at this level for memory house keeping */
1420 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1421 *lpParam1 = (DWORD)wh32;
1422 *lpParam2 = sizeof(WAVEHDR);
1424 ret = MMDRV_MAP_OKMEM;
1426 ret = MMDRV_MAP_NOMEM;
1430 case WODM_UNPREPARE:
1433 LPWAVEHDR wh16 = MapSL(*lpParam1);
1434 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1436 *lpParam1 = (DWORD)wh32;
1437 *lpParam2 = sizeof(WAVEHDR);
1438 /* dwBufferLength can be reduced between prepare & write */
1439 if (wh32->dwBufferLength < wh16->dwBufferLength) {
1440 ERR("Size of buffer has been increased (%ld, %ld)\n",
1441 wh32->dwBufferLength, wh16->dwBufferLength);
1442 return MMDRV_MAP_MSGERROR;
1444 wh32->dwBufferLength = wh16->dwBufferLength;
1445 ret = MMDRV_MAP_OKMEM;
1448 case WODM_MAPPER_STATUS:
1449 *lpParam2 = (DWORD)MapSL(*lpParam2);
1453 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1459 /**************************************************************************
1460 * MMDRV_WaveOut_UnMap16To32A [internal]
1462 static MMDRV_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1464 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1468 case WODM_BREAKLOOP:
1470 case WODM_GETNUMDEVS:
1475 case WODM_SETPLAYBACKRATE:
1476 case WODM_SETVOLUME:
1477 case WODM_MAPPER_STATUS:
1482 case WODM_GETPLAYBACKRATE:
1483 case WODM_GETVOLUME:
1485 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1488 case WODM_GETDEVCAPS:
1490 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1491 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1493 woc16->wMid = woc32->wMid;
1494 woc16->wPid = woc32->wPid;
1495 woc16->vDriverVersion = woc32->vDriverVersion;
1496 strcpy(woc16->szPname, woc32->szPname);
1497 woc16->dwFormats = woc32->dwFormats;
1498 woc16->wChannels = woc32->wChannels;
1499 woc16->dwSupport = woc32->dwSupport;
1500 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1506 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1507 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1509 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1510 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1515 case WODM_UNPREPARE:
1518 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1519 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1521 assert(wh16->lpNext == wh32);
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;
1528 if (wMsg == WODM_UNPREPARE) {
1529 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1536 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1542 /**************************************************************************
1543 * MMDRV_WaveOut_Map32ATo16 [internal]
1545 static MMDRV_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1551 case WODM_BREAKLOOP:
1553 case WODM_GETNUMDEVS:
1558 case WODM_SETPLAYBACKRATE:
1559 case WODM_SETVOLUME:
1563 case WODM_GETDEVCAPS:
1565 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1566 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1567 sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1570 *(LPWAVEOUTCAPSA*)ptr = woc32;
1571 ret = MMDRV_MAP_OKMEM;
1573 ret = MMDRV_MAP_NOMEM;
1575 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSA);
1576 *lpParam2 = sizeof(WAVEOUTCAPS16);
1580 FIXME("NIY: no conversion yet\n");
1581 ret = MMDRV_MAP_MSGERROR;
1583 case WODM_GETPLAYBACKRATE:
1584 FIXME("NIY: no conversion yet\n");
1585 ret = MMDRV_MAP_MSGERROR;
1589 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1590 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1591 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1594 *(LPMMTIME*)ptr = mmt32;
1595 mmt16->wType = mmt32->wType;
1596 ret = MMDRV_MAP_OKMEM;
1598 ret = MMDRV_MAP_NOMEM;
1600 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1601 *lpParam2 = sizeof(MMTIME16);
1604 case WODM_GETVOLUME:
1605 FIXME("NIY: no conversion yet\n");
1606 ret = MMDRV_MAP_MSGERROR;
1610 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1611 int sz = sizeof(WAVEFORMATEX);
1613 LPWAVEOPENDESC16 wod16;
1615 /* allocated data are mapped as follows:
1616 LPWAVEOPENDESC ptr to orig lParam1
1617 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1618 DWORD dwUser passed to driver
1619 WAVEOPENDESC16 wod16: openDesc passed to driver
1620 WAVEFORMATEX openDesc->lpFormat passed to driver
1621 xxx extra bytes to WAVEFORMATEX
1623 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1624 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1625 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1628 ptr = HeapAlloc( GetProcessHeap(), 0,
1629 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1632 SEGPTR seg_ptr = MapLS( ptr );
1633 *(LPWAVEOPENDESC*)ptr = wod32;
1634 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1635 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1637 wod16->hWave = wod32->hWave;
1638 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1639 memcpy(wod16 + 1, wod32->lpFormat, sz);
1641 wod16->dwCallback = wod32->dwCallback;
1642 wod16->dwInstance = wod32->dwInstance;
1643 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1644 wod16->dnDevNode = wod32->dnDevNode;
1646 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1647 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1649 ret = MMDRV_MAP_OKMEM;
1651 ret = MMDRV_MAP_NOMEM;
1657 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1659 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1660 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1663 SEGPTR seg_ptr = MapLS( ptr );
1664 *(LPWAVEHDR*)ptr = wh32;
1665 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1666 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1667 /* data will be copied on WODM_WRITE */
1668 wh16->dwBufferLength = wh32->dwBufferLength;
1669 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1670 wh16->dwUser = wh32->dwUser;
1671 wh16->dwFlags = wh32->dwFlags;
1672 wh16->dwLoops = wh32->dwLoops;
1673 /* FIXME: nothing on wh32->lpNext */
1674 /* could link the wh32->lpNext at this level for memory house keeping */
1675 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1676 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1677 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1678 wh32->dwBufferLength, (DWORD)wh32->lpData);
1679 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1680 *lpParam2 = sizeof(WAVEHDR);
1682 ret = MMDRV_MAP_OKMEM;
1684 ret = MMDRV_MAP_NOMEM;
1688 case WODM_UNPREPARE:
1691 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1692 LPWAVEHDR wh16 = wh32->lpNext;
1693 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1694 SEGPTR seg_ptr = MapLS( ptr );
1696 assert(*(LPWAVEHDR*)ptr == wh32);
1698 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1699 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1700 wh32->dwBufferLength, (DWORD)wh32->lpData);
1702 if (wMsg == WODM_WRITE)
1703 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1705 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1706 *lpParam2 = sizeof(WAVEHDR);
1707 /* dwBufferLength can be reduced between prepare & write */
1708 if (wh16->dwBufferLength < wh32->dwBufferLength) {
1709 ERR("Size of buffer has been increased (%ld, %ld)\n",
1710 wh16->dwBufferLength, wh32->dwBufferLength);
1711 return MMDRV_MAP_MSGERROR;
1713 wh16->dwBufferLength = wh32->dwBufferLength;
1714 ret = MMDRV_MAP_OKMEM;
1717 case DRVM_MAPPER_STATUS:
1719 LPDWORD p32 = (LPDWORD)*lpParam2;
1720 *lpParam2 = MapLS(p32);
1721 ret = MMDRV_MAP_OKMEM;
1725 FIXME("NIY: no conversion yet\n");
1726 ret = MMDRV_MAP_MSGERROR;
1732 /**************************************************************************
1733 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1735 static MMDRV_MapType MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1741 case WODM_BREAKLOOP:
1743 case WODM_GETNUMDEVS:
1748 case WODM_SETPLAYBACKRATE:
1749 case WODM_SETVOLUME:
1753 case WODM_GETDEVCAPS:
1755 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1756 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1757 LPWAVEOUTCAPSA woc32 = *(LPWAVEOUTCAPSA*)ptr;
1759 woc32->wMid = woc16->wMid;
1760 woc32->wPid = woc16->wPid;
1761 woc32->vDriverVersion = woc16->vDriverVersion;
1762 strcpy(woc32->szPname, woc16->szPname);
1763 woc32->dwFormats = woc16->dwFormats;
1764 woc32->wChannels = woc16->wChannels;
1765 woc32->dwSupport = woc16->dwSupport;
1766 UnMapLS( *lpParam1 );
1767 HeapFree( GetProcessHeap(), 0, ptr );
1772 FIXME("NIY: no conversion yet\n");
1773 ret = MMDRV_MAP_MSGERROR;
1775 case WODM_GETPLAYBACKRATE:
1776 FIXME("NIY: no conversion yet\n");
1777 ret = MMDRV_MAP_MSGERROR;
1781 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1782 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1783 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1785 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1786 UnMapLS( *lpParam1 );
1787 HeapFree( GetProcessHeap(), 0, ptr );
1793 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1794 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1795 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1797 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1798 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1799 UnMapLS( *lpParam1 );
1800 HeapFree( GetProcessHeap(), 0, ptr );
1805 case WODM_UNPREPARE:
1808 LPWAVEHDR wh16 = MapSL(*lpParam1);
1809 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1810 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1812 assert(wh32->lpNext == wh16);
1813 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1814 wh32->dwUser = wh16->dwUser;
1815 wh32->dwFlags = wh16->dwFlags;
1816 wh32->dwLoops = wh16->dwLoops;
1818 UnMapLS( *lpParam1 );
1819 if (wMsg == WODM_UNPREPARE) {
1820 HeapFree( GetProcessHeap(), 0, ptr );
1826 case WODM_GETVOLUME:
1827 FIXME("NIY: no conversion yet\n");
1828 ret = MMDRV_MAP_MSGERROR;
1830 case DRVM_MAPPER_STATUS:
1832 UnMapLS( *lpParam2 );
1837 FIXME("NIY: no conversion yet\n");
1838 ret = MMDRV_MAP_MSGERROR;
1844 /**************************************************************************
1845 * MMDRV_WaveOut_Callback [internal]
1847 static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1849 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1854 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1857 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1858 /* initial map is: 32 => 16 */
1859 LPWAVEHDR wh16 = MapSL(dwParam1);
1860 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1862 dwParam1 = (DWORD)wh32;
1863 wh32->dwFlags = wh16->dwFlags;
1864 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1865 /* initial map is: 16 => 32 */
1866 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1867 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1868 LPWAVEHDR wh16 = MapSL(segwh16);
1870 dwParam1 = (DWORD)segwh16;
1871 wh16->dwFlags = wh32->dwFlags;
1873 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1876 ERR("Unknown msg %u\n", uMsg);
1879 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1882 #define A(_x,_y) {#_y, _x, \
1883 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1884 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1885 MMDRV_##_y##_Callback, 0, NULL, -1}
1887 /* Note: the indices of this array must match the definitions
1888 * of the MMDRV_???? manifest constants
1890 static WINE_LLTYPE llTypes[MMDRV_MAX] = {
1900 /**************************************************************************
1901 * MMDRV_GetNum [internal]
1903 UINT MMDRV_GetNum(UINT type)
1905 assert(type < MMDRV_MAX);
1906 return llTypes[type].wMaxId;
1909 /**************************************************************************
1910 * WINE_Message [internal]
1912 DWORD MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1,
1913 DWORD dwParam2, BOOL bFrom32)
1915 LPWINE_MM_DRIVER lpDrv;
1917 WINE_MM_DRIVER_PART* part;
1918 WINE_LLTYPE* llType = &llTypes[mld->type];
1922 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1923 llTypes[mld->type].typestr, mld->uDeviceID, wMsg,
1924 mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
1926 if (mld->uDeviceID == (UINT16)-1) {
1927 if (!llType->bSupportMapper) {
1928 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1929 llTypes[mld->type].typestr);
1930 return MMSYSERR_BADDEVICEID;
1934 if (mld->uDeviceID >= llType->wMaxId) {
1935 WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
1936 return MMSYSERR_BADDEVICEID;
1938 devID = mld->uDeviceID;
1941 lpDrv = &MMDrvs[mld->mmdIndex];
1942 part = &lpDrv->parts[mld->type];
1945 /* some sanity checks */
1946 if (!(part->nIDMin <= devID))
1947 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
1948 if (!(devID < part->nIDMax))
1949 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
1953 assert(part->u.fnMessage32);
1956 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1957 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1958 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1959 TRACE("=> %lu\n", ret);
1961 map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1963 case MMDRV_MAP_NOMEM:
1964 ret = MMSYSERR_NOMEM;
1966 case MMDRV_MAP_MSGERROR:
1967 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
1968 ret = MMSYSERR_ERROR;
1971 case MMDRV_MAP_OKMEM:
1972 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1973 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1974 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance,
1975 dwParam1, dwParam2);
1976 TRACE("=> %lu\n", ret);
1977 if (map == MMDRV_MAP_OKMEM)
1978 llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1981 case MMDRV_MAP_PASS:
1982 FIXME("NIY: pass used ?\n");
1983 ret = MMSYSERR_NOTSUPPORTED;
1988 assert(part->u.fnMessage16);
1991 map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1993 case MMDRV_MAP_NOMEM:
1994 ret = MMSYSERR_NOMEM;
1996 case MMDRV_MAP_MSGERROR:
1997 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
1998 ret = MMSYSERR_ERROR;
2001 case MMDRV_MAP_OKMEM:
2002 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2003 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2004 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
2005 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2006 TRACE("=> %lu\n", ret);
2007 if (map == MMDRV_MAP_OKMEM)
2008 llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
2011 case MMDRV_MAP_PASS:
2012 FIXME("NIY: pass used ?\n");
2013 ret = MMSYSERR_NOTSUPPORTED;
2017 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2018 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2019 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
2020 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2021 TRACE("=> %lu\n", ret);
2027 /**************************************************************************
2028 * MMDRV_Alloc [internal]
2030 LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
2031 DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
2035 mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2036 if (!mld) return NULL;
2038 /* find an empty slot in MM_MLDrvs table */
2039 for (*hndl = 0; *hndl < MAX_MM_MLDRVS; (*hndl)++) {
2040 if (!MM_MLDrvs[*hndl]) break;
2042 if (*hndl == MAX_MM_MLDRVS) {
2043 /* the MM_MLDrvs table could be made growable in the future if needed */
2044 ERR("Too many open drivers\n");
2047 MM_MLDrvs[*hndl] = mld;
2051 if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
2052 /* FIXME: those conditions must be fulfilled so that:
2053 * - we can distinguish between device IDs and handles
2054 * - we can use handles as 16 or 32 bit entities
2056 ERR("Shouldn't happen. Bad allocation scheme\n");
2059 mld->bFrom32 = bFrom32;
2060 mld->dwFlags = HIWORD(*dwFlags);
2061 mld->dwCallback = *dwCallback;
2062 mld->dwClientInstance = *dwInstance;
2064 *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
2065 *dwCallback = (DWORD)llTypes[type].Callback;
2066 *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2071 /**************************************************************************
2072 * MMDRV_Free [internal]
2074 void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
2076 if (hndl & 0x8000) {
2077 unsigned idx = hndl & ~0x8000;
2078 if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2079 MM_MLDrvs[idx] = NULL;
2080 HeapFree(GetProcessHeap(), 0, mld);
2084 ERR("Bad Handle %08x at %p (not freed)\n", hndl, mld);
2087 /**************************************************************************
2088 * MMDRV_Open [internal]
2090 DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
2092 DWORD dwRet = MMSYSERR_BADDEVICEID;
2094 WINE_LLTYPE* llType = &llTypes[mld->type];
2096 mld->dwDriverInstance = (DWORD)&dwInstance;
2098 if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
2099 TRACE("MAPPER mode requested !\n");
2100 /* check if mapper is supported by type */
2101 if (llType->bSupportMapper) {
2102 if (llType->nMapper == -1) {
2103 /* no driver for mapper has been loaded, try a dumb implementation */
2104 TRACE("No mapper loaded, doing it by hand\n");
2105 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
2106 if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
2107 /* to share this function epilog */
2108 dwInstance = mld->dwDriverInstance;
2113 mld->uDeviceID = (UINT16)-1;
2114 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
2115 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2116 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2120 if (mld->uDeviceID < llType->wMaxId) {
2121 mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
2122 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2123 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2126 if (dwRet == MMSYSERR_NOERROR)
2127 mld->dwDriverInstance = dwInstance;
2131 /**************************************************************************
2132 * MMDRV_Close [internal]
2134 DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
2136 return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
2139 /**************************************************************************
2140 * MMDRV_GetByID [internal]
2142 LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
2144 if (uDevID < llTypes[type].wMaxId)
2145 return &llTypes[type].lpMlds[uDevID];
2146 if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
2147 return &llTypes[type].lpMlds[-1];
2151 /**************************************************************************
2152 * MMDRV_Get [internal]
2154 LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
2156 LPWINE_MLD mld = NULL;
2158 assert(type < MMDRV_MAX);
2160 if ((UINT)hndl >= llTypes[type].wMaxId &&
2161 hndl != (UINT16)-1 && hndl != (UINT)-1) {
2162 if (hndl & 0x8000) {
2164 if (hndl < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2165 mld = MM_MLDrvs[hndl];
2166 if (!mld || !HeapValidate(GetProcessHeap(), 0, mld) || mld->type != type)
2172 if (mld == NULL && bCanBeID) {
2173 mld = MMDRV_GetByID((UINT)hndl, type);
2178 /**************************************************************************
2179 * MMDRV_GetRelated [internal]
2181 LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
2182 BOOL bSrcCanBeID, UINT dstType)
2186 if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
2187 WINE_MM_DRIVER_PART* part = &MMDrvs[mld->mmdIndex].parts[dstType];
2188 if (part->nIDMin < part->nIDMax)
2189 return MMDRV_GetByID(part->nIDMin, dstType);
2194 /**************************************************************************
2195 * MMDRV_PhysicalFeatures [internal]
2197 UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
2200 WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
2202 TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
2204 /* all those function calls are undocumented */
2206 case DRV_QUERYDRVENTRY:
2207 lstrcpynA((LPSTR)dwParam1, lpDrv->drvname, LOWORD(dwParam2));
2209 case DRV_QUERYDEVNODE:
2210 *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
2213 WARN("NIY QueryName\n");
2215 case DRV_QUERYDRIVERIDS:
2216 WARN("NIY call VxD\n");
2217 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2218 * dwParam1 is buffer and dwParam2 is sizeof buffer
2219 * I don't know where the result is stored though
2222 case DRV_QUERYMAPPABLE:
2223 return (lpDrv->bIsMapper) ? 2 : 0;
2225 case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
2226 return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
2229 WARN("Unknown call %04x\n", uMsg);
2230 return MMSYSERR_INVALPARAM;
2235 /**************************************************************************
2236 * MMDRV_InitPerType [internal]
2238 static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT type, UINT wMsg)
2240 WINE_MM_DRIVER_PART* part = &lpDrv->parts[type];
2245 part->nIDMin = part->nIDMax = 0;
2247 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2248 /* the DRVM_ENABLE is only required when the PnP node is non zero */
2250 if (lpDrv->bIs32 && part->u.fnMessage32) {
2251 ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
2252 TRACE("DRVM_INIT => %08lx\n", ret);
2254 ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
2255 TRACE("DRVM_ENABLE => %08lx\n", ret);
2257 count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
2258 } else if (!lpDrv->bIs32 && part->u.fnMessage16) {
2259 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2260 0, DRVM_INIT, 0L, 0L, 0L);
2261 TRACE("DRVM_INIT => %08lx\n", ret);
2263 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2264 0, DRVM_ENABLE, 0L, 0L, 0L);
2265 TRACE("DRVM_ENABLE => %08lx\n", ret);
2267 count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2268 0, wMsg, 0L, 0L, 0L);
2273 TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->drvname, llTypes[type].typestr);
2275 /* got some drivers */
2276 if (lpDrv->bIsMapper) {
2277 /* it seems native mappers return 0 devices :-( */
2278 if (llTypes[type].nMapper != -1)
2279 ERR("Two mappers for type %s (%d, %s)\n",
2280 llTypes[type].typestr, llTypes[type].nMapper, lpDrv->drvname);
2282 ERR("Strange: mapper with %d > 1 devices\n", count);
2283 llTypes[type].nMapper = MMDrvsHi;
2287 part->nIDMin = llTypes[type].wMaxId;
2288 llTypes[type].wMaxId += count;
2289 part->nIDMax = llTypes[type].wMaxId;
2291 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2292 part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
2293 lpDrv->drvname, llTypes[type].typestr);
2294 /* realloc translation table */
2295 llTypes[type].lpMlds = (LPWINE_MLD)
2296 HeapReAlloc(GetProcessHeap(), 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
2297 sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
2298 /* re-build the translation table */
2299 if (llTypes[type].nMapper != -1) {
2300 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, -1, MMDrvs[llTypes[type].nMapper].drvname);
2301 llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
2302 llTypes[type].lpMlds[-1].type = type;
2303 llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
2304 llTypes[type].lpMlds[-1].dwDriverInstance = 0;
2306 for (i = k = 0; i <= MMDrvsHi; i++) {
2307 while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
2308 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, k, MMDrvs[i].drvname);
2309 llTypes[type].lpMlds[k].uDeviceID = k;
2310 llTypes[type].lpMlds[k].type = type;
2311 llTypes[type].lpMlds[k].mmdIndex = i;
2312 llTypes[type].lpMlds[k].dwDriverInstance = 0;
2319 /**************************************************************************
2320 * MMDRV_Install [internal]
2322 static BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
2326 LPWINE_MM_DRIVER lpDrv = &MMDrvs[MMDrvsHi];
2329 TRACE("('%s', '%s', mapper=%c);\n", drvRegName, drvFileName, bIsMapper ? 'Y' : 'N');
2331 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2332 * if not just increase size of MMDrvs */
2333 assert(MMDrvsHi <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
2335 for (i = 0; i < MMDrvsHi; i++) {
2336 if (!strcmp(drvRegName, MMDrvs[i].drvname)) return FALSE;
2339 memset(lpDrv, 0, sizeof(*lpDrv));
2341 if (!(lpDrv->hDriver = OpenDriverA(drvFileName, 0, 0))) {
2342 WARN("Couldn't open driver '%s'\n", drvFileName);
2346 d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
2347 lpDrv->bIs32 = (d->dwFlags & WINE_GDF_16BIT) ? FALSE : TRUE;
2349 /* Then look for xxxMessage functions */
2350 #define AA(_h,_w,_x,_y,_z) \
2351 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
2353 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2354 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2357 WINEMM_msgFunc32 func;
2359 if (d->d.d32.hModule) {
2360 #define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
2361 A(MMDRV_AUX, auxMessage);
2362 A(MMDRV_MIXER, mixMessage);
2363 A(MMDRV_MIDIIN, midMessage);
2364 A(MMDRV_MIDIOUT, modMessage);
2365 A(MMDRV_WAVEIN, widMessage);
2366 A(MMDRV_WAVEOUT, wodMessage);
2370 WINEMM_msgFunc16 func;
2373 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2374 * The beginning of the module description indicates the driver supports
2375 * waveform, auxiliary, and mixer devices. Use one of the following
2376 * device-type names, followed by a colon (:) to indicate the type of
2377 * device your driver supports. If the driver supports more than one
2378 * type of device, separate each device-type name with a comma (,).
2380 * wave for waveform audio devices
2381 * wavemapper for wave mappers
2382 * midi for MIDI audio devices
2383 * midimapper for midi mappers
2384 * aux for auxiliary audio devices
2385 * mixer for mixer devices
2388 if (d->d.d16.hDriver16) {
2389 HMODULE16 hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
2391 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
2392 A(MMDRV_AUX, auxMessage);
2393 A(MMDRV_MIXER, mixMessage);
2394 A(MMDRV_MIDIIN, midMessage);
2395 A(MMDRV_MIDIOUT, modMessage);
2396 A(MMDRV_WAVEIN, widMessage);
2397 A(MMDRV_WAVEOUT, wodMessage);
2403 if (TRACE_ON(mmsys)) {
2404 if ((lpDrv->bIs32) ? MMDRV_GetDescription32(drvFileName, buffer, sizeof(buffer)) :
2405 MMDRV_GetDescription16(drvFileName, buffer, sizeof(buffer)))
2406 TRACE("%s => %s\n", drvFileName, buffer);
2408 TRACE("%s => No description\n", drvFileName);
2412 CloseDriver(lpDrv->hDriver, 0, 0);
2413 WARN("No message functions found\n");
2417 /* FIXME: being a mapper or not should be known by another way */
2418 /* it's known for NE drvs (the description is of the form '*mapper: *'
2419 * I don't have any clue for PE drvs
2421 lpDrv->bIsMapper = bIsMapper;
2422 lpDrv->drvname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(drvRegName) + 1), drvRegName);
2424 /* Finish init and get the count of the devices */
2425 MMDRV_InitPerType(lpDrv, MMDRV_AUX, AUXDM_GETNUMDEVS);
2426 MMDRV_InitPerType(lpDrv, MMDRV_MIXER, MXDM_GETNUMDEVS);
2427 MMDRV_InitPerType(lpDrv, MMDRV_MIDIIN, MIDM_GETNUMDEVS);
2428 MMDRV_InitPerType(lpDrv, MMDRV_MIDIOUT, MODM_GETNUMDEVS);
2429 MMDRV_InitPerType(lpDrv, MMDRV_WAVEIN, WIDM_GETNUMDEVS);
2430 MMDRV_InitPerType(lpDrv, MMDRV_WAVEOUT, WODM_GETNUMDEVS);
2431 /* FIXME: if all those func calls return FALSE,
2432 * then the driver must be unloaded
2440 /**************************************************************************
2441 * MMDRV_InitFromRegistry [internal]
2443 static BOOL MMDRV_InitFromRegistry(void)
2452 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\WinMM", &hKey)) {
2453 TRACE("Cannot open WinMM config key\n");
2457 size = sizeof(buffer);
2458 if (!RegQueryValueExA(hKey, "Drivers", 0, &type, (LPVOID)buffer, &size)) {
2461 p2 = strchr(p1, ';');
2462 if (p2) *p2++ = '\0';
2463 ret |= MMDRV_Install(p1, p1, FALSE);
2468 /* finish with mappers */
2469 size = sizeof(buffer);
2470 if (!RegQueryValueExA(hKey, "WaveMapper", 0, &type, (LPVOID)buffer, &size))
2471 ret |= MMDRV_Install("wavemapper", buffer, TRUE);
2472 size = sizeof(buffer);
2473 if (!RegQueryValueExA(hKey, "MidiMapper", 0, &type, (LPVOID)buffer, &size))
2474 ret |= MMDRV_Install("midimapper", buffer, TRUE);
2481 /**************************************************************************
2482 * MMDRV_InitHardcoded [internal]
2484 static BOOL MMDRV_InitHardcoded(void)
2486 ERR("You didn't setup properly the config file for the Wine multimedia modules.\n"
2487 "Will use the hard-coded setup, but this will disappear soon.\n"
2488 "Please add a WinMM section to your Wine config file.\n");
2490 /* first load hardware drivers */
2491 MMDRV_Install("wineoss.drv", "wineoss.drv", FALSE);
2493 /* finish with mappers */
2494 MMDRV_Install("wavemapper", "msacm.drv", TRUE);
2495 MMDRV_Install("midimapper", "midimap.drv", TRUE);
2500 /**************************************************************************
2501 * MMDRV_Init [internal]
2503 BOOL MMDRV_Init(void)
2505 /* FIXME: MMDRV_InitFromRegistry shall be MMDRV_Init in a near future */
2506 return MMDRV_InitFromRegistry() || MMDRV_InitHardcoded();