1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * MMSYTEM low level drivers handling functions
6 * Copyright 1999 Eric Pouech
12 #include "wine/winbase16.h"
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(mmsys);
20 typedef DWORD (CALLBACK *WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
21 typedef DWORD (CALLBACK *WINEMM_msgFunc32)(UINT , UINT, DWORD, DWORD, DWORD);
23 /* for each loaded driver and each known type of driver, this structure contains
24 * the information needed to access it
26 typedef struct tagWINE_MM_DRIVER_PART {
27 int nIDMin; /* lower bound of global indexes for this type */
28 int nIDMax; /* hhigher bound of global indexes for this type */
30 WINEMM_msgFunc32 fnMessage32; /* pointer to fonction */
31 WINEMM_msgFunc16 fnMessage16;
33 } WINE_MM_DRIVER_PART;
35 /* each low-level .drv will be associated with an instance of this structure */
36 typedef struct tagWINE_MM_DRIVER {
38 LPSTR drvname; /* name of the driver */
39 BOOL bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */
40 bIsMapper : 1; /* TRUE if mapper */
41 WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */
42 } WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
45 MMDRV_MAP_NOMEM, /* ko, memory problem */
46 MMDRV_MAP_MSGERROR, /* ko, unknown message */
47 MMDRV_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
48 MMDRV_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
49 MMDRV_MAP_PASS /* not handled (no memory allocated) to be sent to the driver */
52 typedef MMDRV_MapType (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
54 /* each known type of driver has an instance of this structure */
55 typedef struct tagWINE_LLTYPE {
56 /* those attributes depend on the specification of the type */
57 LPSTR typestr; /* name (for debugging) */
58 BOOL bSupportMapper; /* if type is allowed to support mapper */
59 MMDRV_MAPFUNC Map16To32A; /* those are function pointers to handle */
60 MMDRV_MAPFUNC UnMap16To32A; /* the parameter conversion (16 vs 32 bit) */
61 MMDRV_MAPFUNC Map32ATo16; /* when hi-func (in mmsystem or winmm) and */
62 MMDRV_MAPFUNC UnMap32ATo16; /* low-func (in .drv) do not match */
63 LPDRVCALLBACK Callback; /* handles callback for a specified type */
64 /* those attributes reflect the loaded/current situation for the type */
65 UINT wMaxId; /* number of loaded devices (sum across all loaded drivers */
66 LPWINE_MLD lpMlds; /* "static" mlds to access the part though device IDs */
67 int nMapper; /* index to mapper */
70 static int MMDrvsHi /* = 0 */;
71 static WINE_MM_DRIVER MMDrvs[3];
72 static LPWINE_MLD MM_MLDrvs[40];
73 #define MAX_MM_MLDRVS (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
75 /* ### start build ### */
76 extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
77 /* ### stop build ### */
79 /**************************************************************************
80 * MMDRV_GetDescription16 [internal]
82 static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
90 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
91 ERR("Can't open file %s (builtin driver ?)\n", fname);
95 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
97 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
98 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
99 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
100 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
101 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
102 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
103 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %lu\n", dw));
104 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
105 buflen = min((BYTE)buf[0], buflen - 1);
106 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
109 TRACE("Got '%s' [%d]\n", buf, buflen);
115 /**************************************************************************
116 * MMDRV_GetDescription32 [internal]
118 static BOOL MMDRV_GetDescription32(const char* fname, char* buf, int buflen)
127 FARPROC pGetFileVersionInfoSizeA;
128 FARPROC pGetFileVersionInfoA;
129 FARPROC pVerQueryValueA;
132 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
134 if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR) E(("Can't find file %s\n", fname));
136 if (!(hmodule = LoadLibraryA( "version.dll" ))) goto theEnd;
137 if (!(pGetFileVersionInfoSizeA = GetProcAddress( hmodule, "GetFileVersionInfoSizeA" )))
139 if (!(pGetFileVersionInfoA = GetProcAddress( hmodule, "GetFileVersionInfoA" )))
141 if (!(pVerQueryValueA = GetProcAddress( hmodule, "pVerQueryValueA" )))
144 if (!(dw = pGetFileVersionInfoSizeA(ofs.szPathName, &h))) E(("Can't get FVIS\n"));
145 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw))) E(("OOM\n"));
146 if (!pGetFileVersionInfoA(ofs.szPathName, h, dw, ptr)) E(("Can't get FVI\n"));
148 #define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
149 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
165 if (!pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
166 lstrcpynA(buf, val, buflen);
171 HeapFree(GetProcessHeap(), 0, ptr);
172 if (hmodule) FreeLibrary( hmodule );
176 /**************************************************************************
177 * MMDRV_Callback [internal]
179 static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
181 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
182 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
184 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
185 /* 16 bit func, call it */
186 TRACE("Function (16 bit) !\n");
187 MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, hDev, uMsg,
188 mld->dwClientInstance, dwParam1, dwParam2);
190 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
191 mld->dwClientInstance, dwParam1, dwParam2);
195 /* =================================
196 * A U X M A P P E R S
197 * ================================= */
199 /**************************************************************************
200 * MMDRV_Aux_Map16To32A [internal]
202 static MMDRV_MapType MMDRV_Aux_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
204 return MMDRV_MAP_MSGERROR;
207 /**************************************************************************
208 * MMDRV_Aux_UnMap16To32A [internal]
210 static MMDRV_MapType MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
212 return MMDRV_MAP_MSGERROR;
215 /**************************************************************************
216 * MMDRV_Aux_Map32ATo16 [internal]
218 static MMDRV_MapType MMDRV_Aux_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
220 return MMDRV_MAP_MSGERROR;
223 /**************************************************************************
224 * MMDRV_Aux_UnMap32ATo16 [internal]
226 static MMDRV_MapType MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
229 case AUXDM_GETDEVCAPS:
230 lpCaps->wMid = ac16.wMid;
231 lpCaps->wPid = ac16.wPid;
232 lpCaps->vDriverVersion = ac16.vDriverVersion;
233 strcpy(lpCaps->szPname, ac16.szPname);
234 lpCaps->wTechnology = ac16.wTechnology;
235 lpCaps->dwSupport = ac16.dwSupport;
237 return MMDRV_MAP_MSGERROR;
240 /**************************************************************************
241 * MMDRV_Aux_Callback [internal]
243 static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
245 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
248 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
251 /* =================================
252 * M I X E R M A P P E R S
253 * ================================= */
255 /**************************************************************************
256 * xMMDRV_Mixer_Map16To32A [internal]
258 static MMDRV_MapType MMDRV_Mixer_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
260 return MMDRV_MAP_MSGERROR;
263 /**************************************************************************
264 * MMDRV_Mixer_UnMap16To32A [internal]
266 static MMDRV_MapType MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
270 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
272 if (ret == MMSYSERR_NOERROR) {
273 mixcaps->wMid = micA.wMid;
274 mixcaps->wPid = micA.wPid;
275 mixcaps->vDriverVersion = micA.vDriverVersion;
276 strcpy(mixcaps->szPname, micA.szPname);
277 mixcaps->fdwSupport = micA.fdwSupport;
278 mixcaps->cDestinations = micA.cDestinations;
282 return MMDRV_MAP_MSGERROR;
285 /**************************************************************************
286 * MMDRV_Mixer_Map32ATo16 [internal]
288 static MMDRV_MapType MMDRV_Mixer_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
290 return MMDRV_MAP_MSGERROR;
293 /**************************************************************************
294 * MMDRV_Mixer_UnMap32ATo16 [internal]
296 static MMDRV_MapType MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
298 return MMDRV_MAP_MSGERROR;
301 /**************************************************************************
302 * MMDRV_Mixer_Callback [internal]
304 static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
306 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
309 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
312 /* =================================
313 * M I D I I N M A P P E R S
314 * ================================= */
316 /**************************************************************************
317 * MMDRV_MidiIn_Map16To32A [internal]
319 static MMDRV_MapType MMDRV_MidiIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
321 return MMDRV_MAP_MSGERROR;
324 /**************************************************************************
325 * MMDRV_MidiIn_UnMap16To32A [internal]
327 static MMDRV_MapType MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
329 return MMDRV_MAP_MSGERROR;
332 /**************************************************************************
333 * MMDRV_MidiIn_Map32ATo16 [internal]
335 static MMDRV_MapType MMDRV_MidiIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
337 return MMDRV_MAP_MSGERROR;
340 /**************************************************************************
341 * MMDRV_MidiIn_UnMap32ATo16 [internal]
343 static MMDRV_MapType MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
345 return MMDRV_MAP_MSGERROR;
348 /**************************************************************************
349 * MMDRV_MidiIn_Callback [internal]
351 static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
353 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
358 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
363 /* dwParam1 & dwParam2 are are data, nothing to do */
367 /* dwParam1 points to a MidiHdr, work to be done !!! */
368 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
369 /* initial map is: 32 => 16 */
370 LPMIDIHDR mh16 = MapSL(dwParam1);
371 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
373 dwParam1 = (DWORD)mh32;
374 mh32->dwFlags = mh16->dwFlags;
375 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
376 if (mh32->reserved >= sizeof(MIDIHDR))
377 mh32->dwOffset = mh16->dwOffset;
378 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
379 /* initial map is: 16 => 32 */
380 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
381 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
382 LPMIDIHDR mh16 = MapSL(segmh16);
384 dwParam1 = (DWORD)segmh16;
385 mh16->dwFlags = mh32->dwFlags;
386 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
387 if (mh16->reserved >= sizeof(MIDIHDR))
388 mh16->dwOffset = mh32->dwOffset;
390 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
392 /* case MOM_POSITIONCB: */
394 ERR("Unknown msg %u\n", uMsg);
397 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
400 /* =================================
401 * M I D I O U T M A P P E R S
402 * ================================= */
404 /**************************************************************************
405 * MMDRV_MidiOut_Map16To32A [internal]
407 static MMDRV_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
409 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
412 case MODM_GETNUMDEVS:
422 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
425 case MODM_GETDEVCAPS:
427 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
428 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
431 *(LPMIDIOUTCAPS16*)moc32 = moc16;
432 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
433 *lpParam1 = (DWORD)moc32;
434 *lpParam2 = sizeof(MIDIOUTCAPSA);
436 ret = MMDRV_MAP_OKMEM;
438 ret = MMDRV_MAP_NOMEM;
444 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
445 LPMIDIHDR mh16 = MapSL(*lpParam1);
448 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
449 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
450 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
451 mh32->dwBufferLength = mh16->dwBufferLength;
452 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
453 mh32->dwUser = mh16->dwUser;
454 mh32->dwFlags = mh16->dwFlags;
455 /* FIXME: nothing on mh32->lpNext */
456 /* could link the mh32->lpNext at this level for memory house keeping */
457 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
458 mh16->lpNext = mh32; /* for reuse in unprepare and write */
459 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
460 mh16->reserved = *lpParam2;
461 *lpParam1 = (DWORD)mh32;
462 *lpParam2 = sizeof(MIDIHDR);
464 ret = MMDRV_MAP_OKMEM;
466 ret = MMDRV_MAP_NOMEM;
473 LPMIDIHDR mh16 = MapSL(*lpParam1);
474 LPMIDIHDR mh32 = (LPMIDIHDR)mh16->lpNext;
476 *lpParam1 = (DWORD)mh32;
477 *lpParam2 = sizeof(MIDIHDR);
478 /* dwBufferLength can be reduced between prepare & write */
479 if (mh32->dwBufferLength < mh16->dwBufferLength) {
480 ERR("Size of buffer has been increased (%ld, %ld)\n",
481 mh32->dwBufferLength, mh16->dwBufferLength);
482 return MMDRV_MAP_MSGERROR;
484 mh32->dwBufferLength = mh16->dwBufferLength;
485 ret = MMDRV_MAP_OKMEM;
489 case MODM_CACHEPATCHES:
490 case MODM_CACHEDRUMPATCHES:
492 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
498 /**************************************************************************
499 * MMDRV_MidiOut_UnMap16To32A [internal]
501 static MMDRV_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
503 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
506 case MODM_GETNUMDEVS:
516 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
519 case MODM_GETDEVCAPS:
521 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
522 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
524 moc16->wMid = moc32->wMid;
525 moc16->wPid = moc32->wPid;
526 moc16->vDriverVersion = moc32->vDriverVersion;
527 strcpy(moc16->szPname, moc32->szPname);
528 moc16->wTechnology = moc32->wTechnology;
529 moc16->wVoices = moc32->wVoices;
530 moc16->wNotes = moc32->wNotes;
531 moc16->wChannelMask = moc32->wChannelMask;
532 moc16->dwSupport = moc32->dwSupport;
533 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
541 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
542 LPMIDIHDR mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
544 assert(mh16->lpNext == mh32);
545 mh16->dwBufferLength = mh32->dwBufferLength;
546 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
547 mh16->dwUser = mh32->dwUser;
548 mh16->dwFlags = mh32->dwFlags;
549 if (mh16->reserved >= sizeof(MIDIHDR))
550 mh16->dwOffset = mh32->dwOffset;
552 if (wMsg == MODM_UNPREPARE) {
553 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
560 case MODM_CACHEPATCHES:
561 case MODM_CACHEDRUMPATCHES:
563 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
569 /**************************************************************************
570 * MMDRV_MidiOut_Map32ATo16 [internal]
572 static MMDRV_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
574 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
578 case MODM_GETNUMDEVS:
584 case MODM_GETDEVCAPS:
586 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
587 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA)+sizeof(MIDIOUTCAPS16));
590 *(LPMIDIOUTCAPSA*)ptr = moc32;
591 ret = MMDRV_MAP_OKMEM;
593 ret = MMDRV_MAP_NOMEM;
595 *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSA);
596 *lpParam2 = sizeof(MIDIOUTCAPS16);
601 LPMIDIHDR mh32 = (LPMIDIHDR)*lpParam1;
603 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
604 sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
607 *(LPMIDIHDR*)ptr = mh32;
608 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
609 *lpParam1 = MapLS(mh16);
610 mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
611 /* data will be copied on WODM_WRITE */
612 mh16->dwBufferLength = mh32->dwBufferLength;
613 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
614 mh16->dwUser = mh32->dwUser;
615 mh16->dwFlags = mh32->dwFlags;
616 /* FIXME: nothing on mh32->lpNext */
617 /* could link the mh32->lpNext at this level for memory house keeping */
618 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
620 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
621 mh32->reserved = *lpParam2;
623 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
624 *lpParam1, (DWORD)mh16->lpData,
625 mh32->dwBufferLength, (DWORD)mh32->lpData);
626 *lpParam2 = sizeof(MIDIHDR);
628 ret = MMDRV_MAP_OKMEM;
630 ret = MMDRV_MAP_NOMEM;
637 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
638 LPMIDIHDR mh16 = (LPMIDIHDR)mh32->lpNext;
639 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
641 assert(*(LPMIDIHDR*)ptr == mh32);
643 if (wMsg == MODM_LONGDATA)
644 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
646 *lpParam1 = MapLS(mh16);
647 *lpParam2 = sizeof(MIDIHDR);
648 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
649 *lpParam1, (DWORD)mh16->lpData, mh32->dwBufferLength, (DWORD)mh32->lpData);
651 /* dwBufferLength can be reduced between prepare & write */
652 if (mh16->dwBufferLength < mh32->dwBufferLength) {
653 ERR("Size of buffer has been increased (%ld, %ld)\n",
654 mh16->dwBufferLength, mh32->dwBufferLength);
655 return MMDRV_MAP_MSGERROR;
657 mh16->dwBufferLength = mh32->dwBufferLength;
658 ret = MMDRV_MAP_OKMEM;
663 LPMIDIOPENDESC mod32 = (LPMIDIOPENDESC)*lpParam1;
665 LPMIDIOPENDESC16 mod16;
667 /* allocated data are mapped as follows:
668 LPMIDIOPENDESC ptr to orig lParam1
669 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
670 DWORD dwUser passed to driver
671 MIDIOPENDESC16 mod16: openDesc passed to driver
674 ptr = HeapAlloc( GetProcessHeap(), 0,
675 sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
676 mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
679 SEGPTR segptr = MapLS(ptr);
680 *(LPMIDIOPENDESC*)ptr = mod32;
681 *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
682 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
684 mod16->hMidi = mod32->hMidi;
685 mod16->dwCallback = mod32->dwCallback;
686 mod16->dwInstance = mod32->dwInstance;
687 mod16->dnDevNode = mod32->dnDevNode;
688 mod16->cIds = mod32->cIds;
689 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
691 *lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
692 *lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
694 ret = MMDRV_MAP_OKMEM;
696 ret = MMDRV_MAP_NOMEM;
701 case MODM_CACHEPATCHES:
702 case MODM_CACHEDRUMPATCHES:
704 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
710 /**************************************************************************
711 * MMDRV_MidiOut_UnMap32ATo16 [internal]
713 static MMDRV_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
715 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
719 case MODM_GETNUMDEVS:
725 case MODM_GETDEVCAPS:
727 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
728 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
729 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
731 moc32->wMid = moc16->wMid;
732 moc32->wPid = moc16->wPid;
733 moc32->vDriverVersion = moc16->vDriverVersion;
734 strcpy(moc32->szPname, moc16->szPname);
735 moc32->wTechnology = moc16->wTechnology;
736 moc32->wVoices = moc16->wVoices;
737 moc32->wNotes = moc16->wNotes;
738 moc32->wChannelMask = moc16->wChannelMask;
739 moc32->dwSupport = moc16->dwSupport;
740 UnMapLS( *lpParam1 );
741 HeapFree( GetProcessHeap(), 0, ptr );
749 LPMIDIHDR mh16 = MapSL(*lpParam1);
750 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
751 LPMIDIHDR mh32 = *(LPMIDIHDR*)ptr;
753 assert(mh32->lpNext == (LPMIDIHDR)mh16);
754 UnMapLS( *lpParam1 );
755 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
756 mh32->dwUser = mh16->dwUser;
757 mh32->dwFlags = mh16->dwFlags;
759 if (wMsg == MODM_UNPREPARE) {
760 HeapFree( GetProcessHeap(), 0, ptr );
768 LPMIDIOPENDESC16 mod16 = MapSL(*lpParam1);
769 LPSTR ptr = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
770 UnMapLS( *lpParam1 );
771 **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
773 HeapFree( GetProcessHeap(), 0, ptr );
778 case MODM_CACHEPATCHES:
779 case MODM_CACHEDRUMPATCHES:
781 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
787 /**************************************************************************
788 * MMDRV_MidiOut_Callback [internal]
790 static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
792 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
797 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
800 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
801 /* initial map is: 32 => 16 */
802 LPMIDIHDR mh16 = MapSL(dwParam1);
803 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
805 dwParam1 = (DWORD)mh32;
806 mh32->dwFlags = mh16->dwFlags;
807 mh32->dwOffset = mh16->dwOffset;
808 if (mh32->reserved >= sizeof(MIDIHDR))
809 mh32->dwOffset = mh16->dwOffset;
810 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
811 /* initial map is: 16 => 32 */
812 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
813 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
814 LPMIDIHDR mh16 = MapSL(segmh16);
816 dwParam1 = (DWORD)segmh16;
817 mh16->dwFlags = mh32->dwFlags;
818 if (mh16->reserved >= sizeof(MIDIHDR))
819 mh16->dwOffset = mh32->dwOffset;
821 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
823 /* case MOM_POSITIONCB: */
825 ERR("Unknown msg %u\n", uMsg);
828 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
831 /* =================================
832 * W A V E I N M A P P E R S
833 * ================================= */
835 /**************************************************************************
836 * MMDRV_WaveIn_Map16To32A [internal]
838 static MMDRV_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
840 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
843 case WIDM_GETNUMDEVS:
851 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
853 case WIDM_GETDEVCAPS:
855 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
856 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
859 *(LPWAVEINCAPS16*)wic32 = wic16;
860 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
861 *lpParam1 = (DWORD)wic32;
862 *lpParam2 = sizeof(WAVEINCAPSA);
864 ret = MMDRV_MAP_OKMEM;
866 ret = MMDRV_MAP_NOMEM;
872 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
873 LPMMTIME16 mmt16 = MapSL(*lpParam1);
876 *(LPMMTIME16*)mmt32 = mmt16;
877 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
879 mmt32->wType = mmt16->wType;
880 *lpParam1 = (DWORD)mmt32;
881 *lpParam2 = sizeof(MMTIME);
883 ret = MMDRV_MAP_OKMEM;
885 ret = MMDRV_MAP_NOMEM;
891 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
892 LPWAVEHDR wh16 = MapSL(*lpParam1);
895 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
896 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
897 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
898 wh32->dwBufferLength = wh16->dwBufferLength;
899 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
900 wh32->dwUser = wh16->dwUser;
901 wh32->dwFlags = wh16->dwFlags;
902 wh32->dwLoops = wh16->dwLoops;
903 /* FIXME: nothing on wh32->lpNext */
904 /* could link the wh32->lpNext at this level for memory house keeping */
905 wh16->lpNext = wh32; /* for reuse in unprepare and write */
906 *lpParam1 = (DWORD)wh32;
907 *lpParam2 = sizeof(WAVEHDR);
909 ret = MMDRV_MAP_OKMEM;
911 ret = MMDRV_MAP_NOMEM;
918 LPWAVEHDR wh16 = MapSL(*lpParam1);
919 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
921 *lpParam1 = (DWORD)wh32;
922 *lpParam2 = sizeof(WAVEHDR);
923 /* dwBufferLength can be reduced between prepare & write */
924 if (wh32->dwBufferLength < wh16->dwBufferLength) {
925 ERR("Size of buffer has been increased (%ld, %ld)\n",
926 wh32->dwBufferLength, wh16->dwBufferLength);
927 return MMDRV_MAP_MSGERROR;
929 wh32->dwBufferLength = wh16->dwBufferLength;
930 ret = MMDRV_MAP_OKMEM;
933 case WIDM_MAPPER_STATUS:
934 /* just a single DWORD */
935 *lpParam2 = (DWORD)MapSL(*lpParam2);
939 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
945 /**************************************************************************
946 * MMDRV_WaveIn_UnMap16To32A [internal]
948 static MMDRV_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
950 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
953 case WIDM_GETNUMDEVS:
957 case WIDM_MAPPER_STATUS:
962 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
964 case WIDM_GETDEVCAPS:
966 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
967 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
969 wic16->wMid = wic32->wMid;
970 wic16->wPid = wic32->wPid;
971 wic16->vDriverVersion = wic32->vDriverVersion;
972 strcpy(wic16->szPname, wic32->szPname);
973 wic16->dwFormats = wic32->dwFormats;
974 wic16->wChannels = wic32->wChannels;
975 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
981 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
982 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
984 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
985 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
993 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
994 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
996 assert(wh16->lpNext == wh32);
997 wh16->dwBufferLength = wh32->dwBufferLength;
998 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
999 wh16->dwUser = wh32->dwUser;
1000 wh16->dwFlags = wh32->dwFlags;
1001 wh16->dwLoops = wh32->dwLoops;
1003 if (wMsg == WIDM_UNPREPARE) {
1004 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1011 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1017 /**************************************************************************
1018 * MMDRV_WaveIn_Map32ATo16 [internal]
1020 static MMDRV_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1022 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1026 case WIDM_GETNUMDEVS:
1035 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1036 int sz = sizeof(WAVEFORMATEX);
1038 LPWAVEOPENDESC16 wod16;
1040 /* allocated data are mapped as follows:
1041 LPWAVEOPENDESC ptr to orig lParam1
1042 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1043 DWORD dwUser passed to driver
1044 WAVEOPENDESC16 wod16: openDesc passed to driver
1045 WAVEFORMATEX openDesc->lpFormat passed to driver
1046 xxx extra bytes to WAVEFORMATEX
1048 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1049 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1050 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1053 ptr = HeapAlloc( GetProcessHeap(), 0,
1054 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1057 SEGPTR seg_ptr = MapLS( ptr );
1058 *(LPWAVEOPENDESC*)ptr = wod32;
1059 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1060 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1062 wod16->hWave = wod32->hWave;
1063 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1064 memcpy(wod16 + 1, wod32->lpFormat, sz);
1066 wod16->dwCallback = wod32->dwCallback;
1067 wod16->dwInstance = wod32->dwInstance;
1068 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1069 wod16->dnDevNode = wod32->dnDevNode;
1071 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1072 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1074 ret = MMDRV_MAP_OKMEM;
1076 ret = MMDRV_MAP_NOMEM;
1082 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1084 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1085 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1088 SEGPTR seg_ptr = MapLS( ptr );
1089 *(LPWAVEHDR*)ptr = wh32;
1090 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1091 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1092 /* data will be copied on WODM_WRITE */
1093 wh16->dwBufferLength = wh32->dwBufferLength;
1094 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1095 wh16->dwUser = wh32->dwUser;
1096 wh16->dwFlags = wh32->dwFlags;
1097 wh16->dwLoops = wh32->dwLoops;
1098 /* FIXME: nothing on wh32->lpNext */
1099 /* could link the wh32->lpNext at this level for memory house keeping */
1100 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1101 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1102 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1103 wh32->dwBufferLength, (DWORD)wh32->lpData);
1104 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1105 *lpParam2 = sizeof(WAVEHDR);
1107 ret = MMDRV_MAP_OKMEM;
1109 ret = MMDRV_MAP_NOMEM;
1113 case WIDM_ADDBUFFER:
1114 case WIDM_UNPREPARE:
1116 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1117 LPWAVEHDR wh16 = wh32->lpNext;
1118 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1119 SEGPTR seg_ptr = MapLS( ptr );
1121 assert(*(LPWAVEHDR*)ptr == wh32);
1123 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1124 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1125 wh32->dwBufferLength, (DWORD)wh32->lpData);
1127 if (wMsg == WIDM_ADDBUFFER)
1128 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1130 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1131 *lpParam2 = sizeof(WAVEHDR);
1132 /* dwBufferLength can be reduced between prepare & write */
1133 if (wh32->dwBufferLength < wh16->dwBufferLength) {
1134 ERR("Size of buffer has been increased (%ld, %ld)\n",
1135 wh32->dwBufferLength, wh16->dwBufferLength);
1136 return MMDRV_MAP_MSGERROR;
1138 wh32->dwBufferLength = wh16->dwBufferLength;
1139 ret = MMDRV_MAP_OKMEM;
1142 case WIDM_GETDEVCAPS:
1144 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
1145 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
1148 *(LPWAVEINCAPSA*)ptr = wic32;
1149 ret = MMDRV_MAP_OKMEM;
1151 ret = MMDRV_MAP_NOMEM;
1153 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSA);
1154 *lpParam2 = sizeof(WAVEINCAPS16);
1159 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1160 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1161 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1164 *(LPMMTIME*)ptr = mmt32;
1165 mmt16->wType = mmt32->wType;
1166 ret = MMDRV_MAP_OKMEM;
1168 ret = MMDRV_MAP_NOMEM;
1170 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1171 *lpParam2 = sizeof(MMTIME16);
1174 case DRVM_MAPPER_STATUS:
1176 LPDWORD p32 = (LPDWORD)*lpParam2;
1177 *lpParam2 = MapLS(p32);
1178 ret = MMDRV_MAP_OKMEM;
1182 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1188 /**************************************************************************
1189 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1191 static MMDRV_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1193 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1197 case WIDM_GETNUMDEVS:
1206 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1207 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1208 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1210 UnMapLS( *lpParam1 );
1211 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1212 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1213 HeapFree( GetProcessHeap(), 0, ptr );
1218 case WIDM_ADDBUFFER:
1220 case WIDM_UNPREPARE:
1222 LPWAVEHDR wh16 = MapSL(*lpParam1);
1223 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1224 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1226 assert(wh32->lpNext == wh16);
1227 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1228 wh32->dwUser = wh16->dwUser;
1229 wh32->dwFlags = wh16->dwFlags;
1230 wh32->dwLoops = wh16->dwLoops;
1231 UnMapLS( *lpParam1 );
1233 if (wMsg == WIDM_UNPREPARE) {
1234 HeapFree( GetProcessHeap(), 0, ptr );
1240 case WIDM_GETDEVCAPS:
1242 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
1243 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1244 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
1246 wic32->wMid = wic16->wMid;
1247 wic32->wPid = wic16->wPid;
1248 wic32->vDriverVersion = wic16->vDriverVersion;
1249 strcpy(wic32->szPname, wic16->szPname);
1250 wic32->dwFormats = wic16->dwFormats;
1251 wic32->wChannels = wic16->wChannels;
1252 UnMapLS( *lpParam1 );
1253 HeapFree( GetProcessHeap(), 0, ptr );
1259 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1260 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1261 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1263 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1264 UnMapLS( *lpParam1 );
1265 HeapFree( GetProcessHeap(), 0, ptr );
1269 case DRVM_MAPPER_STATUS:
1271 UnMapLS( *lpParam2 );
1276 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1282 /**************************************************************************
1283 * MMDRV_WaveIn_Callback [internal]
1285 static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1287 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1292 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1295 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1296 /* initial map is: 32 => 16 */
1297 LPWAVEHDR wh16 = MapSL(dwParam1);
1298 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1300 dwParam1 = (DWORD)wh32;
1301 wh32->dwFlags = wh16->dwFlags;
1302 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1303 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1304 /* initial map is: 16 => 32 */
1305 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1306 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1307 LPWAVEHDR wh16 = MapSL(segwh16);
1309 dwParam1 = (DWORD)segwh16;
1310 wh16->dwFlags = wh32->dwFlags;
1311 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1313 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1316 ERR("Unknown msg %u\n", uMsg);
1319 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1322 /* =================================
1323 * W A V E O U T M A P P E R S
1324 * ================================= */
1326 /**************************************************************************
1327 * MMDRV_WaveOut_Map16To32A [internal]
1329 static MMDRV_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1331 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1335 case WODM_BREAKLOOP:
1337 case WODM_GETNUMDEVS:
1342 case WODM_SETPLAYBACKRATE:
1343 case WODM_SETVOLUME:
1348 case WODM_GETPLAYBACKRATE:
1349 case WODM_GETVOLUME:
1351 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1354 case WODM_GETDEVCAPS:
1356 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1357 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1360 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1361 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1362 *lpParam1 = (DWORD)woc32;
1363 *lpParam2 = sizeof(WAVEOUTCAPSA);
1365 ret = MMDRV_MAP_OKMEM;
1367 ret = MMDRV_MAP_NOMEM;
1373 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1374 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1377 *(LPMMTIME16*)mmt32 = mmt16;
1378 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1380 mmt32->wType = mmt16->wType;
1381 *lpParam1 = (DWORD)mmt32;
1382 *lpParam2 = sizeof(MMTIME);
1384 ret = MMDRV_MAP_OKMEM;
1386 ret = MMDRV_MAP_NOMEM;
1392 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1393 LPWAVEHDR wh16 = MapSL(*lpParam1);
1396 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1397 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1398 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1399 wh32->dwBufferLength = wh16->dwBufferLength;
1400 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1401 wh32->dwUser = wh16->dwUser;
1402 wh32->dwFlags = wh16->dwFlags;
1403 wh32->dwLoops = wh16->dwLoops;
1404 /* FIXME: nothing on wh32->lpNext */
1405 /* could link the wh32->lpNext at this level for memory house keeping */
1406 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1407 *lpParam1 = (DWORD)wh32;
1408 *lpParam2 = sizeof(WAVEHDR);
1410 ret = MMDRV_MAP_OKMEM;
1412 ret = MMDRV_MAP_NOMEM;
1416 case WODM_UNPREPARE:
1419 LPWAVEHDR wh16 = MapSL(*lpParam1);
1420 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1422 *lpParam1 = (DWORD)wh32;
1423 *lpParam2 = sizeof(WAVEHDR);
1424 /* dwBufferLength can be reduced between prepare & write */
1425 if (wh32->dwBufferLength < wh16->dwBufferLength) {
1426 ERR("Size of buffer has been increased (%ld, %ld)\n",
1427 wh32->dwBufferLength, wh16->dwBufferLength);
1428 return MMDRV_MAP_MSGERROR;
1430 wh32->dwBufferLength = wh16->dwBufferLength;
1431 ret = MMDRV_MAP_OKMEM;
1434 case WODM_MAPPER_STATUS:
1435 *lpParam2 = (DWORD)MapSL(*lpParam2);
1439 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1445 /**************************************************************************
1446 * MMDRV_WaveOut_UnMap16To32A [internal]
1448 static MMDRV_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1450 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1454 case WODM_BREAKLOOP:
1456 case WODM_GETNUMDEVS:
1461 case WODM_SETPLAYBACKRATE:
1462 case WODM_SETVOLUME:
1463 case WODM_MAPPER_STATUS:
1468 case WODM_GETPLAYBACKRATE:
1469 case WODM_GETVOLUME:
1471 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1474 case WODM_GETDEVCAPS:
1476 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1477 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1479 woc16->wMid = woc32->wMid;
1480 woc16->wPid = woc32->wPid;
1481 woc16->vDriverVersion = woc32->vDriverVersion;
1482 strcpy(woc16->szPname, woc32->szPname);
1483 woc16->dwFormats = woc32->dwFormats;
1484 woc16->wChannels = woc32->wChannels;
1485 woc16->dwSupport = woc32->dwSupport;
1486 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1492 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1493 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1495 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1496 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1501 case WODM_UNPREPARE:
1504 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1505 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1507 assert(wh16->lpNext == wh32);
1508 wh16->dwBufferLength = wh32->dwBufferLength;
1509 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1510 wh16->dwUser = wh32->dwUser;
1511 wh16->dwFlags = wh32->dwFlags;
1512 wh16->dwLoops = wh32->dwLoops;
1514 if (wMsg == WODM_UNPREPARE) {
1515 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1522 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1528 /**************************************************************************
1529 * MMDRV_WaveOut_Map32ATo16 [internal]
1531 static MMDRV_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1537 case WODM_BREAKLOOP:
1539 case WODM_GETNUMDEVS:
1544 case WODM_SETPLAYBACKRATE:
1545 case WODM_SETVOLUME:
1549 case WODM_GETDEVCAPS:
1551 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1552 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
1553 sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1556 *(LPWAVEOUTCAPSA*)ptr = woc32;
1557 ret = MMDRV_MAP_OKMEM;
1559 ret = MMDRV_MAP_NOMEM;
1561 *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSA);
1562 *lpParam2 = sizeof(WAVEOUTCAPS16);
1566 FIXME("NIY: no conversion yet\n");
1567 ret = MMDRV_MAP_MSGERROR;
1569 case WODM_GETPLAYBACKRATE:
1570 FIXME("NIY: no conversion yet\n");
1571 ret = MMDRV_MAP_MSGERROR;
1575 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1576 LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
1577 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1580 *(LPMMTIME*)ptr = mmt32;
1581 mmt16->wType = mmt32->wType;
1582 ret = MMDRV_MAP_OKMEM;
1584 ret = MMDRV_MAP_NOMEM;
1586 *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
1587 *lpParam2 = sizeof(MMTIME16);
1590 case WODM_GETVOLUME:
1591 FIXME("NIY: no conversion yet\n");
1592 ret = MMDRV_MAP_MSGERROR;
1596 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1597 int sz = sizeof(WAVEFORMATEX);
1599 LPWAVEOPENDESC16 wod16;
1601 /* allocated data are mapped as follows:
1602 LPWAVEOPENDESC ptr to orig lParam1
1603 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1604 DWORD dwUser passed to driver
1605 WAVEOPENDESC16 wod16: openDesc passed to driver
1606 WAVEFORMATEX openDesc->lpFormat passed to driver
1607 xxx extra bytes to WAVEFORMATEX
1609 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1610 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1611 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1614 ptr = HeapAlloc( GetProcessHeap(), 0,
1615 sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1618 SEGPTR seg_ptr = MapLS( ptr );
1619 *(LPWAVEOPENDESC*)ptr = wod32;
1620 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1621 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1623 wod16->hWave = wod32->hWave;
1624 wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1625 memcpy(wod16 + 1, wod32->lpFormat, sz);
1627 wod16->dwCallback = wod32->dwCallback;
1628 wod16->dwInstance = wod32->dwInstance;
1629 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1630 wod16->dnDevNode = wod32->dnDevNode;
1632 *lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1633 *lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1635 ret = MMDRV_MAP_OKMEM;
1637 ret = MMDRV_MAP_NOMEM;
1643 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1645 LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
1646 sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1649 SEGPTR seg_ptr = MapLS( ptr );
1650 *(LPWAVEHDR*)ptr = wh32;
1651 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1652 wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1653 /* data will be copied on WODM_WRITE */
1654 wh16->dwBufferLength = wh32->dwBufferLength;
1655 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1656 wh16->dwUser = wh32->dwUser;
1657 wh16->dwFlags = wh32->dwFlags;
1658 wh16->dwLoops = wh32->dwLoops;
1659 /* FIXME: nothing on wh32->lpNext */
1660 /* could link the wh32->lpNext at this level for memory house keeping */
1661 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1662 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1663 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1664 wh32->dwBufferLength, (DWORD)wh32->lpData);
1665 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1666 *lpParam2 = sizeof(WAVEHDR);
1668 ret = MMDRV_MAP_OKMEM;
1670 ret = MMDRV_MAP_NOMEM;
1674 case WODM_UNPREPARE:
1677 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1678 LPWAVEHDR wh16 = wh32->lpNext;
1679 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1680 SEGPTR seg_ptr = MapLS( ptr );
1682 assert(*(LPWAVEHDR*)ptr == wh32);
1684 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1685 seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1686 wh32->dwBufferLength, (DWORD)wh32->lpData);
1688 if (wMsg == WODM_WRITE)
1689 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1691 *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
1692 *lpParam2 = sizeof(WAVEHDR);
1693 /* dwBufferLength can be reduced between prepare & write */
1694 if (wh16->dwBufferLength < wh32->dwBufferLength) {
1695 ERR("Size of buffer has been increased (%ld, %ld)\n",
1696 wh16->dwBufferLength, wh32->dwBufferLength);
1697 return MMDRV_MAP_MSGERROR;
1699 wh16->dwBufferLength = wh32->dwBufferLength;
1700 ret = MMDRV_MAP_OKMEM;
1703 case DRVM_MAPPER_STATUS:
1705 LPDWORD p32 = (LPDWORD)*lpParam2;
1706 *lpParam2 = MapLS(p32);
1707 ret = MMDRV_MAP_OKMEM;
1711 FIXME("NIY: no conversion yet\n");
1712 ret = MMDRV_MAP_MSGERROR;
1718 /**************************************************************************
1719 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1721 static MMDRV_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 = MMDRV_MAP_MSGERROR;
1761 case WODM_GETPLAYBACKRATE:
1762 FIXME("NIY: no conversion yet\n");
1763 ret = MMDRV_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 = MMDRV_MAP_MSGERROR;
1816 case DRVM_MAPPER_STATUS:
1818 UnMapLS( *lpParam2 );
1823 FIXME("NIY: no conversion yet\n");
1824 ret = MMDRV_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 MMDRV_MAP_NOMEM:
1950 ret = MMSYSERR_NOMEM;
1952 case MMDRV_MAP_MSGERROR:
1953 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
1954 ret = MMSYSERR_ERROR;
1957 case MMDRV_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 == MMDRV_MAP_OKMEM)
1964 llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1967 case MMDRV_MAP_PASS:
1968 FIXME("NIY: pass used ?\n");
1969 ret = MMSYSERR_NOTSUPPORTED;
1974 assert(part->u.fnMessage16);
1977 map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1979 case MMDRV_MAP_NOMEM:
1980 ret = MMSYSERR_NOMEM;
1982 case MMDRV_MAP_MSGERROR:
1983 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
1984 ret = MMSYSERR_ERROR;
1987 case MMDRV_MAP_OKMEM:
1988 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1989 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1990 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1991 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1992 TRACE("=> %lu\n", ret);
1993 if (map == MMDRV_MAP_OKMEM)
1994 llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1997 case MMDRV_MAP_PASS:
1998 FIXME("NIY: pass used ?\n");
1999 ret = MMSYSERR_NOTSUPPORTED;
2003 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2004 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2005 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
2006 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2007 TRACE("=> %lu\n", ret);
2013 /**************************************************************************
2014 * MMDRV_Alloc [internal]
2016 LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
2017 DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
2021 mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2022 if (!mld) return NULL;
2024 /* find an empty slot in MM_MLDrvs table */
2025 for (*hndl = 0; *hndl < MAX_MM_MLDRVS; (*hndl)++) {
2026 if (!MM_MLDrvs[*hndl]) break;
2028 if (*hndl == MAX_MM_MLDRVS) {
2029 /* the MM_MLDrvs table could be made growable in the future if needed */
2030 ERR("Too many open drivers\n");
2033 MM_MLDrvs[*hndl] = mld;
2037 if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
2038 /* FIXME: those conditions must be fulfilled so that:
2039 * - we can distinguish between device IDs and handles
2040 * - we can use handles as 16 or 32 bit entities
2042 ERR("Shouldn't happen. Bad allocation scheme\n");
2045 mld->bFrom32 = bFrom32;
2046 mld->dwFlags = HIWORD(*dwFlags);
2047 mld->dwCallback = *dwCallback;
2048 mld->dwClientInstance = *dwInstance;
2050 *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
2051 *dwCallback = (DWORD)llTypes[type].Callback;
2052 *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2057 /**************************************************************************
2058 * MMDRV_Free [internal]
2060 void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
2062 if (hndl & 0x8000) {
2063 unsigned idx = hndl & ~0x8000;
2064 if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2065 MM_MLDrvs[idx] = NULL;
2066 HeapFree(GetProcessHeap(), 0, mld);
2070 ERR("Bad Handle %08x at %p (not freed)\n", hndl, mld);
2073 /**************************************************************************
2074 * MMDRV_Open [internal]
2076 DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
2078 DWORD dwRet = MMSYSERR_BADDEVICEID;
2080 WINE_LLTYPE* llType = &llTypes[mld->type];
2082 mld->dwDriverInstance = (DWORD)&dwInstance;
2084 if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
2085 TRACE("MAPPER mode requested !\n");
2086 /* check if mapper is supported by type */
2087 if (llType->bSupportMapper) {
2088 if (llType->nMapper == -1) {
2089 /* no driver for mapper has been loaded, try a dumb implementation */
2090 TRACE("No mapper loaded, doing it by hand\n");
2091 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
2092 if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
2093 /* to share this function epilog */
2094 dwInstance = mld->dwDriverInstance;
2099 mld->uDeviceID = (UINT16)-1;
2100 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
2101 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2102 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2106 if (mld->uDeviceID < llType->wMaxId) {
2107 mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
2108 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2109 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2112 if (dwRet == MMSYSERR_NOERROR)
2113 mld->dwDriverInstance = dwInstance;
2117 /**************************************************************************
2118 * MMDRV_Close [internal]
2120 DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
2122 return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
2125 /**************************************************************************
2126 * MMDRV_GetByID [internal]
2128 LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
2130 if (uDevID < llTypes[type].wMaxId)
2131 return &llTypes[type].lpMlds[uDevID];
2132 if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
2133 return &llTypes[type].lpMlds[-1];
2137 /**************************************************************************
2138 * MMDRV_Get [internal]
2140 LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
2142 LPWINE_MLD mld = NULL;
2144 assert(type < MMDRV_MAX);
2146 if ((UINT)hndl >= llTypes[type].wMaxId &&
2147 hndl != (UINT16)-1 && hndl != (UINT)-1) {
2148 if (hndl & 0x8000) {
2150 if (hndl < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2151 mld = MM_MLDrvs[hndl];
2152 if (!mld || !HeapValidate(GetProcessHeap(), 0, mld) || mld->type != type)
2158 if (mld == NULL && bCanBeID) {
2159 mld = MMDRV_GetByID((UINT)hndl, type);
2164 /**************************************************************************
2165 * MMDRV_GetRelated [internal]
2167 LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
2168 BOOL bSrcCanBeID, UINT dstType)
2172 if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
2173 WINE_MM_DRIVER_PART* part = &MMDrvs[mld->mmdIndex].parts[dstType];
2174 if (part->nIDMin < part->nIDMax)
2175 return MMDRV_GetByID(part->nIDMin, dstType);
2180 /**************************************************************************
2181 * MMDRV_PhysicalFeatures [internal]
2183 UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
2186 WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
2188 TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
2190 /* all those function calls are undocumented */
2192 case DRV_QUERYDRVENTRY:
2193 lstrcpynA((LPSTR)dwParam1, lpDrv->drvname, LOWORD(dwParam2));
2195 case DRV_QUERYDEVNODE:
2196 *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
2199 WARN("NIY QueryName\n");
2201 case DRV_QUERYDRIVERIDS:
2202 WARN("NIY call VxD\n");
2203 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2204 * dwParam1 is buffer and dwParam2 is sizeof buffer
2205 * I don't know where the result is stored though
2208 case DRV_QUERYMAPPABLE:
2209 return (lpDrv->bIsMapper) ? 2 : 0;
2211 case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
2212 return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
2215 WARN("Unknown call %04x\n", uMsg);
2216 return MMSYSERR_INVALPARAM;
2221 /**************************************************************************
2222 * MMDRV_InitPerType [internal]
2224 static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT type, UINT wMsg)
2226 WINE_MM_DRIVER_PART* part = &lpDrv->parts[type];
2231 part->nIDMin = part->nIDMax = 0;
2233 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2234 /* the DRVM_ENABLE is only required when the PnP node is non zero */
2236 if (lpDrv->bIs32 && part->u.fnMessage32) {
2237 ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
2238 TRACE("DRVM_INIT => %08lx\n", ret);
2240 ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
2241 TRACE("DRVM_ENABLE => %08lx\n", ret);
2243 count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
2244 } else if (!lpDrv->bIs32 && part->u.fnMessage16) {
2245 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2246 0, DRVM_INIT, 0L, 0L, 0L);
2247 TRACE("DRVM_INIT => %08lx\n", ret);
2249 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2250 0, DRVM_ENABLE, 0L, 0L, 0L);
2251 TRACE("DRVM_ENABLE => %08lx\n", ret);
2253 count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2254 0, wMsg, 0L, 0L, 0L);
2259 TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->drvname, llTypes[type].typestr);
2261 /* got some drivers */
2262 if (lpDrv->bIsMapper) {
2263 /* it seems native mappers return 0 devices :-( */
2264 if (llTypes[type].nMapper != -1)
2265 ERR("Two mappers for type %s (%d, %s)\n",
2266 llTypes[type].typestr, llTypes[type].nMapper, lpDrv->drvname);
2268 ERR("Strange: mapper with %d > 1 devices\n", count);
2269 llTypes[type].nMapper = MMDrvsHi;
2273 part->nIDMin = llTypes[type].wMaxId;
2274 llTypes[type].wMaxId += count;
2275 part->nIDMax = llTypes[type].wMaxId;
2277 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2278 part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
2279 lpDrv->drvname, llTypes[type].typestr);
2280 /* realloc translation table */
2281 llTypes[type].lpMlds = (LPWINE_MLD)
2282 HeapReAlloc(GetProcessHeap(), 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
2283 sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
2284 /* re-build the translation table */
2285 if (llTypes[type].nMapper != -1) {
2286 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, -1, MMDrvs[llTypes[type].nMapper].drvname);
2287 llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
2288 llTypes[type].lpMlds[-1].type = type;
2289 llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
2290 llTypes[type].lpMlds[-1].dwDriverInstance = 0;
2292 for (i = k = 0; i <= MMDrvsHi; i++) {
2293 while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
2294 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, k, MMDrvs[i].drvname);
2295 llTypes[type].lpMlds[k].uDeviceID = k;
2296 llTypes[type].lpMlds[k].type = type;
2297 llTypes[type].lpMlds[k].mmdIndex = i;
2298 llTypes[type].lpMlds[k].dwDriverInstance = 0;
2305 /**************************************************************************
2306 * MMDRV_Install [internal]
2308 static BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
2312 LPWINE_MM_DRIVER lpDrv = &MMDrvs[MMDrvsHi];
2315 TRACE("('%s', '%s', mapper=%c);\n", drvRegName, drvFileName, bIsMapper ? 'Y' : 'N');
2317 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2318 * if not just increase size of MMDrvs */
2319 assert(MMDrvsHi <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
2321 for (i = 0; i < MMDrvsHi; i++) {
2322 if (!strcmp(drvRegName, MMDrvs[i].drvname)) return FALSE;
2325 memset(lpDrv, 0, sizeof(*lpDrv));
2327 if (!(lpDrv->hDriver = OpenDriverA(drvFileName, 0, 0))) {
2328 WARN("Couldn't open driver '%s'\n", drvFileName);
2332 d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
2333 lpDrv->bIs32 = (d->dwFlags & WINE_GDF_16BIT) ? FALSE : TRUE;
2335 /* Then look for xxxMessage functions */
2336 #define AA(_h,_w,_x,_y,_z) \
2337 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
2339 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2340 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2343 WINEMM_msgFunc32 func;
2345 if (d->d.d32.hModule) {
2346 #define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
2347 A(MMDRV_AUX, auxMessage);
2348 A(MMDRV_MIXER, mixMessage);
2349 A(MMDRV_MIDIIN, midMessage);
2350 A(MMDRV_MIDIOUT, modMessage);
2351 A(MMDRV_WAVEIN, widMessage);
2352 A(MMDRV_WAVEOUT, wodMessage);
2356 WINEMM_msgFunc16 func;
2359 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2360 * The beginning of the module description indicates the driver supports
2361 * waveform, auxiliary, and mixer devices. Use one of the following
2362 * device-type names, followed by a colon (:) to indicate the type of
2363 * device your driver supports. If the driver supports more than one
2364 * type of device, separate each device-type name with a comma (,).
2366 * wave for waveform audio devices
2367 * wavemapper for wave mappers
2368 * midi for MIDI audio devices
2369 * midimapper for midi mappers
2370 * aux for auxiliary audio devices
2371 * mixer for mixer devices
2374 if (d->d.d16.hDriver16) {
2375 HMODULE16 hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
2377 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
2378 A(MMDRV_AUX, auxMessage);
2379 A(MMDRV_MIXER, mixMessage);
2380 A(MMDRV_MIDIIN, midMessage);
2381 A(MMDRV_MIDIOUT, modMessage);
2382 A(MMDRV_WAVEIN, widMessage);
2383 A(MMDRV_WAVEOUT, wodMessage);
2389 if (TRACE_ON(mmsys)) {
2390 if ((lpDrv->bIs32) ? MMDRV_GetDescription32(drvFileName, buffer, sizeof(buffer)) :
2391 MMDRV_GetDescription16(drvFileName, buffer, sizeof(buffer)))
2392 TRACE("%s => %s\n", drvFileName, buffer);
2394 TRACE("%s => No description\n", drvFileName);
2398 CloseDriver(lpDrv->hDriver, 0, 0);
2399 WARN("No message functions found\n");
2403 /* FIXME: being a mapper or not should be known by another way */
2404 /* it's known for NE drvs (the description is of the form '*mapper: *'
2405 * I don't have any clue for PE drvs
2407 lpDrv->bIsMapper = bIsMapper;
2408 lpDrv->drvname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(drvRegName) + 1), drvRegName);
2410 /* Finish init and get the count of the devices */
2411 MMDRV_InitPerType(lpDrv, MMDRV_AUX, AUXDM_GETNUMDEVS);
2412 MMDRV_InitPerType(lpDrv, MMDRV_MIXER, MXDM_GETNUMDEVS);
2413 MMDRV_InitPerType(lpDrv, MMDRV_MIDIIN, MIDM_GETNUMDEVS);
2414 MMDRV_InitPerType(lpDrv, MMDRV_MIDIOUT, MODM_GETNUMDEVS);
2415 MMDRV_InitPerType(lpDrv, MMDRV_WAVEIN, WIDM_GETNUMDEVS);
2416 MMDRV_InitPerType(lpDrv, MMDRV_WAVEOUT, WODM_GETNUMDEVS);
2417 /* FIXME: if all those func calls return FALSE,
2418 * then the driver must be unloaded
2426 /**************************************************************************
2427 * MMDRV_InitFromRegistry [internal]
2429 static BOOL MMDRV_InitFromRegistry(void)
2438 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\WinMM", &hKey)) {
2439 TRACE("Cannot open WinMM config key\n");
2443 size = sizeof(buffer);
2444 if (!RegQueryValueExA(hKey, "Drivers", 0, &type, (LPVOID)buffer, &size)) {
2447 p2 = strchr(p1, ';');
2448 if (p2) *p2++ = '\0';
2449 ret |= MMDRV_Install(p1, p1, FALSE);
2454 /* finish with mappers */
2455 size = sizeof(buffer);
2456 if (!RegQueryValueExA(hKey, "WaveMapper", 0, &type, (LPVOID)buffer, &size))
2457 ret |= MMDRV_Install("wavemapper", buffer, TRUE);
2458 size = sizeof(buffer);
2459 if (!RegQueryValueExA(hKey, "MidiMapper", 0, &type, (LPVOID)buffer, &size))
2460 ret |= MMDRV_Install("midimapper", buffer, TRUE);
2467 /**************************************************************************
2468 * MMDRV_InitHardcoded [internal]
2470 static BOOL MMDRV_InitHardcoded(void)
2472 ERR("You didn't setup properly the config file for the Wine multimedia modules.\n"
2473 "Will use the hard-coded setup, but this will disappear soon.\n"
2474 "Please add a WinMM section to your Wine config file.\n");
2476 /* first load hardware drivers */
2477 MMDRV_Install("wineoss.drv", "wineoss.drv", FALSE);
2479 /* finish with mappers */
2480 MMDRV_Install("wavemapper", "msacm.drv", TRUE);
2481 MMDRV_Install("midimapper", "midimap.drv", TRUE);
2486 /**************************************************************************
2487 * MMDRV_Init [internal]
2489 BOOL MMDRV_Init(void)
2491 /* FIXME: MMDRV_InitFromRegistry shall be MMDRV_Init in a near future */
2492 return MMDRV_InitFromRegistry() || MMDRV_InitHardcoded();