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;
58 typedef WINMM_MapType (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
60 /* each known type of driver has an instance of this structure */
61 typedef struct tagWINE_LLTYPE {
62 /* those attributes depend on the specification of the type */
63 LPSTR typestr; /* name (for debugging) */
64 BOOL bSupportMapper; /* if type is allowed to support mapper */
65 MMDRV_MAPFUNC Map16To32A; /* those are function pointers to handle */
66 MMDRV_MAPFUNC UnMap16To32A; /* the parameter conversion (16 vs 32 bit) */
67 MMDRV_MAPFUNC Map32ATo16; /* when hi-func (in mmsystem or winmm) and */
68 MMDRV_MAPFUNC UnMap32ATo16; /* low-func (in .drv) do not match */
69 LPDRVCALLBACK Callback; /* handles callback for a specified type */
70 /* those attributes reflect the loaded/current situation for the type */
71 UINT wMaxId; /* number of loaded devices (sum across all loaded drivers */
72 LPWINE_MLD lpMlds; /* "static" mlds to access the part though device IDs */
73 int nMapper; /* index to mapper */
76 static int MMDrvsHi /* = 0 */;
77 static WINE_MM_DRIVER MMDrvs[3];
78 static LPWINE_MLD MM_MLDrvs[40];
79 #define MAX_MM_MLDRVS (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
81 /* ### start build ### */
82 extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
83 /* ### stop build ### */
85 /**************************************************************************
86 * MMDRV_GetDescription16 [internal]
88 static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
96 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
97 ERR("Can't open file %s (builtin driver ?)\n", fname);
101 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
103 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
104 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
105 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
106 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
107 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
108 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
109 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %lu\n", dw));
110 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
111 buflen = min((int)(unsigned)(BYTE)buf[0], buflen - 1);
112 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
115 TRACE("Got '%s' [%d]\n", buf, buflen);
121 /**************************************************************************
122 * MMDRV_GetDescription32 [internal]
124 static BOOL MMDRV_GetDescription32(const char* fname, char* buf, int buflen)
133 FARPROC pGetFileVersionInfoSizeA;
134 FARPROC pGetFileVersionInfoA;
135 FARPROC pVerQueryValueA;
138 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
140 if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR) E(("Can't find file %s\n", fname));
142 if (!(hmodule = LoadLibraryA( "version.dll" ))) goto theEnd;
143 if (!(pGetFileVersionInfoSizeA = GetProcAddress( hmodule, "GetFileVersionInfoSizeA" )))
145 if (!(pGetFileVersionInfoA = GetProcAddress( hmodule, "GetFileVersionInfoA" )))
147 if (!(pVerQueryValueA = GetProcAddress( hmodule, "pVerQueryValueA" )))
150 if (!(dw = pGetFileVersionInfoSizeA(ofs.szPathName, &h))) E(("Can't get FVIS\n"));
151 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw))) E(("OOM\n"));
152 if (!pGetFileVersionInfoA(ofs.szPathName, h, dw, ptr)) E(("Can't get FVI\n"));
154 #define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
155 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
171 if (!pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
172 lstrcpynA(buf, val, buflen);
177 HeapFree(GetProcessHeap(), 0, ptr);
178 if (hmodule) FreeLibrary( hmodule );
182 /**************************************************************************
183 * MMDRV_Callback [internal]
185 static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
187 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
188 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
190 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
191 /* 16 bit func, call it */
192 TRACE("Function (16 bit) !\n");
193 MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, HDRVR_16(hDev), uMsg,
194 mld->dwClientInstance, dwParam1, dwParam2);
196 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
197 mld->dwClientInstance, dwParam1, dwParam2);
201 /* =================================
202 * A U X M A P P E R S
203 * ================================= */
205 /**************************************************************************
206 * MMDRV_Aux_Map16To32A [internal]
208 static WINMM_MapType MMDRV_Aux_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
210 return WINMM_MAP_MSGERROR;
213 /**************************************************************************
214 * MMDRV_Aux_UnMap16To32A [internal]
216 static WINMM_MapType MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
218 return WINMM_MAP_MSGERROR;
221 /**************************************************************************
222 * MMDRV_Aux_Map32ATo16 [internal]
224 static WINMM_MapType MMDRV_Aux_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
226 return WINMM_MAP_MSGERROR;
229 /**************************************************************************
230 * MMDRV_Aux_UnMap32ATo16 [internal]
232 static WINMM_MapType MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
235 case AUXDM_GETDEVCAPS:
236 lpCaps->wMid = ac16.wMid;
237 lpCaps->wPid = ac16.wPid;
238 lpCaps->vDriverVersion = ac16.vDriverVersion;
239 strcpy(lpCaps->szPname, ac16.szPname);
240 lpCaps->wTechnology = ac16.wTechnology;
241 lpCaps->dwSupport = ac16.dwSupport;
243 return WINMM_MAP_MSGERROR;
246 /**************************************************************************
247 * MMDRV_Aux_Callback [internal]
249 static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
251 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
254 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
257 /* =================================
258 * M I X E R M A P P E R S
259 * ================================= */
261 /**************************************************************************
262 * xMMDRV_Mixer_Map16To32A [internal]
264 static WINMM_MapType MMDRV_Mixer_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
266 return WINMM_MAP_MSGERROR;
269 /**************************************************************************
270 * MMDRV_Mixer_UnMap16To32A [internal]
272 static WINMM_MapType MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
276 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
278 if (ret == MMSYSERR_NOERROR) {
279 mixcaps->wMid = micA.wMid;
280 mixcaps->wPid = micA.wPid;
281 mixcaps->vDriverVersion = micA.vDriverVersion;
282 strcpy(mixcaps->szPname, micA.szPname);
283 mixcaps->fdwSupport = micA.fdwSupport;
284 mixcaps->cDestinations = micA.cDestinations;
288 return WINMM_MAP_MSGERROR;
291 /**************************************************************************
292 * MMDRV_Mixer_Map32ATo16 [internal]
294 static WINMM_MapType MMDRV_Mixer_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
296 return WINMM_MAP_MSGERROR;
299 /**************************************************************************
300 * MMDRV_Mixer_UnMap32ATo16 [internal]
302 static WINMM_MapType MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
304 return WINMM_MAP_MSGERROR;
307 /**************************************************************************
308 * MMDRV_Mixer_Callback [internal]
310 static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
312 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
315 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
318 /* =================================
319 * M I D I I N M A P P E R S
320 * ================================= */
322 /**************************************************************************
323 * MMDRV_MidiIn_Map16To32A [internal]
325 static WINMM_MapType MMDRV_MidiIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
327 return WINMM_MAP_MSGERROR;
330 /**************************************************************************
331 * MMDRV_MidiIn_UnMap16To32A [internal]
333 static WINMM_MapType MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
335 return WINMM_MAP_MSGERROR;
338 /**************************************************************************
339 * MMDRV_MidiIn_Map32ATo16 [internal]
341 static WINMM_MapType MMDRV_MidiIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
343 return WINMM_MAP_MSGERROR;
346 /**************************************************************************
347 * MMDRV_MidiIn_UnMap32ATo16 [internal]
349 static WINMM_MapType MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
351 return WINMM_MAP_MSGERROR;
354 /**************************************************************************
355 * MMDRV_MidiIn_Callback [internal]
357 static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
359 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
364 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
369 /* dwParam1 & dwParam2 are are data, nothing to do */
373 /* dwParam1 points to a MidiHdr, work to be done !!! */
374 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
375 /* initial map is: 32 => 16 */
376 LPMIDIHDR mh16 = MapSL(dwParam1);
377 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
379 dwParam1 = (DWORD)mh32;
380 mh32->dwFlags = mh16->dwFlags;
381 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
382 if (mh32->reserved >= sizeof(MIDIHDR))
383 mh32->dwOffset = mh16->dwOffset;
384 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
385 /* initial map is: 16 => 32 */
386 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
387 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
388 LPMIDIHDR mh16 = MapSL(segmh16);
390 dwParam1 = (DWORD)segmh16;
391 mh16->dwFlags = mh32->dwFlags;
392 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
393 if (mh16->reserved >= sizeof(MIDIHDR))
394 mh16->dwOffset = mh32->dwOffset;
396 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
398 /* case MOM_POSITIONCB: */
400 ERR("Unknown msg %u\n", uMsg);
403 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
406 /* =================================
407 * M I D I O U T M A P P E R S
408 * ================================= */
410 /**************************************************************************
411 * MMDRV_MidiOut_Map16To32A [internal]
413 static WINMM_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
415 WINMM_MapType ret = WINMM_MAP_MSGERROR;
418 case MODM_GETNUMDEVS:
428 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
431 case MODM_GETDEVCAPS:
433 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
434 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
437 *(LPMIDIOUTCAPS16*)moc32 = moc16;
438 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
439 *lpParam1 = (DWORD)moc32;
440 *lpParam2 = sizeof(MIDIOUTCAPSA);
442 ret = WINMM_MAP_OKMEM;
444 ret = WINMM_MAP_NOMEM;
450 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
451 LPMIDIHDR mh16 = MapSL(*lpParam1);
454 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
455 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
456 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
457 mh32->dwBufferLength = mh16->dwBufferLength;
458 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
459 mh32->dwUser = mh16->dwUser;
460 mh32->dwFlags = mh16->dwFlags;
461 /* FIXME: nothing on mh32->lpNext */
462 /* could link the mh32->lpNext at this level for memory house keeping */
463 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
464 mh16->lpNext = mh32; /* for reuse in unprepare and write */
465 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
466 mh16->reserved = *lpParam2;
467 *lpParam1 = (DWORD)mh32;
468 *lpParam2 = sizeof(MIDIHDR);
470 ret = WINMM_MAP_OKMEM;
472 ret = WINMM_MAP_NOMEM;
479 LPMIDIHDR mh16 = MapSL(*lpParam1);
480 LPMIDIHDR mh32 = (LPMIDIHDR)mh16->lpNext;
482 *lpParam1 = (DWORD)mh32;
483 *lpParam2 = sizeof(MIDIHDR);
484 /* dwBufferLength can be reduced between prepare & write */
485 if (wMsg == MODM_LONGDATA && mh32->dwBufferLength < mh16->dwBufferLength) {
486 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
487 mh32->dwBufferLength, mh16->dwBufferLength);
489 mh32->dwBufferLength = mh16->dwBufferLength;
490 ret = WINMM_MAP_OKMEM;
494 case MODM_CACHEPATCHES:
495 case MODM_CACHEDRUMPATCHES:
497 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
503 /**************************************************************************
504 * MMDRV_MidiOut_UnMap16To32A [internal]
506 static WINMM_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
508 WINMM_MapType ret = WINMM_MAP_MSGERROR;
511 case MODM_GETNUMDEVS:
521 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
524 case MODM_GETDEVCAPS:
526 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
527 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
529 moc16->wMid = moc32->wMid;
530 moc16->wPid = moc32->wPid;
531 moc16->vDriverVersion = moc32->vDriverVersion;
532 strcpy(moc16->szPname, moc32->szPname);
533 moc16->wTechnology = moc32->wTechnology;
534 moc16->wVoices = moc32->wVoices;
535 moc16->wNotes = moc32->wNotes;
536 moc16->wChannelMask = moc32->wChannelMask;
537 moc16->dwSupport = moc32->dwSupport;
538 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
546 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
547 LPMIDIHDR mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
549 assert(mh16->lpNext == mh32);
550 mh16->dwBufferLength = mh32->dwBufferLength;
551 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
552 mh16->dwUser = mh32->dwUser;
553 mh16->dwFlags = mh32->dwFlags;
554 if (mh16->reserved >= sizeof(MIDIHDR))
555 mh16->dwOffset = mh32->dwOffset;
557 if (wMsg == MODM_UNPREPARE) {
558 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
565 case MODM_CACHEPATCHES:
566 case MODM_CACHEDRUMPATCHES:
568 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
574 /**************************************************************************
575 * MMDRV_MidiOut_Map32ATo16 [internal]
577 static WINMM_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
579 WINMM_MapType ret = WINMM_MAP_MSGERROR;
583 case MODM_GETNUMDEVS:
589 case MODM_GETDEVCAPS:
591 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
592 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA)+sizeof(MIDIOUTCAPS16));
595 *(LPMIDIOUTCAPSA*)ptr = moc32;
596 ret = WINMM_MAP_OKMEM;
598 ret = WINMM_MAP_NOMEM;
600 *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSA);
601 *lpParam2 = sizeof(MIDIOUTCAPS16);
606 LPMIDIHDR mh32 = (LPMIDIHDR)*lpParam1;
608 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
609 sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
612 *(LPMIDIHDR*)ptr = mh32;
613 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
614 *lpParam1 = MapLS(mh16);
615 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
616 /* data will be copied on WODM_WRITE */
617 mh16->dwBufferLength = mh32->dwBufferLength;
618 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
619 mh16->dwUser = mh32->dwUser;
620 mh16->dwFlags = mh32->dwFlags;
621 /* FIXME: nothing on mh32->lpNext */
622 /* could link the mh32->lpNext at this level for memory house keeping */
623 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
625 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
626 mh32->reserved = *lpParam2;
628 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
629 *lpParam1, (DWORD)mh16->lpData,
630 mh32->dwBufferLength, (DWORD)mh32->lpData);
631 *lpParam2 = sizeof(MIDIHDR);
633 ret = WINMM_MAP_OKMEM;
635 ret = WINMM_MAP_NOMEM;
642 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
643 LPMIDIHDR mh16 = (LPMIDIHDR)mh32->lpNext;
644 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
646 assert(*(LPMIDIHDR*)ptr == mh32);
648 if (wMsg == MODM_LONGDATA)
649 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
651 *lpParam1 = MapLS(mh16);
652 *lpParam2 = sizeof(MIDIHDR);
653 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
654 *lpParam1, (DWORD)mh16->lpData, mh32->dwBufferLength, (DWORD)mh32->lpData);
656 /* dwBufferLength can be reduced between prepare & write */
657 if (wMsg == MODM_LONGDATA && mh16->dwBufferLength < mh32->dwBufferLength) {
658 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
659 mh16->dwBufferLength, mh32->dwBufferLength);
661 mh16->dwBufferLength = mh32->dwBufferLength;
662 ret = WINMM_MAP_OKMEM;
667 LPMIDIOPENDESC mod32 = (LPMIDIOPENDESC)*lpParam1;
669 LPMIDIOPENDESC16 mod16;
671 /* allocated data are mapped as follows:
672 LPMIDIOPENDESC ptr to orig lParam1
673 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
674 DWORD dwUser passed to driver
675 MIDIOPENDESC16 mod16: openDesc passed to driver
678 ptr = HeapAlloc( GetProcessHeap(), 0,
679 sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
680 mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
683 SEGPTR segptr = MapLS(ptr);
684 *(LPMIDIOPENDESC*)ptr = mod32;
685 *(LPDWORD)((char*)ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
686 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
688 mod16->hMidi = HMIDI_16(mod32->hMidi);
689 mod16->dwCallback = mod32->dwCallback;
690 mod16->dwInstance = mod32->dwInstance;
691 mod16->dnDevNode = mod32->dnDevNode;
692 mod16->cIds = mod32->cIds;
693 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
695 *lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
696 *lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
698 ret = WINMM_MAP_OKMEM;
700 ret = WINMM_MAP_NOMEM;
705 case MODM_CACHEPATCHES:
706 case MODM_CACHEDRUMPATCHES:
708 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
714 /**************************************************************************
715 * MMDRV_MidiOut_UnMap32ATo16 [internal]
717 static WINMM_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
719 WINMM_MapType ret = WINMM_MAP_MSGERROR;
723 case MODM_GETNUMDEVS:
729 case MODM_GETDEVCAPS:
731 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
732 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
733 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
735 moc32->wMid = moc16->wMid;
736 moc32->wPid = moc16->wPid;
737 moc32->vDriverVersion = moc16->vDriverVersion;
738 strcpy(moc32->szPname, moc16->szPname);
739 moc32->wTechnology = moc16->wTechnology;
740 moc32->wVoices = moc16->wVoices;
741 moc32->wNotes = moc16->wNotes;
742 moc32->wChannelMask = moc16->wChannelMask;
743 moc32->dwSupport = moc16->dwSupport;
744 UnMapLS( *lpParam1 );
745 HeapFree( GetProcessHeap(), 0, ptr );
753 LPMIDIHDR mh16 = MapSL(*lpParam1);
754 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
755 LPMIDIHDR mh32 = *(LPMIDIHDR*)ptr;
757 assert(mh32->lpNext == (LPMIDIHDR)mh16);
758 UnMapLS( *lpParam1 );
759 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
760 mh32->dwUser = mh16->dwUser;
761 mh32->dwFlags = mh16->dwFlags;
763 if (wMsg == MODM_UNPREPARE) {
764 HeapFree( GetProcessHeap(), 0, ptr );
772 LPMIDIOPENDESC16 mod16 = MapSL(*lpParam1);
773 LPSTR ptr = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
774 UnMapLS( *lpParam1 );
775 **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
777 HeapFree( GetProcessHeap(), 0, ptr );
782 case MODM_CACHEPATCHES:
783 case MODM_CACHEDRUMPATCHES:
785 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
791 /**************************************************************************
792 * MMDRV_MidiOut_Callback [internal]
794 static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
796 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
801 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
804 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
805 /* initial map is: 32 => 16 */
806 LPMIDIHDR mh16 = MapSL(dwParam1);
807 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
809 dwParam1 = (DWORD)mh32;
810 mh32->dwFlags = mh16->dwFlags;
811 mh32->dwOffset = mh16->dwOffset;
812 if (mh32->reserved >= sizeof(MIDIHDR))
813 mh32->dwOffset = mh16->dwOffset;
814 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
815 /* initial map is: 16 => 32 */
816 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
817 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
818 LPMIDIHDR mh16 = MapSL(segmh16);
820 dwParam1 = (DWORD)segmh16;
821 mh16->dwFlags = mh32->dwFlags;
822 if (mh16->reserved >= sizeof(MIDIHDR))
823 mh16->dwOffset = mh32->dwOffset;
825 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
827 /* case MOM_POSITIONCB: */
829 ERR("Unknown msg %u\n", uMsg);
832 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
835 /* =================================
836 * W A V E I N M A P P E R S
837 * ================================= */
839 /**************************************************************************
840 * MMDRV_WaveIn_Map16To32A [internal]
842 static WINMM_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
844 WINMM_MapType ret = WINMM_MAP_MSGERROR;
847 case WIDM_GETNUMDEVS:
855 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
857 case WIDM_GETDEVCAPS:
859 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
860 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
863 *(LPWAVEINCAPS16*)wic32 = wic16;
864 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
865 *lpParam1 = (DWORD)wic32;
866 *lpParam2 = sizeof(WAVEINCAPSA);
868 ret = WINMM_MAP_OKMEM;
870 ret = WINMM_MAP_NOMEM;
876 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
877 LPMMTIME16 mmt16 = MapSL(*lpParam1);
880 *(LPMMTIME16*)mmt32 = mmt16;
881 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
883 mmt32->wType = mmt16->wType;
884 *lpParam1 = (DWORD)mmt32;
885 *lpParam2 = sizeof(MMTIME);
887 ret = WINMM_MAP_OKMEM;
889 ret = WINMM_MAP_NOMEM;
895 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
896 LPWAVEHDR wh16 = MapSL(*lpParam1);
899 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
900 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
901 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
902 wh32->dwBufferLength = wh16->dwBufferLength;
903 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
904 wh32->dwUser = wh16->dwUser;
905 wh32->dwFlags = wh16->dwFlags;
906 wh32->dwLoops = wh16->dwLoops;
907 /* FIXME: nothing on wh32->lpNext */
908 /* could link the wh32->lpNext at this level for memory house keeping */
909 wh16->lpNext = wh32; /* for reuse in unprepare and write */
910 *lpParam1 = (DWORD)wh32;
911 *lpParam2 = sizeof(WAVEHDR);
913 ret = WINMM_MAP_OKMEM;
915 ret = WINMM_MAP_NOMEM;
922 LPWAVEHDR wh16 = MapSL(*lpParam1);
923 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
925 *lpParam1 = (DWORD)wh32;
926 *lpParam2 = sizeof(WAVEHDR);
927 /* dwBufferLength can be reduced between prepare & write */
928 if (wMsg == WIDM_ADDBUFFER && wh32->dwBufferLength < wh16->dwBufferLength) {
929 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
930 wh32->dwBufferLength, wh16->dwBufferLength);
932 wh32->dwBufferLength = wh16->dwBufferLength;
933 ret = WINMM_MAP_OKMEM;
936 case WIDM_MAPPER_STATUS:
937 /* just a single DWORD */
938 *lpParam2 = (DWORD)MapSL(*lpParam2);
942 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
948 /**************************************************************************
949 * MMDRV_WaveIn_UnMap16To32A [internal]
951 static WINMM_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
953 WINMM_MapType ret = WINMM_MAP_MSGERROR;
956 case WIDM_GETNUMDEVS:
960 case WIDM_MAPPER_STATUS:
965 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
967 case WIDM_GETDEVCAPS:
969 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
970 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
972 wic16->wMid = wic32->wMid;
973 wic16->wPid = wic32->wPid;
974 wic16->vDriverVersion = wic32->vDriverVersion;
975 strcpy(wic16->szPname, wic32->szPname);
976 wic16->dwFormats = wic32->dwFormats;
977 wic16->wChannels = wic32->wChannels;
978 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
984 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
985 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
987 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
988 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
996 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
997 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
999 assert(wh16->lpNext == wh32);
1000 wh16->dwBufferLength = wh32->dwBufferLength;
1001 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1002 wh16->dwUser = wh32->dwUser;
1003 wh16->dwFlags = wh32->dwFlags;
1004 wh16->dwLoops = wh32->dwLoops;
1006 if (wMsg == WIDM_UNPREPARE) {
1007 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1014 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1020 /**************************************************************************
1021 * MMDRV_WaveIn_Map32ATo16 [internal]
1023 static WINMM_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1025 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1029 case WIDM_GETNUMDEVS:
1038 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1039 int sz = sizeof(WAVEFORMATEX);
1041 LPWAVEOPENDESC16 wod16;
1043 /* allocated data are mapped as follows:
1044 LPWAVEOPENDESC ptr to orig lParam1
1045 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1046 DWORD dwUser passed to driver
1047 WAVEOPENDESC16 wod16: openDesc passed to driver
1048 WAVEFORMATEX openDesc->lpFormat passed to driver
1049 xxx extra bytes to WAVEFORMATEX
1051 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1052 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1053 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1056 ptr = HeapAlloc( GetProcessHeap(), 0,
1057 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1060 SEGPTR seg_ptr = MapLS( ptr );
1061 *(LPWAVEOPENDESC*)ptr = wod32;
1062 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1063 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1065 wod16->hWave = HWAVE_16(wod32->hWave);
1066 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1067 memcpy(wod16 + 1, wod32->lpFormat, sz);
1069 wod16->dwCallback = wod32->dwCallback;
1070 wod16->dwInstance = wod32->dwInstance;
1071 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1072 wod16->dnDevNode = wod32->dnDevNode;
1074 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1075 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1077 ret = WINMM_MAP_OKMEM;
1079 ret = WINMM_MAP_NOMEM;
1085 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1087 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1088 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1091 SEGPTR seg_ptr = MapLS( ptr );
1092 *(LPWAVEHDR*)ptr = wh32;
1093 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1094 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1095 /* data will be copied on WODM_WRITE */
1096 wh16->dwBufferLength = wh32->dwBufferLength;
1097 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1098 wh16->dwUser = wh32->dwUser;
1099 wh16->dwFlags = wh32->dwFlags;
1100 wh16->dwLoops = wh32->dwLoops;
1101 /* FIXME: nothing on wh32->lpNext */
1102 /* could link the wh32->lpNext at this level for memory house keeping */
1103 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1104 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1105 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1106 wh32->dwBufferLength, (DWORD)wh32->lpData);
1107 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1108 *lpParam2 = sizeof(WAVEHDR);
1110 ret = WINMM_MAP_OKMEM;
1112 ret = WINMM_MAP_NOMEM;
1116 case WIDM_ADDBUFFER:
1117 case WIDM_UNPREPARE:
1119 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1120 LPWAVEHDR wh16 = wh32->lpNext;
1121 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1122 SEGPTR seg_ptr = MapLS( ptr );
1124 assert(*(LPWAVEHDR*)ptr == wh32);
1126 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1127 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1128 wh32->dwBufferLength, (DWORD)wh32->lpData);
1130 if (wMsg == WIDM_ADDBUFFER)
1131 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1133 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1134 *lpParam2 = sizeof(WAVEHDR);
1135 /* dwBufferLength can be reduced between prepare & write */
1136 if (wMsg == WIDM_ADDBUFFER && wh16->dwBufferLength < wh32->dwBufferLength) {
1137 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1138 wh16->dwBufferLength, wh32->dwBufferLength);
1140 wh16->dwBufferLength = wh32->dwBufferLength;
1141 ret = WINMM_MAP_OKMEM;
1144 case WIDM_GETDEVCAPS:
1146 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
1147 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
1150 *(LPWAVEINCAPSA*)ptr = wic32;
1151 ret = WINMM_MAP_OKMEM;
1153 ret = WINMM_MAP_NOMEM;
1155 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSA);
1156 *lpParam2 = sizeof(WAVEINCAPS16);
1161 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1162 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1163 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1166 *(LPMMTIME*)ptr = mmt32;
1167 mmt16->wType = mmt32->wType;
1168 ret = WINMM_MAP_OKMEM;
1170 ret = WINMM_MAP_NOMEM;
1172 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1173 *lpParam2 = sizeof(MMTIME16);
1176 case DRVM_MAPPER_STATUS:
1178 LPDWORD p32 = (LPDWORD)*lpParam2;
1179 *lpParam2 = MapLS(p32);
1180 ret = WINMM_MAP_OKMEM;
1184 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1190 /**************************************************************************
1191 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1193 static WINMM_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1195 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1199 case WIDM_GETNUMDEVS:
1208 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1209 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1210 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1212 UnMapLS( *lpParam1 );
1213 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1214 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1215 HeapFree( GetProcessHeap(), 0, ptr );
1220 case WIDM_ADDBUFFER:
1222 case WIDM_UNPREPARE:
1224 LPWAVEHDR wh16 = MapSL(*lpParam1);
1225 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1226 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1228 assert(wh32->lpNext == wh16);
1229 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1230 wh32->dwUser = wh16->dwUser;
1231 wh32->dwFlags = wh16->dwFlags;
1232 wh32->dwLoops = wh16->dwLoops;
1233 UnMapLS( *lpParam1 );
1235 if (wMsg == WIDM_UNPREPARE) {
1236 HeapFree( GetProcessHeap(), 0, ptr );
1242 case WIDM_GETDEVCAPS:
1244 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
1245 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1246 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
1248 wic32->wMid = wic16->wMid;
1249 wic32->wPid = wic16->wPid;
1250 wic32->vDriverVersion = wic16->vDriverVersion;
1251 strcpy(wic32->szPname, wic16->szPname);
1252 wic32->dwFormats = wic16->dwFormats;
1253 wic32->wChannels = wic16->wChannels;
1254 UnMapLS( *lpParam1 );
1255 HeapFree( GetProcessHeap(), 0, ptr );
1261 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1262 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1263 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1265 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1266 UnMapLS( *lpParam1 );
1267 HeapFree( GetProcessHeap(), 0, ptr );
1271 case DRVM_MAPPER_STATUS:
1273 UnMapLS( *lpParam2 );
1278 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1284 /**************************************************************************
1285 * MMDRV_WaveIn_Callback [internal]
1287 static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1289 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1294 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1297 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1298 /* initial map is: 32 => 16 */
1299 LPWAVEHDR wh16 = MapSL(dwParam1);
1300 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1302 dwParam1 = (DWORD)wh32;
1303 wh32->dwFlags = wh16->dwFlags;
1304 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1305 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1306 /* initial map is: 16 => 32 */
1307 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1308 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1309 LPWAVEHDR wh16 = MapSL(segwh16);
1311 dwParam1 = (DWORD)segwh16;
1312 wh16->dwFlags = wh32->dwFlags;
1313 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1315 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1318 ERR("Unknown msg %u\n", uMsg);
1321 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1324 /* =================================
1325 * W A V E O U T M A P P E R S
1326 * ================================= */
1328 /**************************************************************************
1329 * MMDRV_WaveOut_Map16To32A [internal]
1331 static WINMM_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1333 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1337 case WODM_BREAKLOOP:
1339 case WODM_GETNUMDEVS:
1344 case WODM_SETPLAYBACKRATE:
1345 case WODM_SETVOLUME:
1350 case WODM_GETPLAYBACKRATE:
1351 case WODM_GETVOLUME:
1353 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1356 case WODM_GETDEVCAPS:
1358 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1359 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1362 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1363 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1364 *lpParam1 = (DWORD)woc32;
1365 *lpParam2 = sizeof(WAVEOUTCAPSA);
1367 ret = WINMM_MAP_OKMEM;
1369 ret = WINMM_MAP_NOMEM;
1375 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1376 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1379 *(LPMMTIME16*)mmt32 = mmt16;
1380 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1382 mmt32->wType = mmt16->wType;
1383 *lpParam1 = (DWORD)mmt32;
1384 *lpParam2 = sizeof(MMTIME);
1386 ret = WINMM_MAP_OKMEM;
1388 ret = WINMM_MAP_NOMEM;
1394 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1395 LPWAVEHDR wh16 = MapSL(*lpParam1);
1398 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1399 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1400 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1401 wh32->dwBufferLength = wh16->dwBufferLength;
1402 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1403 wh32->dwUser = wh16->dwUser;
1404 wh32->dwFlags = wh16->dwFlags;
1405 wh32->dwLoops = wh16->dwLoops;
1406 /* FIXME: nothing on wh32->lpNext */
1407 /* could link the wh32->lpNext at this level for memory house keeping */
1408 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1409 *lpParam1 = (DWORD)wh32;
1410 *lpParam2 = sizeof(WAVEHDR);
1412 ret = WINMM_MAP_OKMEM;
1414 ret = WINMM_MAP_NOMEM;
1418 case WODM_UNPREPARE:
1421 LPWAVEHDR wh16 = MapSL(*lpParam1);
1422 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1424 *lpParam1 = (DWORD)wh32;
1425 *lpParam2 = sizeof(WAVEHDR);
1426 /* dwBufferLength can be reduced between prepare & write */
1427 if (wMsg == WODM_WRITE && wh32->dwBufferLength < wh16->dwBufferLength) {
1428 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1429 wh32->dwBufferLength, wh16->dwBufferLength);
1431 wh32->dwBufferLength = wh16->dwBufferLength;
1432 ret = WINMM_MAP_OKMEM;
1435 case WODM_MAPPER_STATUS:
1436 *lpParam2 = (DWORD)MapSL(*lpParam2);
1440 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1446 /**************************************************************************
1447 * MMDRV_WaveOut_UnMap16To32A [internal]
1449 static WINMM_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1451 WINMM_MapType ret = WINMM_MAP_MSGERROR;
1455 case WODM_BREAKLOOP:
1457 case WODM_GETNUMDEVS:
1462 case WODM_SETPLAYBACKRATE:
1463 case WODM_SETVOLUME:
1464 case WODM_MAPPER_STATUS:
1469 case WODM_GETPLAYBACKRATE:
1470 case WODM_GETVOLUME:
1472 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1475 case WODM_GETDEVCAPS:
1477 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1478 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1480 woc16->wMid = woc32->wMid;
1481 woc16->wPid = woc32->wPid;
1482 woc16->vDriverVersion = woc32->vDriverVersion;
1483 strcpy(woc16->szPname, woc32->szPname);
1484 woc16->dwFormats = woc32->dwFormats;
1485 woc16->wChannels = woc32->wChannels;
1486 woc16->dwSupport = woc32->dwSupport;
1487 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1493 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1494 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1496 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1497 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1502 case WODM_UNPREPARE:
1505 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1506 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1508 assert(wh16->lpNext == wh32);
1509 wh16->dwBufferLength = wh32->dwBufferLength;
1510 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1511 wh16->dwUser = wh32->dwUser;
1512 wh16->dwFlags = wh32->dwFlags;
1513 wh16->dwLoops = wh32->dwLoops;
1515 if (wMsg == WODM_UNPREPARE) {
1516 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1523 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1529 /**************************************************************************
1530 * MMDRV_WaveOut_Map32ATo16 [internal]
1532 static WINMM_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1538 case WODM_BREAKLOOP:
1540 case WODM_GETNUMDEVS:
1545 case WODM_SETPLAYBACKRATE:
1546 case WODM_SETVOLUME:
1550 case WODM_GETDEVCAPS:
1552 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1553 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1554 sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1557 *(LPWAVEOUTCAPSA*)ptr = woc32;
1558 ret = WINMM_MAP_OKMEM;
1560 ret = WINMM_MAP_NOMEM;
1562 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSA);
1563 *lpParam2 = sizeof(WAVEOUTCAPS16);
1567 FIXME("NIY: no conversion yet\n");
1568 ret = WINMM_MAP_MSGERROR;
1570 case WODM_GETPLAYBACKRATE:
1571 FIXME("NIY: no conversion yet\n");
1572 ret = WINMM_MAP_MSGERROR;
1576 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1577 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1578 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1581 *(LPMMTIME*)ptr = mmt32;
1582 mmt16->wType = mmt32->wType;
1583 ret = WINMM_MAP_OKMEM;
1585 ret = WINMM_MAP_NOMEM;
1587 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1588 *lpParam2 = sizeof(MMTIME16);
1591 case WODM_GETVOLUME:
1592 FIXME("NIY: no conversion yet\n");
1593 ret = WINMM_MAP_MSGERROR;
1597 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1598 int sz = sizeof(WAVEFORMATEX);
1600 LPWAVEOPENDESC16 wod16;
1602 /* allocated data are mapped as follows:
1603 LPWAVEOPENDESC ptr to orig lParam1
1604 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1605 DWORD dwUser passed to driver
1606 WAVEOPENDESC16 wod16: openDesc passed to driver
1607 WAVEFORMATEX openDesc->lpFormat passed to driver
1608 xxx extra bytes to WAVEFORMATEX
1610 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1611 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1612 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1615 ptr = HeapAlloc( GetProcessHeap(), 0,
1616 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1619 SEGPTR seg_ptr = MapLS( ptr );
1620 *(LPWAVEOPENDESC*)ptr = wod32;
1621 *(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1622 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1624 wod16->hWave = HWAVE_16(wod32->hWave);
1625 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1626 memcpy(wod16 + 1, wod32->lpFormat, sz);
1628 wod16->dwCallback = wod32->dwCallback;
1629 wod16->dwInstance = wod32->dwInstance;
1630 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1631 wod16->dnDevNode = wod32->dnDevNode;
1633 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1634 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1636 ret = WINMM_MAP_OKMEM;
1638 ret = WINMM_MAP_NOMEM;
1644 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1646 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1647 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1650 SEGPTR seg_ptr = MapLS( ptr );
1651 *(LPWAVEHDR*)ptr = wh32;
1652 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1653 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1654 /* data will be copied on WODM_WRITE */
1655 wh16->dwBufferLength = wh32->dwBufferLength;
1656 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1657 wh16->dwUser = wh32->dwUser;
1658 wh16->dwFlags = wh32->dwFlags;
1659 wh16->dwLoops = wh32->dwLoops;
1660 /* FIXME: nothing on wh32->lpNext */
1661 /* could link the wh32->lpNext at this level for memory house keeping */
1662 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1663 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1664 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1665 wh32->dwBufferLength, (DWORD)wh32->lpData);
1666 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1667 *lpParam2 = sizeof(WAVEHDR);
1669 ret = WINMM_MAP_OKMEM;
1671 ret = WINMM_MAP_NOMEM;
1675 case WODM_UNPREPARE:
1678 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1679 LPWAVEHDR wh16 = wh32->lpNext;
1680 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1681 SEGPTR seg_ptr = MapLS( ptr );
1683 assert(*(LPWAVEHDR*)ptr == wh32);
1685 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1686 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1687 wh32->dwBufferLength, (DWORD)wh32->lpData);
1689 if (wMsg == WODM_WRITE)
1690 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1692 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1693 *lpParam2 = sizeof(WAVEHDR);
1694 /* dwBufferLength can be reduced between prepare & write */
1695 if (wMsg == WODM_WRITE && wh16->dwBufferLength < wh32->dwBufferLength) {
1696 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1697 wh16->dwBufferLength, wh32->dwBufferLength);
1699 wh16->dwBufferLength = wh32->dwBufferLength;
1700 ret = WINMM_MAP_OKMEM;
1703 case DRVM_MAPPER_STATUS:
1705 LPDWORD p32 = (LPDWORD)*lpParam2;
1706 *lpParam2 = MapLS(p32);
1707 ret = WINMM_MAP_OKMEM;
1711 FIXME("NIY: no conversion yet\n");
1712 ret = WINMM_MAP_MSGERROR;
1718 /**************************************************************************
1719 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1721 static WINMM_MapType MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1727 case WODM_BREAKLOOP:
1729 case WODM_GETNUMDEVS:
1734 case WODM_SETPLAYBACKRATE:
1735 case WODM_SETVOLUME:
1739 case WODM_GETDEVCAPS:
1741 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1742 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1743 LPWAVEOUTCAPSA woc32 = *(LPWAVEOUTCAPSA*)ptr;
1745 woc32->wMid = woc16->wMid;
1746 woc32->wPid = woc16->wPid;
1747 woc32->vDriverVersion = woc16->vDriverVersion;
1748 strcpy(woc32->szPname, woc16->szPname);
1749 woc32->dwFormats = woc16->dwFormats;
1750 woc32->wChannels = woc16->wChannels;
1751 woc32->dwSupport = woc16->dwSupport;
1752 UnMapLS( *lpParam1 );
1753 HeapFree( GetProcessHeap(), 0, ptr );
1758 FIXME("NIY: no conversion yet\n");
1759 ret = WINMM_MAP_MSGERROR;
1761 case WODM_GETPLAYBACKRATE:
1762 FIXME("NIY: no conversion yet\n");
1763 ret = WINMM_MAP_MSGERROR;
1767 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1768 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1769 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1771 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1772 UnMapLS( *lpParam1 );
1773 HeapFree( GetProcessHeap(), 0, ptr );
1779 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1780 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1781 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1783 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1784 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1785 UnMapLS( *lpParam1 );
1786 HeapFree( GetProcessHeap(), 0, ptr );
1791 case WODM_UNPREPARE:
1794 LPWAVEHDR wh16 = MapSL(*lpParam1);
1795 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1796 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1798 assert(wh32->lpNext == wh16);
1799 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1800 wh32->dwUser = wh16->dwUser;
1801 wh32->dwFlags = wh16->dwFlags;
1802 wh32->dwLoops = wh16->dwLoops;
1804 UnMapLS( *lpParam1 );
1805 if (wMsg == WODM_UNPREPARE) {
1806 HeapFree( GetProcessHeap(), 0, ptr );
1812 case WODM_GETVOLUME:
1813 FIXME("NIY: no conversion yet\n");
1814 ret = WINMM_MAP_MSGERROR;
1816 case DRVM_MAPPER_STATUS:
1818 UnMapLS( *lpParam2 );
1823 FIXME("NIY: no conversion yet\n");
1824 ret = WINMM_MAP_MSGERROR;
1830 /**************************************************************************
1831 * MMDRV_WaveOut_Callback [internal]
1833 static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1835 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1840 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1843 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1844 /* initial map is: 32 => 16 */
1845 LPWAVEHDR wh16 = MapSL(dwParam1);
1846 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1848 dwParam1 = (DWORD)wh32;
1849 wh32->dwFlags = wh16->dwFlags;
1850 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1851 /* initial map is: 16 => 32 */
1852 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1853 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1854 LPWAVEHDR wh16 = MapSL(segwh16);
1856 dwParam1 = (DWORD)segwh16;
1857 wh16->dwFlags = wh32->dwFlags;
1859 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1862 ERR("Unknown msg %u\n", uMsg);
1865 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1868 #define A(_x,_y) {#_y, _x, \
1869 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1870 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1871 MMDRV_##_y##_Callback, 0, NULL, -1}
1873 /* Note: the indices of this array must match the definitions
1874 * of the MMDRV_???? manifest constants
1876 static WINE_LLTYPE llTypes[MMDRV_MAX] = {
1886 /**************************************************************************
1887 * MMDRV_GetNum [internal]
1889 UINT MMDRV_GetNum(UINT type)
1891 assert(type < MMDRV_MAX);
1892 return llTypes[type].wMaxId;
1895 /**************************************************************************
1896 * WINE_Message [internal]
1898 DWORD MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1,
1899 DWORD dwParam2, BOOL bFrom32)
1901 LPWINE_MM_DRIVER lpDrv;
1903 WINE_MM_DRIVER_PART* part;
1904 WINE_LLTYPE* llType = &llTypes[mld->type];
1908 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1909 llTypes[mld->type].typestr, mld->uDeviceID, wMsg,
1910 mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
1912 if (mld->uDeviceID == (UINT16)-1) {
1913 if (!llType->bSupportMapper) {
1914 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1915 llTypes[mld->type].typestr);
1916 return MMSYSERR_BADDEVICEID;
1920 if (mld->uDeviceID >= llType->wMaxId) {
1921 WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
1922 return MMSYSERR_BADDEVICEID;
1924 devID = mld->uDeviceID;
1927 lpDrv = &MMDrvs[mld->mmdIndex];
1928 part = &lpDrv->parts[mld->type];
1931 /* some sanity checks */
1932 if (!(part->nIDMin <= devID))
1933 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
1934 if (!(devID < part->nIDMax))
1935 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
1939 assert(part->u.fnMessage32);
1942 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1943 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1944 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1945 TRACE("=> %lu\n", ret);
1947 map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1949 case WINMM_MAP_NOMEM:
1950 ret = MMSYSERR_NOMEM;
1952 case WINMM_MAP_MSGERROR:
1953 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
1954 ret = MMSYSERR_ERROR;
1957 case WINMM_MAP_OKMEM:
1958 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1959 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1960 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance,
1961 dwParam1, dwParam2);
1962 TRACE("=> %lu\n", ret);
1963 if (map == WINMM_MAP_OKMEM)
1964 llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1968 ret = MMSYSERR_NOTSUPPORTED;
1973 assert(part->u.fnMessage16);
1976 map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1978 case WINMM_MAP_NOMEM:
1979 ret = MMSYSERR_NOMEM;
1981 case WINMM_MAP_MSGERROR:
1982 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
1983 ret = MMSYSERR_ERROR;
1986 case WINMM_MAP_OKMEM:
1987 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1988 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1989 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1990 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1991 TRACE("=> %lu\n", ret);
1992 if (map == WINMM_MAP_OKMEM)
1993 llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1997 ret = MMSYSERR_NOTSUPPORTED;
2001 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2002 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2003 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
2004 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2005 TRACE("=> %lu\n", ret);
2011 /**************************************************************************
2012 * MMDRV_Alloc [internal]
2014 LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
2015 DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
2019 mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2020 if (!mld) return NULL;
2022 /* find an empty slot in MM_MLDrvs table */
2023 for (*hndl = 0; *hndl < MAX_MM_MLDRVS; (*hndl)++) {
2024 if (!MM_MLDrvs[(UINT)*hndl]) break;
2026 if (*hndl == MAX_MM_MLDRVS) {
2027 /* the MM_MLDrvs table could be made growable in the future if needed */
2028 ERR("Too many open drivers\n");
2031 MM_MLDrvs[(UINT)*hndl] = mld;
2032 *hndl = (HANDLE)((UINT)*hndl | 0x8000);
2035 if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
2036 /* FIXME: those conditions must be fulfilled so that:
2037 * - we can distinguish between device IDs and handles
2038 * - we can use handles as 16 or 32 bit entities
2040 ERR("Shouldn't happen. Bad allocation scheme\n");
2043 mld->bFrom32 = bFrom32;
2044 mld->dwFlags = HIWORD(*dwFlags);
2045 mld->dwCallback = *dwCallback;
2046 mld->dwClientInstance = *dwInstance;
2048 *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
2049 *dwCallback = (DWORD)llTypes[type].Callback;
2050 *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2055 /**************************************************************************
2056 * MMDRV_Free [internal]
2058 void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
2060 if ((UINT)hndl & 0x8000) {
2061 unsigned idx = (UINT)hndl & ~0x8000;
2062 if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2063 MM_MLDrvs[idx] = NULL;
2064 HeapFree(GetProcessHeap(), 0, mld);
2068 ERR("Bad Handle %08x at %p (not freed)\n", hndl, mld);
2071 /**************************************************************************
2072 * MMDRV_Open [internal]
2074 DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
2076 DWORD dwRet = MMSYSERR_BADDEVICEID;
2078 WINE_LLTYPE* llType = &llTypes[mld->type];
2080 mld->dwDriverInstance = (DWORD)&dwInstance;
2082 if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
2083 TRACE("MAPPER mode requested !\n");
2084 /* check if mapper is supported by type */
2085 if (llType->bSupportMapper) {
2086 if (llType->nMapper == -1) {
2087 /* no driver for mapper has been loaded, try a dumb implementation */
2088 TRACE("No mapper loaded, doing it by hand\n");
2089 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
2090 if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
2091 /* to share this function epilog */
2092 dwInstance = mld->dwDriverInstance;
2097 mld->uDeviceID = (UINT16)-1;
2098 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
2099 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2100 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2104 if (mld->uDeviceID < llType->wMaxId) {
2105 mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
2106 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2107 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2110 if (dwRet == MMSYSERR_NOERROR)
2111 mld->dwDriverInstance = dwInstance;
2115 /**************************************************************************
2116 * MMDRV_Close [internal]
2118 DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
2120 return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
2123 /**************************************************************************
2124 * MMDRV_GetByID [internal]
2126 LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
2128 if (uDevID < llTypes[type].wMaxId)
2129 return &llTypes[type].lpMlds[uDevID];
2130 if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
2131 return &llTypes[type].lpMlds[-1];
2135 /**************************************************************************
2136 * MMDRV_Get [internal]
2138 LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
2140 LPWINE_MLD mld = NULL;
2142 assert(type < MMDRV_MAX);
2144 if ((UINT)hndl >= llTypes[type].wMaxId &&
2145 hndl != (UINT16)-1 && hndl != (UINT)-1) {
2146 if ((UINT)hndl & 0x8000) {
2147 hndl = (HANDLE)((UINT)hndl & ~0x8000);
2148 if (hndl < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2149 mld = MM_MLDrvs[(UINT)hndl];
2150 if (!mld || !HeapValidate(GetProcessHeap(), 0, mld) || mld->type != type)
2153 hndl = (HANDLE)((UINT)hndl | 0x8000);
2156 if (mld == NULL && bCanBeID) {
2157 mld = MMDRV_GetByID((UINT)hndl, type);
2162 /**************************************************************************
2163 * MMDRV_GetRelated [internal]
2165 LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
2166 BOOL bSrcCanBeID, UINT dstType)
2170 if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
2171 WINE_MM_DRIVER_PART* part = &MMDrvs[mld->mmdIndex].parts[dstType];
2172 if (part->nIDMin < part->nIDMax)
2173 return MMDRV_GetByID(part->nIDMin, dstType);
2178 /**************************************************************************
2179 * MMDRV_PhysicalFeatures [internal]
2181 UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
2184 WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
2186 TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
2188 /* all those function calls are undocumented */
2190 case DRV_QUERYDRVENTRY:
2191 lstrcpynA((LPSTR)dwParam1, lpDrv->drvname, LOWORD(dwParam2));
2193 case DRV_QUERYDEVNODE:
2194 *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
2197 WARN("NIY QueryName\n");
2199 case DRV_QUERYDRIVERIDS:
2200 WARN("NIY call VxD\n");
2201 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2202 * dwParam1 is buffer and dwParam2 is sizeof buffer
2203 * I don't know where the result is stored though
2206 case DRV_QUERYMAPPABLE:
2207 return (lpDrv->bIsMapper) ? 2 : 0;
2209 case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
2210 return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
2213 WARN("Unknown call %04x\n", uMsg);
2214 return MMSYSERR_INVALPARAM;
2219 /**************************************************************************
2220 * MMDRV_InitPerType [internal]
2222 static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT type, UINT wMsg)
2224 WINE_MM_DRIVER_PART* part = &lpDrv->parts[type];
2229 part->nIDMin = part->nIDMax = 0;
2231 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2232 /* the DRVM_ENABLE is only required when the PnP node is non zero */
2234 if (lpDrv->bIs32 && part->u.fnMessage32) {
2235 ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
2236 TRACE("DRVM_INIT => %08lx\n", ret);
2238 ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
2239 TRACE("DRVM_ENABLE => %08lx\n", ret);
2241 count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
2242 } else if (!lpDrv->bIs32 && part->u.fnMessage16) {
2243 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2244 0, DRVM_INIT, 0L, 0L, 0L);
2245 TRACE("DRVM_INIT => %08lx\n", ret);
2247 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2248 0, DRVM_ENABLE, 0L, 0L, 0L);
2249 TRACE("DRVM_ENABLE => %08lx\n", ret);
2251 count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2252 0, wMsg, 0L, 0L, 0L);
2257 TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->drvname, llTypes[type].typestr);
2259 /* got some drivers */
2260 if (lpDrv->bIsMapper) {
2261 /* it seems native mappers return 0 devices :-( */
2262 if (llTypes[type].nMapper != -1)
2263 ERR("Two mappers for type %s (%d, %s)\n",
2264 llTypes[type].typestr, llTypes[type].nMapper, lpDrv->drvname);
2266 ERR("Strange: mapper with %d > 1 devices\n", count);
2267 llTypes[type].nMapper = MMDrvsHi;
2271 part->nIDMin = llTypes[type].wMaxId;
2272 llTypes[type].wMaxId += count;
2273 part->nIDMax = llTypes[type].wMaxId;
2275 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2276 part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
2277 lpDrv->drvname, llTypes[type].typestr);
2278 /* realloc translation table */
2279 llTypes[type].lpMlds = (LPWINE_MLD)
2280 HeapReAlloc(GetProcessHeap(), 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
2281 sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
2282 /* re-build the translation table */
2283 if (llTypes[type].nMapper != -1) {
2284 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, -1, MMDrvs[llTypes[type].nMapper].drvname);
2285 llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
2286 llTypes[type].lpMlds[-1].type = type;
2287 llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
2288 llTypes[type].lpMlds[-1].dwDriverInstance = 0;
2290 for (i = k = 0; i <= MMDrvsHi; i++) {
2291 while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
2292 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, k, MMDrvs[i].drvname);
2293 llTypes[type].lpMlds[k].uDeviceID = k;
2294 llTypes[type].lpMlds[k].type = type;
2295 llTypes[type].lpMlds[k].mmdIndex = i;
2296 llTypes[type].lpMlds[k].dwDriverInstance = 0;
2303 /**************************************************************************
2304 * MMDRV_Install [internal]
2306 static BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
2310 LPWINE_MM_DRIVER lpDrv = &MMDrvs[MMDrvsHi];
2313 TRACE("('%s', '%s', mapper=%c);\n", drvRegName, drvFileName, bIsMapper ? 'Y' : 'N');
2315 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2316 * if not just increase size of MMDrvs */
2317 assert(MMDrvsHi <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
2319 for (i = 0; i < MMDrvsHi; i++) {
2320 if (!strcmp(drvRegName, MMDrvs[i].drvname)) return FALSE;
2323 memset(lpDrv, 0, sizeof(*lpDrv));
2325 if (!(lpDrv->hDriver = OpenDriverA(drvFileName, 0, 0))) {
2326 WARN("Couldn't open driver '%s'\n", drvFileName);
2330 d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
2331 lpDrv->bIs32 = (d->dwFlags & WINE_GDF_16BIT) ? FALSE : TRUE;
2333 /* Then look for xxxMessage functions */
2334 #define AA(_h,_w,_x,_y,_z) \
2335 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
2337 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2338 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2341 WINEMM_msgFunc32 func;
2343 if (d->d.d32.hModule) {
2344 #define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
2345 A(MMDRV_AUX, auxMessage);
2346 A(MMDRV_MIXER, mixMessage);
2347 A(MMDRV_MIDIIN, midMessage);
2348 A(MMDRV_MIDIOUT, modMessage);
2349 A(MMDRV_WAVEIN, widMessage);
2350 A(MMDRV_WAVEOUT, wodMessage);
2354 WINEMM_msgFunc16 func;
2357 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2358 * The beginning of the module description indicates the driver supports
2359 * waveform, auxiliary, and mixer devices. Use one of the following
2360 * device-type names, followed by a colon (:) to indicate the type of
2361 * device your driver supports. If the driver supports more than one
2362 * type of device, separate each device-type name with a comma (,).
2364 * wave for waveform audio devices
2365 * wavemapper for wave mappers
2366 * midi for MIDI audio devices
2367 * midimapper for midi mappers
2368 * aux for auxiliary audio devices
2369 * mixer for mixer devices
2372 if (d->d.d16.hDriver16) {
2373 HMODULE16 hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
2375 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
2376 A(MMDRV_AUX, auxMessage);
2377 A(MMDRV_MIXER, mixMessage);
2378 A(MMDRV_MIDIIN, midMessage);
2379 A(MMDRV_MIDIOUT, modMessage);
2380 A(MMDRV_WAVEIN, widMessage);
2381 A(MMDRV_WAVEOUT, wodMessage);
2387 if (TRACE_ON(mmsys)) {
2388 if ((lpDrv->bIs32) ? MMDRV_GetDescription32(drvFileName, buffer, sizeof(buffer)) :
2389 MMDRV_GetDescription16(drvFileName, buffer, sizeof(buffer)))
2390 TRACE("%s => %s\n", drvFileName, buffer);
2392 TRACE("%s => No description\n", drvFileName);
2396 CloseDriver(lpDrv->hDriver, 0, 0);
2397 WARN("No message functions found\n");
2401 /* FIXME: being a mapper or not should be known by another way */
2402 /* it's known for NE drvs (the description is of the form '*mapper: *'
2403 * I don't have any clue for PE drvs
2405 lpDrv->bIsMapper = bIsMapper;
2406 lpDrv->drvname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(drvRegName) + 1), drvRegName);
2408 /* Finish init and get the count of the devices */
2409 MMDRV_InitPerType(lpDrv, MMDRV_AUX, AUXDM_GETNUMDEVS);
2410 MMDRV_InitPerType(lpDrv, MMDRV_MIXER, MXDM_GETNUMDEVS);
2411 MMDRV_InitPerType(lpDrv, MMDRV_MIDIIN, MIDM_GETNUMDEVS);
2412 MMDRV_InitPerType(lpDrv, MMDRV_MIDIOUT, MODM_GETNUMDEVS);
2413 MMDRV_InitPerType(lpDrv, MMDRV_WAVEIN, WIDM_GETNUMDEVS);
2414 MMDRV_InitPerType(lpDrv, MMDRV_WAVEOUT, WODM_GETNUMDEVS);
2415 /* FIXME: if all those func calls return FALSE,
2416 * then the driver must be unloaded
2424 /**************************************************************************
2425 * MMDRV_InitFromRegistry [internal]
2427 static BOOL MMDRV_InitFromRegistry(void)
2436 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\WinMM", &hKey)) {
2437 TRACE("Cannot open WinMM config key\n");
2441 size = sizeof(buffer);
2442 if (!RegQueryValueExA(hKey, "Drivers", 0, &type, (LPVOID)buffer, &size)) {
2445 p2 = strchr(p1, ';');
2446 if (p2) *p2++ = '\0';
2447 ret |= MMDRV_Install(p1, p1, FALSE);
2452 /* finish with mappers */
2453 size = sizeof(buffer);
2454 if (!RegQueryValueExA(hKey, "WaveMapper", 0, &type, (LPVOID)buffer, &size))
2455 ret |= MMDRV_Install("wavemapper", buffer, TRUE);
2456 size = sizeof(buffer);
2457 if (!RegQueryValueExA(hKey, "MidiMapper", 0, &type, (LPVOID)buffer, &size))
2458 ret |= MMDRV_Install("midimapper", buffer, TRUE);
2465 /**************************************************************************
2466 * MMDRV_InitHardcoded [internal]
2468 static BOOL MMDRV_InitHardcoded(void)
2470 /* first load hardware drivers */
2471 MMDRV_Install("wineoss.drv", "wineoss.drv", FALSE);
2473 /* finish with mappers */
2474 MMDRV_Install("wavemapper", "msacm.drv", TRUE);
2475 MMDRV_Install("midimapper", "midimap.drv", TRUE);
2480 /**************************************************************************
2481 * MMDRV_Init [internal]
2483 BOOL MMDRV_Init(void)
2485 /* FIXME: MMDRV_InitFromRegistry shall be MMDRV_Init in a near future */
2486 return MMDRV_InitFromRegistry() || MMDRV_InitHardcoded();