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"
17 #include "debugtools.h"
19 DEFAULT_DEBUG_CHANNEL(mmsys);
21 typedef DWORD CALLBACK (*WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
22 typedef DWORD CALLBACK (*WINEMM_msgFunc32)(UINT , UINT, DWORD, DWORD, DWORD);
24 /* for each loaded driver and each known type of driver, this structure contains
25 * the information needed to access it
27 typedef struct tagWINE_MM_DRIVER_PART {
28 int nIDMin; /* lower bound of global indexes for this type */
29 int nIDMax; /* hhigher bound of global indexes for this type */
31 WINEMM_msgFunc32 fnMessage32; /* pointer to fonction */
32 WINEMM_msgFunc16 fnMessage16;
34 } WINE_MM_DRIVER_PART;
36 /* each low-level .drv will be associated with an instance of this structure */
37 typedef struct tagWINE_MM_DRIVER {
39 LPSTR drvname; /* name of the driver */
40 BOOL bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */
41 bIsMapper : 1; /* TRUE if mapper */
42 WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */
43 } WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
46 MMDRV_MAP_NOMEM, /* ko, memory problem */
47 MMDRV_MAP_MSGERROR, /* ko, unknown message */
48 MMDRV_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
49 MMDRV_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
50 MMDRV_MAP_PASS /* not handled (no memory allocated) to be sent to the driver */
53 typedef MMDRV_MapType (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
55 /* each known type of driver has an instance of this structure */
56 typedef struct tagWINE_LLTYPE {
57 /* those attributes depend on the specification of the type */
58 LPSTR typestr; /* name (for debugging) */
59 BOOL bSupportMapper; /* if type is allowed to support mapper */
60 MMDRV_MAPFUNC Map16To32A; /* those are function pointers to handle */
61 MMDRV_MAPFUNC UnMap16To32A; /* the parameter conversion (16 vs 32 bit) */
62 MMDRV_MAPFUNC Map32ATo16; /* when hi-func (in mmsystem or winmm) and */
63 MMDRV_MAPFUNC UnMap32ATo16; /* low-func (in .drv) do not match */
64 LPDRVCALLBACK Callback; /* handles callback for a specified type */
65 /* those attributes reflect the loaded/current situation for the type */
66 UINT wMaxId; /* number of loaded devices (sum across all loaded drivers */
67 LPWINE_MLD lpMlds; /* "static" mlds to access the part though device IDs */
68 int nMapper; /* index to mapper */
71 static int MMDrvsHi /* = 0 */;
72 static WINE_MM_DRIVER MMDrvs[3];
73 static LPWINE_MLD MM_MLDrvs[40];
74 #define MAX_MM_MLDRVS (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
76 /* ### start build ### */
77 extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
78 /* ### stop build ### */
80 /**************************************************************************
81 * MMDRV_GetDescription16 [internal]
83 static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
91 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
92 ERR("Can't open file %s (builtin driver ?)\n", fname);
96 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
98 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
99 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
100 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
101 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
102 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
103 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
104 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %lu\n", dw));
105 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
106 buflen = min((BYTE)buf[0], buflen - 1);
107 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
110 TRACE("Got '%s' [%d]\n", buf, buflen);
116 /**************************************************************************
117 * MMDRV_GetDescription32 [internal]
119 static BOOL MMDRV_GetDescription32(const char* fname, char* buf, int buflen)
128 FARPROC pGetFileVersionInfoSizeA;
129 FARPROC pGetFileVersionInfoA;
130 FARPROC pVerQueryValueA;
133 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
135 if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR) E(("Can't find file %s\n", fname));
137 if (!(hmodule = LoadLibraryA( "version.dll" ))) goto theEnd;
138 if (!(pGetFileVersionInfoSizeA = GetProcAddress( hmodule, "GetFileVersionInfoSizeA" )))
140 if (!(pGetFileVersionInfoA = GetProcAddress( hmodule, "GetFileVersionInfoA" )))
142 if (!(pVerQueryValueA = GetProcAddress( hmodule, "pVerQueryValueA" )))
145 if (!(dw = pGetFileVersionInfoSizeA(ofs.szPathName, &h))) E(("Can't get FVIS\n"));
146 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw))) E(("OOM\n"));
147 if (!pGetFileVersionInfoA(ofs.szPathName, h, dw, ptr)) E(("Can't get FVI\n"));
149 #define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
150 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
166 if (!pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
167 lstrcpynA(buf, val, buflen);
172 HeapFree(GetProcessHeap(), 0, ptr);
173 if (hmodule) FreeLibrary( hmodule );
177 /**************************************************************************
178 * MMDRV_Callback [internal]
180 static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
182 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
183 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
185 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
186 /* 16 bit func, call it */
187 TRACE("Function (16 bit) !\n");
188 MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, hDev, uMsg,
189 mld->dwClientInstance, dwParam1, dwParam2);
191 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
192 mld->dwClientInstance, dwParam1, dwParam2);
196 /* =================================
197 * A U X M A P P E R S
198 * ================================= */
200 /**************************************************************************
201 * MMDRV_Aux_Map16To32A [internal]
203 static MMDRV_MapType MMDRV_Aux_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
205 return MMDRV_MAP_MSGERROR;
208 /**************************************************************************
209 * MMDRV_Aux_UnMap16To32A [internal]
211 static MMDRV_MapType MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
213 return MMDRV_MAP_MSGERROR;
216 /**************************************************************************
217 * MMDRV_Aux_Map32ATo16 [internal]
219 static MMDRV_MapType MMDRV_Aux_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
221 return MMDRV_MAP_MSGERROR;
224 /**************************************************************************
225 * MMDRV_Aux_UnMap32ATo16 [internal]
227 static MMDRV_MapType MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
230 case AUXDM_GETDEVCAPS:
231 lpCaps->wMid = ac16.wMid;
232 lpCaps->wPid = ac16.wPid;
233 lpCaps->vDriverVersion = ac16.vDriverVersion;
234 strcpy(lpCaps->szPname, ac16.szPname);
235 lpCaps->wTechnology = ac16.wTechnology;
236 lpCaps->dwSupport = ac16.dwSupport;
238 return MMDRV_MAP_MSGERROR;
241 /**************************************************************************
242 * MMDRV_Aux_Callback [internal]
244 static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
246 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
249 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
252 /* =================================
253 * M I X E R M A P P E R S
254 * ================================= */
256 /**************************************************************************
257 * xMMDRV_Mixer_Map16To32A [internal]
259 static MMDRV_MapType MMDRV_Mixer_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
261 return MMDRV_MAP_MSGERROR;
264 /**************************************************************************
265 * MMDRV_Mixer_UnMap16To32A [internal]
267 static MMDRV_MapType MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
271 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
273 if (ret == MMSYSERR_NOERROR) {
274 mixcaps->wMid = micA.wMid;
275 mixcaps->wPid = micA.wPid;
276 mixcaps->vDriverVersion = micA.vDriverVersion;
277 strcpy(mixcaps->szPname, micA.szPname);
278 mixcaps->fdwSupport = micA.fdwSupport;
279 mixcaps->cDestinations = micA.cDestinations;
283 return MMDRV_MAP_MSGERROR;
286 /**************************************************************************
287 * MMDRV_Mixer_Map32ATo16 [internal]
289 static MMDRV_MapType MMDRV_Mixer_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
291 return MMDRV_MAP_MSGERROR;
294 /**************************************************************************
295 * MMDRV_Mixer_UnMap32ATo16 [internal]
297 static MMDRV_MapType MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
299 return MMDRV_MAP_MSGERROR;
302 /**************************************************************************
303 * MMDRV_Mixer_Callback [internal]
305 static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
307 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
310 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
313 /* =================================
314 * M I D I I N M A P P E R S
315 * ================================= */
317 /**************************************************************************
318 * MMDRV_MidiIn_Map16To32A [internal]
320 static MMDRV_MapType MMDRV_MidiIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
322 return MMDRV_MAP_MSGERROR;
325 /**************************************************************************
326 * MMDRV_MidiIn_UnMap16To32A [internal]
328 static MMDRV_MapType MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
330 return MMDRV_MAP_MSGERROR;
333 /**************************************************************************
334 * MMDRV_MidiIn_Map32ATo16 [internal]
336 static MMDRV_MapType MMDRV_MidiIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
338 return MMDRV_MAP_MSGERROR;
341 /**************************************************************************
342 * MMDRV_MidiIn_UnMap32ATo16 [internal]
344 static MMDRV_MapType MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
346 return MMDRV_MAP_MSGERROR;
349 /**************************************************************************
350 * MMDRV_MidiIn_Callback [internal]
352 static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
354 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
359 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
364 /* dwParam1 & dwParam2 are are data, nothing to do */
368 /* dwParam1 points to a MidiHdr, work to be done !!! */
369 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
370 /* initial map is: 32 => 16 */
371 LPMIDIHDR mh16 = MapSL(dwParam1);
372 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
374 dwParam1 = (DWORD)mh32;
375 mh32->dwFlags = mh16->dwFlags;
376 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
377 if (mh32->reserved >= sizeof(MIDIHDR))
378 mh32->dwOffset = mh16->dwOffset;
379 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
380 /* initial map is: 16 => 32 */
381 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
382 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
383 LPMIDIHDR mh16 = MapSL(segmh16);
385 dwParam1 = (DWORD)segmh16;
386 mh16->dwFlags = mh32->dwFlags;
387 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
388 if (mh16->reserved >= sizeof(MIDIHDR))
389 mh16->dwOffset = mh32->dwOffset;
391 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
393 /* case MOM_POSITIONCB: */
395 ERR("Unknown msg %u\n", uMsg);
398 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
401 /* =================================
402 * M I D I O U T M A P P E R S
403 * ================================= */
405 /**************************************************************************
406 * MMDRV_MidiOut_Map16To32A [internal]
408 static MMDRV_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
410 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
413 case MODM_GETNUMDEVS:
423 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
426 case MODM_GETDEVCAPS:
428 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
429 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
432 *(LPMIDIOUTCAPS16*)moc32 = moc16;
433 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
434 *lpParam1 = (DWORD)moc32;
435 *lpParam2 = sizeof(MIDIOUTCAPSA);
437 ret = MMDRV_MAP_OKMEM;
439 ret = MMDRV_MAP_NOMEM;
445 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
446 LPMIDIHDR mh16 = MapSL(*lpParam1);
449 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
450 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
451 mh32->lpData = MapSL((SEGPTR)mh16->lpData);
452 mh32->dwBufferLength = mh16->dwBufferLength;
453 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
454 mh32->dwUser = mh16->dwUser;
455 mh32->dwFlags = mh16->dwFlags;
456 /* FIXME: nothing on mh32->lpNext */
457 /* could link the mh32->lpNext at this level for memory house keeping */
458 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
459 mh16->lpNext = mh32; /* for reuse in unprepare and write */
460 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
461 mh16->reserved = *lpParam2;
462 *lpParam1 = (DWORD)mh32;
463 *lpParam2 = sizeof(MIDIHDR);
465 ret = MMDRV_MAP_OKMEM;
467 ret = MMDRV_MAP_NOMEM;
474 LPMIDIHDR mh16 = MapSL(*lpParam1);
475 LPMIDIHDR mh32 = (LPMIDIHDR)mh16->lpNext;
477 *lpParam1 = (DWORD)mh32;
478 *lpParam2 = sizeof(MIDIHDR);
479 /* dwBufferLength can be reduced between prepare & write */
480 if (mh32->dwBufferLength < mh16->dwBufferLength) {
481 ERR("Size of buffer has been increased (%ld, %ld)\n",
482 mh32->dwBufferLength, mh16->dwBufferLength);
483 return MMDRV_MAP_MSGERROR;
485 mh32->dwBufferLength = mh16->dwBufferLength;
486 ret = MMDRV_MAP_OKMEM;
490 case MODM_CACHEPATCHES:
491 case MODM_CACHEDRUMPATCHES:
493 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
499 /**************************************************************************
500 * MMDRV_MidiOut_UnMap16To32A [internal]
502 static MMDRV_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
504 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
507 case MODM_GETNUMDEVS:
517 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
520 case MODM_GETDEVCAPS:
522 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
523 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
525 moc16->wMid = moc32->wMid;
526 moc16->wPid = moc32->wPid;
527 moc16->vDriverVersion = moc32->vDriverVersion;
528 strcpy(moc16->szPname, moc32->szPname);
529 moc16->wTechnology = moc32->wTechnology;
530 moc16->wVoices = moc32->wVoices;
531 moc16->wNotes = moc32->wNotes;
532 moc16->wChannelMask = moc32->wChannelMask;
533 moc16->dwSupport = moc32->dwSupport;
534 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
542 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
543 LPMIDIHDR mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
545 assert(mh16->lpNext == mh32);
546 mh16->dwBufferLength = mh32->dwBufferLength;
547 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
548 mh16->dwUser = mh32->dwUser;
549 mh16->dwFlags = mh32->dwFlags;
550 if (mh16->reserved >= sizeof(MIDIHDR))
551 mh16->dwOffset = mh32->dwOffset;
553 if (wMsg == MODM_UNPREPARE) {
554 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
561 case MODM_CACHEPATCHES:
562 case MODM_CACHEDRUMPATCHES:
564 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
570 /**************************************************************************
571 * MMDRV_MidiOut_Map32ATo16 [internal]
573 static MMDRV_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
575 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
579 case MODM_GETNUMDEVS:
585 case MODM_GETDEVCAPS:
587 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
588 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMIDIOUTCAPSA) + sizeof(MIDIOUTCAPS16));
591 *(LPMIDIOUTCAPSA*)ptr = moc32;
592 ret = MMDRV_MAP_OKMEM;
594 ret = MMDRV_MAP_NOMEM;
596 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOUTCAPSA);
597 *lpParam2 = sizeof(MIDIOUTCAPS16);
602 LPMIDIHDR mh32 = (LPMIDIHDR)*lpParam1;
604 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
607 *(LPMIDIHDR*)ptr = mh32;
608 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
609 mh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR) + sizeof(MIDIHDR);
610 /* data will be copied on WODM_WRITE */
611 mh16->dwBufferLength = mh32->dwBufferLength;
612 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
613 mh16->dwUser = mh32->dwUser;
614 mh16->dwFlags = mh32->dwFlags;
615 /* FIXME: nothing on mh32->lpNext */
616 /* could link the mh32->lpNext at this level for memory house keeping */
617 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
619 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
620 mh32->reserved = *lpParam2;
622 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
623 (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR), (DWORD)mh16->lpData,
624 mh32->dwBufferLength, (DWORD)mh32->lpData);
625 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR);
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 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
644 (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR), (DWORD)mh16->lpData,
645 mh32->dwBufferLength, (DWORD)mh32->lpData);
647 if (wMsg == MODM_LONGDATA)
648 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
650 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR);
651 *lpParam2 = sizeof(MIDIHDR);
652 /* dwBufferLength can be reduced between prepare & write */
653 if (mh16->dwBufferLength < mh32->dwBufferLength) {
654 ERR("Size of buffer has been increased (%ld, %ld)\n",
655 mh16->dwBufferLength, mh32->dwBufferLength);
656 return MMDRV_MAP_MSGERROR;
658 mh16->dwBufferLength = mh32->dwBufferLength;
659 ret = MMDRV_MAP_OKMEM;
664 LPMIDIOPENDESC mod32 = (LPMIDIOPENDESC)*lpParam1;
666 LPMIDIOPENDESC16 mod16;
668 /* allocated data are mapped as follows:
669 LPMIDIOPENDESC ptr to orig lParam1
670 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
671 DWORD dwUser passed to driver
672 MIDIOPENDESC16 mod16: openDesc passed to driver
675 ptr = SEGPTR_ALLOC(sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
676 mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
679 *(LPMIDIOPENDESC*)ptr = mod32;
680 *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
681 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
683 mod16->hMidi = mod32->hMidi;
684 mod16->dwCallback = mod32->dwCallback;
685 mod16->dwInstance = mod32->dwInstance;
686 mod16->dnDevNode = mod32->dnDevNode;
687 mod16->cIds = mod32->cIds;
688 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
690 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
691 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
693 ret = MMDRV_MAP_OKMEM;
695 ret = MMDRV_MAP_NOMEM;
700 case MODM_CACHEPATCHES:
701 case MODM_CACHEDRUMPATCHES:
703 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
709 /**************************************************************************
710 * MMDRV_MidiOut_UnMap32ATo16 [internal]
712 static MMDRV_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
714 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
718 case MODM_GETNUMDEVS:
724 case MODM_GETDEVCAPS:
726 LPMIDIOUTCAPS16 moc16 = MapSL(*lpParam1);
727 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
728 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
730 moc32->wMid = moc16->wMid;
731 moc32->wPid = moc16->wPid;
732 moc32->vDriverVersion = moc16->vDriverVersion;
733 strcpy(moc32->szPname, moc16->szPname);
734 moc32->wTechnology = moc16->wTechnology;
735 moc32->wVoices = moc16->wVoices;
736 moc32->wNotes = moc16->wNotes;
737 moc32->wChannelMask = moc16->wChannelMask;
738 moc32->dwSupport = moc16->dwSupport;
740 if (!SEGPTR_FREE(ptr))
741 FIXME("bad free line=%d\n", __LINE__);
749 LPMIDIHDR mh16 = MapSL(*lpParam1);
750 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
751 LPMIDIHDR mh32 = *(LPMIDIHDR*)ptr;
753 assert(mh32->lpNext == (LPMIDIHDR)mh16);
754 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
755 mh32->dwUser = mh16->dwUser;
756 mh32->dwFlags = mh16->dwFlags;
758 if (wMsg == MODM_UNPREPARE) {
759 if (!SEGPTR_FREE(ptr))
760 FIXME("bad free line=%d\n", __LINE__);
768 LPMIDIOPENDESC16 mod16 = MapSL(*lpParam1);
769 LPSTR ptr = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
771 **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
773 if (!SEGPTR_FREE(ptr))
774 FIXME("bad free line=%d\n", __LINE__);
780 case MODM_CACHEPATCHES:
781 case MODM_CACHEDRUMPATCHES:
783 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
789 /**************************************************************************
790 * MMDRV_MidiOut_Callback [internal]
792 static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
794 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
799 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
802 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
803 /* initial map is: 32 => 16 */
804 LPMIDIHDR mh16 = MapSL(dwParam1);
805 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
807 dwParam1 = (DWORD)mh32;
808 mh32->dwFlags = mh16->dwFlags;
809 mh32->dwOffset = mh16->dwOffset;
810 if (mh32->reserved >= sizeof(MIDIHDR))
811 mh32->dwOffset = mh16->dwOffset;
812 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
813 /* initial map is: 16 => 32 */
814 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
815 SEGPTR segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
816 LPMIDIHDR mh16 = MapSL(segmh16);
818 dwParam1 = (DWORD)segmh16;
819 mh16->dwFlags = mh32->dwFlags;
820 if (mh16->reserved >= sizeof(MIDIHDR))
821 mh16->dwOffset = mh32->dwOffset;
823 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
825 /* case MOM_POSITIONCB: */
827 ERR("Unknown msg %u\n", uMsg);
830 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
833 /* =================================
834 * W A V E I N M A P P E R S
835 * ================================= */
837 /**************************************************************************
838 * MMDRV_WaveIn_Map16To32A [internal]
840 static MMDRV_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
842 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
845 case WIDM_GETNUMDEVS:
853 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
855 case WIDM_GETDEVCAPS:
857 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
858 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
861 *(LPWAVEINCAPS16*)wic32 = wic16;
862 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
863 *lpParam1 = (DWORD)wic32;
864 *lpParam2 = sizeof(WAVEINCAPSA);
866 ret = MMDRV_MAP_OKMEM;
868 ret = MMDRV_MAP_NOMEM;
874 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
875 LPMMTIME16 mmt16 = MapSL(*lpParam1);
878 *(LPMMTIME16*)mmt32 = mmt16;
879 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
881 mmt32->wType = mmt16->wType;
882 *lpParam1 = (DWORD)mmt32;
883 *lpParam2 = sizeof(MMTIME);
885 ret = MMDRV_MAP_OKMEM;
887 ret = MMDRV_MAP_NOMEM;
893 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
894 LPWAVEHDR wh16 = MapSL(*lpParam1);
897 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
898 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
899 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
900 wh32->dwBufferLength = wh16->dwBufferLength;
901 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
902 wh32->dwUser = wh16->dwUser;
903 wh32->dwFlags = wh16->dwFlags;
904 wh32->dwLoops = wh16->dwLoops;
905 /* FIXME: nothing on wh32->lpNext */
906 /* could link the wh32->lpNext at this level for memory house keeping */
907 wh16->lpNext = wh32; /* for reuse in unprepare and write */
908 *lpParam1 = (DWORD)wh32;
909 *lpParam2 = sizeof(WAVEHDR);
911 ret = MMDRV_MAP_OKMEM;
913 ret = MMDRV_MAP_NOMEM;
920 LPWAVEHDR wh16 = MapSL(*lpParam1);
921 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
923 *lpParam1 = (DWORD)wh32;
924 *lpParam2 = sizeof(WAVEHDR);
925 /* dwBufferLength can be reduced between prepare & write */
926 if (wh32->dwBufferLength < wh16->dwBufferLength) {
927 ERR("Size of buffer has been increased (%ld, %ld)\n",
928 wh32->dwBufferLength, wh16->dwBufferLength);
929 return MMDRV_MAP_MSGERROR;
931 wh32->dwBufferLength = wh16->dwBufferLength;
932 ret = MMDRV_MAP_OKMEM;
935 case WIDM_MAPPER_STATUS:
936 /* just a single DWORD */
937 *lpParam2 = (DWORD)MapSL(*lpParam2);
941 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
947 /**************************************************************************
948 * MMDRV_WaveIn_UnMap16To32A [internal]
950 static MMDRV_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
952 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
955 case WIDM_GETNUMDEVS:
959 case WIDM_MAPPER_STATUS:
964 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
966 case WIDM_GETDEVCAPS:
968 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
969 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
971 wic16->wMid = wic32->wMid;
972 wic16->wPid = wic32->wPid;
973 wic16->vDriverVersion = wic32->vDriverVersion;
974 strcpy(wic16->szPname, wic32->szPname);
975 wic16->dwFormats = wic32->dwFormats;
976 wic16->wChannels = wic32->wChannels;
977 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
983 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
984 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
986 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
987 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
995 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
996 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
998 assert(wh16->lpNext == wh32);
999 wh16->dwBufferLength = wh32->dwBufferLength;
1000 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1001 wh16->dwUser = wh32->dwUser;
1002 wh16->dwFlags = wh32->dwFlags;
1003 wh16->dwLoops = wh32->dwLoops;
1005 if (wMsg == WIDM_UNPREPARE) {
1006 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1013 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1019 /**************************************************************************
1020 * MMDRV_WaveIn_Map32ATo16 [internal]
1022 static MMDRV_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1024 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1028 case WIDM_GETNUMDEVS:
1037 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1038 int sz = sizeof(WAVEFORMATEX);
1040 LPWAVEOPENDESC16 wod16;
1042 /* allocated data are mapped as follows:
1043 LPWAVEOPENDESC ptr to orig lParam1
1044 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1045 DWORD dwUser passed to driver
1046 WAVEOPENDESC16 wod16: openDesc passed to driver
1047 WAVEFORMATEX openDesc->lpFormat passed to driver
1048 xxx extra bytes to WAVEFORMATEX
1050 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1051 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1052 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1055 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
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)((DWORD)SEGPTR_GET(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 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1072 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1074 ret = MMDRV_MAP_OKMEM;
1076 ret = MMDRV_MAP_NOMEM;
1082 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1084 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1087 *(LPWAVEHDR*)ptr = wh32;
1088 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1089 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1090 /* data will be copied on WODM_WRITE */
1091 wh16->dwBufferLength = wh32->dwBufferLength;
1092 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1093 wh16->dwUser = wh32->dwUser;
1094 wh16->dwFlags = wh32->dwFlags;
1095 wh16->dwLoops = wh32->dwLoops;
1096 /* FIXME: nothing on wh32->lpNext */
1097 /* could link the wh32->lpNext at this level for memory house keeping */
1098 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1099 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1100 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1101 wh32->dwBufferLength, (DWORD)wh32->lpData);
1102 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1103 *lpParam2 = sizeof(WAVEHDR);
1105 ret = MMDRV_MAP_OKMEM;
1107 ret = MMDRV_MAP_NOMEM;
1111 case WIDM_ADDBUFFER:
1112 case WIDM_UNPREPARE:
1114 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1115 LPWAVEHDR wh16 = wh32->lpNext;
1116 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1118 assert(*(LPWAVEHDR*)ptr == wh32);
1120 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1121 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1122 wh32->dwBufferLength, (DWORD)wh32->lpData);
1124 if (wMsg == WIDM_ADDBUFFER)
1125 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1127 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1128 *lpParam2 = sizeof(WAVEHDR);
1129 /* dwBufferLength can be reduced between prepare & write */
1130 if (wh32->dwBufferLength < wh16->dwBufferLength) {
1131 ERR("Size of buffer has been increased (%ld, %ld)\n",
1132 wh32->dwBufferLength, wh16->dwBufferLength);
1133 return MMDRV_MAP_MSGERROR;
1135 wh32->dwBufferLength = wh16->dwBufferLength;
1136 ret = MMDRV_MAP_OKMEM;
1139 case WIDM_GETDEVCAPS:
1141 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
1142 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
1145 *(LPWAVEINCAPSA*)ptr = wic32;
1146 ret = MMDRV_MAP_OKMEM;
1148 ret = MMDRV_MAP_NOMEM;
1150 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEINCAPSA);
1151 *lpParam2 = sizeof(WAVEINCAPS16);
1156 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1157 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
1158 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1161 *(LPMMTIME*)ptr = mmt32;
1162 mmt16->wType = mmt32->wType;
1163 ret = MMDRV_MAP_OKMEM;
1165 ret = MMDRV_MAP_NOMEM;
1167 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
1168 *lpParam2 = sizeof(MMTIME16);
1171 case DRVM_MAPPER_STATUS:
1173 LPDWORD p32 = (LPDWORD)*lpParam2;
1178 switch (*lpParam1) {
1179 case WAVEIN_MAPPER_STATUS_DEVICE: sz = sizeof(DWORD); break;
1180 case WAVEIN_MAPPER_STATUS_MAPPED: sz = sizeof(DWORD); break;
1181 case WAVEIN_MAPPER_STATUS_FORMAT: sz = sizeof(WAVEFORMATEX); break;
1183 ERR("Unknown value: %lu\n", *lpParam1);
1184 return MMDRV_MAP_MSGERROR;
1186 ptr = SEGPTR_ALLOC(sizeof(LPDWORD) + sz);
1187 p16 = (LPDWORD)(ptr + sizeof(LPDWORD));
1190 *(LPDWORD*)ptr = p32;
1191 ret = MMDRV_MAP_OKMEM;
1193 ret = MMDRV_MAP_NOMEM;
1195 *lpParam2 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPDWORD);
1199 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1205 /**************************************************************************
1206 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1208 static MMDRV_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1210 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1214 case WIDM_GETNUMDEVS:
1223 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1224 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1225 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1227 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1228 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1230 if (!SEGPTR_FREE(ptr))
1231 FIXME("bad free line=%d\n", __LINE__);
1237 case WIDM_ADDBUFFER:
1239 case WIDM_UNPREPARE:
1241 LPWAVEHDR wh16 = MapSL(*lpParam1);
1242 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1243 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1245 assert(wh32->lpNext == wh16);
1246 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1247 wh32->dwUser = wh16->dwUser;
1248 wh32->dwFlags = wh16->dwFlags;
1249 wh32->dwLoops = wh16->dwLoops;
1251 if (wMsg == WIDM_UNPREPARE) {
1252 if (!SEGPTR_FREE(ptr))
1253 FIXME("bad free line=%d\n", __LINE__);
1259 case WIDM_GETDEVCAPS:
1261 LPWAVEINCAPS16 wic16 = MapSL(*lpParam1);
1262 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1263 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
1265 wic32->wMid = wic16->wMid;
1266 wic32->wPid = wic16->wPid;
1267 wic32->vDriverVersion = wic16->vDriverVersion;
1268 strcpy(wic32->szPname, wic16->szPname);
1269 wic32->dwFormats = wic16->dwFormats;
1270 wic32->wChannels = wic16->wChannels;
1271 if (!SEGPTR_FREE(ptr))
1272 FIXME("bad free line=%d\n", __LINE__);
1278 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1279 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1280 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1282 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1284 if (!SEGPTR_FREE(ptr))
1285 FIXME("bad free line=%d\n", __LINE__);
1290 case DRVM_MAPPER_STATUS:
1292 LPDWORD p16 = MapSL(*lpParam2);
1293 LPSTR ptr = (LPSTR)p16 - sizeof(LPDWORD);
1294 LPDWORD p32 = *(LPDWORD*)ptr;
1297 switch (*lpParam1) {
1298 case WAVEIN_MAPPER_STATUS_DEVICE: sz = sizeof(DWORD); break;
1299 case WAVEIN_MAPPER_STATUS_MAPPED: sz = sizeof(DWORD); break;
1300 case WAVEIN_MAPPER_STATUS_FORMAT: sz = sizeof(WAVEFORMATEX); break;
1302 ERR("Unknown value: %lu\n", *lpParam1);
1303 return MMDRV_MAP_MSGERROR;
1306 memcpy(p32, p16, sz);
1307 if (!SEGPTR_FREE(ptr))
1308 FIXME("bad free line=%d\n", __LINE__);
1314 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1320 /**************************************************************************
1321 * MMDRV_WaveIn_Callback [internal]
1323 static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1325 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1330 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1333 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1334 /* initial map is: 32 => 16 */
1335 LPWAVEHDR wh16 = MapSL(dwParam1);
1336 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1338 dwParam1 = (DWORD)wh32;
1339 wh32->dwFlags = wh16->dwFlags;
1340 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1341 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1342 /* initial map is: 16 => 32 */
1343 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1344 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1345 LPWAVEHDR wh16 = MapSL(segwh16);
1347 dwParam1 = (DWORD)segwh16;
1348 wh16->dwFlags = wh32->dwFlags;
1349 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1351 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1354 ERR("Unknown msg %u\n", uMsg);
1357 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1360 /* =================================
1361 * W A V E O U T M A P P E R S
1362 * ================================= */
1364 /**************************************************************************
1365 * MMDRV_WaveOut_Map16To32A [internal]
1367 static MMDRV_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1369 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1373 case WODM_BREAKLOOP:
1375 case WODM_GETNUMDEVS:
1380 case WODM_SETPLAYBACKRATE:
1381 case WODM_SETVOLUME:
1386 case WODM_GETPLAYBACKRATE:
1387 case WODM_GETVOLUME:
1389 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1392 case WODM_GETDEVCAPS:
1394 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1395 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1398 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1399 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1400 *lpParam1 = (DWORD)woc32;
1401 *lpParam2 = sizeof(WAVEOUTCAPSA);
1403 ret = MMDRV_MAP_OKMEM;
1405 ret = MMDRV_MAP_NOMEM;
1411 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1412 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1415 *(LPMMTIME16*)mmt32 = mmt16;
1416 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1418 mmt32->wType = mmt16->wType;
1419 *lpParam1 = (DWORD)mmt32;
1420 *lpParam2 = sizeof(MMTIME);
1422 ret = MMDRV_MAP_OKMEM;
1424 ret = MMDRV_MAP_NOMEM;
1430 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1431 LPWAVEHDR wh16 = MapSL(*lpParam1);
1434 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1435 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1436 wh32->lpData = MapSL((SEGPTR)wh16->lpData);
1437 wh32->dwBufferLength = wh16->dwBufferLength;
1438 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1439 wh32->dwUser = wh16->dwUser;
1440 wh32->dwFlags = wh16->dwFlags;
1441 wh32->dwLoops = wh16->dwLoops;
1442 /* FIXME: nothing on wh32->lpNext */
1443 /* could link the wh32->lpNext at this level for memory house keeping */
1444 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1445 *lpParam1 = (DWORD)wh32;
1446 *lpParam2 = sizeof(WAVEHDR);
1448 ret = MMDRV_MAP_OKMEM;
1450 ret = MMDRV_MAP_NOMEM;
1454 case WODM_UNPREPARE:
1457 LPWAVEHDR wh16 = MapSL(*lpParam1);
1458 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1460 *lpParam1 = (DWORD)wh32;
1461 *lpParam2 = sizeof(WAVEHDR);
1462 /* dwBufferLength can be reduced between prepare & write */
1463 if (wh32->dwBufferLength < wh16->dwBufferLength) {
1464 ERR("Size of buffer has been increased (%ld, %ld)\n",
1465 wh32->dwBufferLength, wh16->dwBufferLength);
1466 return MMDRV_MAP_MSGERROR;
1468 wh32->dwBufferLength = wh16->dwBufferLength;
1469 ret = MMDRV_MAP_OKMEM;
1472 case WODM_MAPPER_STATUS:
1473 *lpParam2 = (DWORD)MapSL(*lpParam2);
1477 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1483 /**************************************************************************
1484 * MMDRV_WaveOut_UnMap16To32A [internal]
1486 static MMDRV_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1488 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1492 case WODM_BREAKLOOP:
1494 case WODM_GETNUMDEVS:
1499 case WODM_SETPLAYBACKRATE:
1500 case WODM_SETVOLUME:
1501 case WODM_MAPPER_STATUS:
1506 case WODM_GETPLAYBACKRATE:
1507 case WODM_GETVOLUME:
1509 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1512 case WODM_GETDEVCAPS:
1514 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1515 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1517 woc16->wMid = woc32->wMid;
1518 woc16->wPid = woc32->wPid;
1519 woc16->vDriverVersion = woc32->vDriverVersion;
1520 strcpy(woc16->szPname, woc32->szPname);
1521 woc16->dwFormats = woc32->dwFormats;
1522 woc16->wChannels = woc32->wChannels;
1523 woc16->dwSupport = woc32->dwSupport;
1524 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1530 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1531 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1533 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1534 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1539 case WODM_UNPREPARE:
1542 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1543 LPWAVEHDR wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1545 assert(wh16->lpNext == wh32);
1546 wh16->dwBufferLength = wh32->dwBufferLength;
1547 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1548 wh16->dwUser = wh32->dwUser;
1549 wh16->dwFlags = wh32->dwFlags;
1550 wh16->dwLoops = wh32->dwLoops;
1552 if (wMsg == WODM_UNPREPARE) {
1553 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1560 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1566 /**************************************************************************
1567 * MMDRV_WaveOut_Map32ATo16 [internal]
1569 static MMDRV_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1575 case WODM_BREAKLOOP:
1577 case WODM_GETNUMDEVS:
1582 case WODM_SETPLAYBACKRATE:
1583 case WODM_SETVOLUME:
1587 case WODM_GETDEVCAPS:
1589 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1590 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1593 *(LPWAVEOUTCAPSA*)ptr = woc32;
1594 ret = MMDRV_MAP_OKMEM;
1596 ret = MMDRV_MAP_NOMEM;
1598 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOUTCAPSA);
1599 *lpParam2 = sizeof(WAVEOUTCAPS16);
1603 FIXME("NIY: no conversion yet\n");
1604 ret = MMDRV_MAP_MSGERROR;
1606 case WODM_GETPLAYBACKRATE:
1607 FIXME("NIY: no conversion yet\n");
1608 ret = MMDRV_MAP_MSGERROR;
1612 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1613 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
1614 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1617 *(LPMMTIME*)ptr = mmt32;
1618 mmt16->wType = mmt32->wType;
1619 ret = MMDRV_MAP_OKMEM;
1621 ret = MMDRV_MAP_NOMEM;
1623 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
1624 *lpParam2 = sizeof(MMTIME16);
1627 case WODM_GETVOLUME:
1628 FIXME("NIY: no conversion yet\n");
1629 ret = MMDRV_MAP_MSGERROR;
1633 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1634 int sz = sizeof(WAVEFORMATEX);
1636 LPWAVEOPENDESC16 wod16;
1638 /* allocated data are mapped as follows:
1639 LPWAVEOPENDESC ptr to orig lParam1
1640 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1641 DWORD dwUser passed to driver
1642 WAVEOPENDESC16 wod16: openDesc passed to driver
1643 WAVEFORMATEX openDesc->lpFormat passed to driver
1644 xxx extra bytes to WAVEFORMATEX
1646 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1647 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1648 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1651 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1654 *(LPWAVEOPENDESC*)ptr = wod32;
1655 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1656 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1658 wod16->hWave = wod32->hWave;
1659 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1660 memcpy(wod16 + 1, wod32->lpFormat, sz);
1662 wod16->dwCallback = wod32->dwCallback;
1663 wod16->dwInstance = wod32->dwInstance;
1664 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1665 wod16->dnDevNode = wod32->dnDevNode;
1667 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1668 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1670 ret = MMDRV_MAP_OKMEM;
1672 ret = MMDRV_MAP_NOMEM;
1678 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1680 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1683 *(LPWAVEHDR*)ptr = wh32;
1684 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1685 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1686 /* data will be copied on WODM_WRITE */
1687 wh16->dwBufferLength = wh32->dwBufferLength;
1688 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1689 wh16->dwUser = wh32->dwUser;
1690 wh16->dwFlags = wh32->dwFlags;
1691 wh16->dwLoops = wh32->dwLoops;
1692 /* FIXME: nothing on wh32->lpNext */
1693 /* could link the wh32->lpNext at this level for memory house keeping */
1694 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1695 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1696 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1697 wh32->dwBufferLength, (DWORD)wh32->lpData);
1698 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1699 *lpParam2 = sizeof(WAVEHDR);
1701 ret = MMDRV_MAP_OKMEM;
1703 ret = MMDRV_MAP_NOMEM;
1707 case WODM_UNPREPARE:
1710 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1711 LPWAVEHDR wh16 = wh32->lpNext;
1712 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1714 assert(*(LPWAVEHDR*)ptr == wh32);
1716 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1717 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1718 wh32->dwBufferLength, (DWORD)wh32->lpData);
1720 if (wMsg == WODM_WRITE)
1721 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1723 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1724 *lpParam2 = sizeof(WAVEHDR);
1725 /* dwBufferLength can be reduced between prepare & write */
1726 if (wh16->dwBufferLength < wh32->dwBufferLength) {
1727 ERR("Size of buffer has been increased (%ld, %ld)\n",
1728 wh16->dwBufferLength, wh32->dwBufferLength);
1729 return MMDRV_MAP_MSGERROR;
1731 wh16->dwBufferLength = wh32->dwBufferLength;
1732 ret = MMDRV_MAP_OKMEM;
1735 case DRVM_MAPPER_STATUS:
1737 LPDWORD p32 = (LPDWORD)*lpParam2;
1742 switch (*lpParam1) {
1743 case WAVEOUT_MAPPER_STATUS_DEVICE: sz = sizeof(DWORD); break;
1744 case WAVEOUT_MAPPER_STATUS_MAPPED: sz = sizeof(DWORD); break;
1745 case WAVEOUT_MAPPER_STATUS_FORMAT: sz = sizeof(WAVEFORMATEX); break;
1747 ERR("Unknown value: %lu\n", *lpParam1);
1748 return MMDRV_MAP_MSGERROR;
1750 ptr = SEGPTR_ALLOC(sizeof(LPDWORD) + sz);
1751 p16 = (LPDWORD)(ptr + sizeof(LPDWORD));
1754 *(LPDWORD*)ptr = p32;
1755 memcpy(p16, p32, sz);
1756 ret = MMDRV_MAP_OKMEM;
1758 ret = MMDRV_MAP_NOMEM;
1760 *lpParam2 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPDWORD);
1764 FIXME("NIY: no conversion yet\n");
1765 ret = MMDRV_MAP_MSGERROR;
1771 /**************************************************************************
1772 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1774 static MMDRV_MapType MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1780 case WODM_BREAKLOOP:
1782 case WODM_GETNUMDEVS:
1787 case WODM_SETPLAYBACKRATE:
1788 case WODM_SETVOLUME:
1792 case WODM_GETDEVCAPS:
1794 LPWAVEOUTCAPS16 woc16 = MapSL(*lpParam1);
1795 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1796 LPWAVEOUTCAPSA woc32 = *(LPWAVEOUTCAPSA*)ptr;
1798 woc32->wMid = woc16->wMid;
1799 woc32->wPid = woc16->wPid;
1800 woc32->vDriverVersion = woc16->vDriverVersion;
1801 strcpy(woc32->szPname, woc16->szPname);
1802 woc32->dwFormats = woc16->dwFormats;
1803 woc32->wChannels = woc16->wChannels;
1804 woc32->dwSupport = woc16->dwSupport;
1805 if (!SEGPTR_FREE(ptr))
1806 FIXME("bad free line=%d\n", __LINE__);
1811 FIXME("NIY: no conversion yet\n");
1812 ret = MMDRV_MAP_MSGERROR;
1814 case WODM_GETPLAYBACKRATE:
1815 FIXME("NIY: no conversion yet\n");
1816 ret = MMDRV_MAP_MSGERROR;
1820 LPMMTIME16 mmt16 = MapSL(*lpParam1);
1821 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1822 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1824 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1826 if (!SEGPTR_FREE(ptr))
1827 FIXME("bad free line=%d\n", __LINE__);
1834 LPWAVEOPENDESC16 wod16 = MapSL(*lpParam1);
1835 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1836 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1838 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1839 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1841 if (!SEGPTR_FREE(ptr))
1842 FIXME("bad free line=%d\n", __LINE__);
1848 case WODM_UNPREPARE:
1851 LPWAVEHDR wh16 = MapSL(*lpParam1);
1852 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1853 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1855 assert(wh32->lpNext == wh16);
1856 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1857 wh32->dwUser = wh16->dwUser;
1858 wh32->dwFlags = wh16->dwFlags;
1859 wh32->dwLoops = wh16->dwLoops;
1861 if (wMsg == WODM_UNPREPARE) {
1862 if (!SEGPTR_FREE(ptr))
1863 FIXME("bad free line=%d\n", __LINE__);
1869 case WODM_GETVOLUME:
1870 FIXME("NIY: no conversion yet\n");
1871 ret = MMDRV_MAP_MSGERROR;
1873 case DRVM_MAPPER_STATUS:
1875 LPDWORD p16 = MapSL(*lpParam2);
1876 LPSTR ptr = (LPSTR)p16 - sizeof(LPDWORD);
1877 LPDWORD p32 = *(LPDWORD*)ptr;
1880 switch (*lpParam1) {
1881 case WAVEOUT_MAPPER_STATUS_DEVICE: sz = sizeof(DWORD); break;
1882 case WAVEOUT_MAPPER_STATUS_MAPPED: sz = sizeof(DWORD); break;
1883 case WAVEOUT_MAPPER_STATUS_FORMAT: sz = sizeof(WAVEFORMATEX); break;
1885 ERR("Unknown value: %lu\n", *lpParam1);
1886 return MMDRV_MAP_MSGERROR;
1889 memcpy(p32, p16, sz);
1890 if (!SEGPTR_FREE(ptr))
1891 FIXME("bad free line=%d\n", __LINE__);
1897 FIXME("NIY: no conversion yet\n");
1898 ret = MMDRV_MAP_MSGERROR;
1904 /**************************************************************************
1905 * MMDRV_WaveOut_Callback [internal]
1907 static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1909 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1914 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1917 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1918 /* initial map is: 32 => 16 */
1919 LPWAVEHDR wh16 = MapSL(dwParam1);
1920 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1922 dwParam1 = (DWORD)wh32;
1923 wh32->dwFlags = wh16->dwFlags;
1924 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1925 /* initial map is: 16 => 32 */
1926 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1927 SEGPTR segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1928 LPWAVEHDR wh16 = MapSL(segwh16);
1930 dwParam1 = (DWORD)segwh16;
1931 wh16->dwFlags = wh32->dwFlags;
1933 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1936 ERR("Unknown msg %u\n", uMsg);
1939 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1942 #define A(_x,_y) {#_y, _x, \
1943 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1944 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1945 MMDRV_##_y##_Callback, 0, NULL, -1}
1947 /* Note: the indices of this array must match the definitions
1948 * of the MMDRV_???? manifest constants
1950 static WINE_LLTYPE llTypes[MMDRV_MAX] = {
1960 /**************************************************************************
1961 * MMDRV_GetNum [internal]
1963 UINT MMDRV_GetNum(UINT type)
1965 assert(type < MMDRV_MAX);
1966 return llTypes[type].wMaxId;
1969 /**************************************************************************
1970 * WINE_Message [internal]
1972 DWORD MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1,
1973 DWORD dwParam2, BOOL bFrom32)
1975 LPWINE_MM_DRIVER lpDrv;
1977 WINE_MM_DRIVER_PART* part;
1978 WINE_LLTYPE* llType = &llTypes[mld->type];
1982 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1983 llTypes[mld->type].typestr, mld->uDeviceID, wMsg,
1984 mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
1986 if (mld->uDeviceID == (UINT16)-1) {
1987 if (!llType->bSupportMapper) {
1988 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1989 llTypes[mld->type].typestr);
1990 return MMSYSERR_BADDEVICEID;
1994 if (mld->uDeviceID >= llType->wMaxId) {
1995 WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
1996 return MMSYSERR_BADDEVICEID;
1998 devID = mld->uDeviceID;
2001 lpDrv = &MMDrvs[mld->mmdIndex];
2002 part = &lpDrv->parts[mld->type];
2005 /* some sanity checks */
2006 if (!(part->nIDMin <= devID))
2007 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
2008 if (!(devID < part->nIDMax))
2009 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
2013 assert(part->u.fnMessage32);
2016 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2017 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2018 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2019 TRACE("=> %lu\n", ret);
2021 map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
2023 case MMDRV_MAP_NOMEM:
2024 ret = MMSYSERR_NOMEM;
2026 case MMDRV_MAP_MSGERROR:
2027 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
2028 ret = MMSYSERR_ERROR;
2031 case MMDRV_MAP_OKMEM:
2032 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2033 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2034 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance,
2035 dwParam1, dwParam2);
2036 TRACE("=> %lu\n", ret);
2037 if (map == MMDRV_MAP_OKMEM)
2038 llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
2041 case MMDRV_MAP_PASS:
2042 FIXME("NIY: pass used ?\n");
2043 ret = MMSYSERR_NOTSUPPORTED;
2048 assert(part->u.fnMessage16);
2051 map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
2053 case MMDRV_MAP_NOMEM:
2054 ret = MMSYSERR_NOMEM;
2056 case MMDRV_MAP_MSGERROR:
2057 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
2058 ret = MMSYSERR_ERROR;
2061 case MMDRV_MAP_OKMEM:
2062 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2063 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2064 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
2065 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2066 TRACE("=> %lu\n", ret);
2067 if (map == MMDRV_MAP_OKMEM)
2068 llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
2071 case MMDRV_MAP_PASS:
2072 FIXME("NIY: pass used ?\n");
2073 ret = MMSYSERR_NOTSUPPORTED;
2077 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2078 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2079 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
2080 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
2081 TRACE("=> %lu\n", ret);
2087 /**************************************************************************
2088 * MMDRV_Alloc [internal]
2090 LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
2091 DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
2095 mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
2096 if (!mld) return NULL;
2098 /* find an empty slot in MM_MLDrvs table */
2099 for (*hndl = 0; *hndl < MAX_MM_MLDRVS; (*hndl)++) {
2100 if (!MM_MLDrvs[*hndl]) break;
2102 if (*hndl == MAX_MM_MLDRVS) {
2103 /* the MM_MLDrvs table could be made growable in the future if needed */
2104 ERR("Too many open drivers\n");
2107 MM_MLDrvs[*hndl] = mld;
2111 if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
2112 /* FIXME: those conditions must be fulfilled so that:
2113 * - we can distinguish between device IDs and handles
2114 * - we can use handles as 16 or 32 bit entities
2116 ERR("Shouldn't happen. Bad allocation scheme\n");
2119 mld->bFrom32 = bFrom32;
2120 mld->dwFlags = HIWORD(*dwFlags);
2121 mld->dwCallback = *dwCallback;
2122 mld->dwClientInstance = *dwInstance;
2124 *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
2125 *dwCallback = (DWORD)llTypes[type].Callback;
2126 *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2131 /**************************************************************************
2132 * MMDRV_Free [internal]
2134 void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
2136 if (hndl & 0x8000) {
2137 unsigned idx = hndl & ~0x8000;
2138 if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2139 MM_MLDrvs[idx] = NULL;
2140 HeapFree(GetProcessHeap(), 0, mld);
2144 ERR("Bad Handle %08x at %p (not freed)\n", hndl, mld);
2147 /**************************************************************************
2148 * MMDRV_Open [internal]
2150 DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
2152 DWORD dwRet = MMSYSERR_BADDEVICEID;
2154 WINE_LLTYPE* llType = &llTypes[mld->type];
2156 mld->dwDriverInstance = (DWORD)&dwInstance;
2158 if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
2159 TRACE("MAPPER mode requested !\n");
2160 /* check if mapper is supported by type */
2161 if (llType->bSupportMapper) {
2162 if (llType->nMapper == -1) {
2163 /* no driver for mapper has been loaded, try a dumb implementation */
2164 TRACE("No mapper loaded, doing it by hand\n");
2165 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
2166 if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
2167 /* to share this function epilog */
2168 dwInstance = mld->dwDriverInstance;
2173 mld->uDeviceID = (UINT16)-1;
2174 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
2175 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2176 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2180 if (mld->uDeviceID < llType->wMaxId) {
2181 mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
2182 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2183 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2186 if (dwRet == MMSYSERR_NOERROR)
2187 mld->dwDriverInstance = dwInstance;
2191 /**************************************************************************
2192 * MMDRV_Close [internal]
2194 DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
2196 return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
2199 /**************************************************************************
2200 * MMDRV_GetByID [internal]
2202 LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
2204 if (uDevID < llTypes[type].wMaxId)
2205 return &llTypes[type].lpMlds[uDevID];
2206 if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
2207 return &llTypes[type].lpMlds[-1];
2211 /**************************************************************************
2212 * MMDRV_Get [internal]
2214 LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
2216 LPWINE_MLD mld = NULL;
2218 assert(type < MMDRV_MAX);
2220 if ((UINT)hndl >= llTypes[type].wMaxId &&
2221 hndl != (UINT16)-1 && hndl != (UINT)-1) {
2222 if (hndl & 0x8000) {
2224 if (hndl < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
2225 mld = MM_MLDrvs[hndl];
2226 if (!mld || !HeapValidate(GetProcessHeap(), 0, mld) || mld->type != type)
2232 if (mld == NULL && bCanBeID) {
2233 mld = MMDRV_GetByID((UINT)hndl, type);
2238 /**************************************************************************
2239 * MMDRV_GetRelated [internal]
2241 LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
2242 BOOL bSrcCanBeID, UINT dstType)
2246 if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
2247 WINE_MM_DRIVER_PART* part = &MMDrvs[mld->mmdIndex].parts[dstType];
2248 if (part->nIDMin < part->nIDMax)
2249 return MMDRV_GetByID(part->nIDMin, dstType);
2254 /**************************************************************************
2255 * MMDRV_PhysicalFeatures [internal]
2257 UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
2260 WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
2262 TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
2264 /* all those function calls are undocumented */
2266 case DRV_QUERYDRVENTRY:
2267 lstrcpynA((LPSTR)dwParam1, lpDrv->drvname, LOWORD(dwParam2));
2269 case DRV_QUERYDEVNODE:
2270 *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
2273 WARN("NIY QueryName\n");
2275 case DRV_QUERYDRIVERIDS:
2276 WARN("NIY call VxD\n");
2277 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2278 * dwParam1 is buffer and dwParam2 is sizeof buffer
2279 * I don't know where the result is stored though
2282 case DRV_QUERYMAPPABLE:
2283 return (lpDrv->bIsMapper) ? 2 : 0;
2285 case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
2286 return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
2289 WARN("Unknown call %04x\n", uMsg);
2290 return MMSYSERR_INVALPARAM;
2295 /**************************************************************************
2296 * MMDRV_InitPerType [internal]
2298 static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT type, UINT wMsg)
2300 WINE_MM_DRIVER_PART* part = &lpDrv->parts[type];
2305 part->nIDMin = part->nIDMax = 0;
2307 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2308 /* the DRVM_ENABLE is only required when the PnP node is non zero */
2310 if (lpDrv->bIs32 && part->u.fnMessage32) {
2311 ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
2312 TRACE("DRVM_INIT => %08lx\n", ret);
2314 ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
2315 TRACE("DRVM_ENABLE => %08lx\n", ret);
2317 count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
2318 } else if (!lpDrv->bIs32 && part->u.fnMessage16) {
2319 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2320 0, DRVM_INIT, 0L, 0L, 0L);
2321 TRACE("DRVM_INIT => %08lx\n", ret);
2323 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2324 0, DRVM_ENABLE, 0L, 0L, 0L);
2325 TRACE("DRVM_ENABLE => %08lx\n", ret);
2327 count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2328 0, wMsg, 0L, 0L, 0L);
2333 TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->drvname, llTypes[type].typestr);
2335 /* got some drivers */
2336 if (lpDrv->bIsMapper) {
2337 /* it seems native mappers return 0 devices :-( */
2338 if (llTypes[type].nMapper != -1)
2339 ERR("Two mappers for type %s (%d, %s)\n",
2340 llTypes[type].typestr, llTypes[type].nMapper, lpDrv->drvname);
2342 ERR("Strange: mapper with %d > 1 devices\n", count);
2343 llTypes[type].nMapper = MMDrvsHi;
2347 part->nIDMin = llTypes[type].wMaxId;
2348 llTypes[type].wMaxId += count;
2349 part->nIDMax = llTypes[type].wMaxId;
2351 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2352 part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
2353 lpDrv->drvname, llTypes[type].typestr);
2354 /* realloc translation table */
2355 llTypes[type].lpMlds = (LPWINE_MLD)
2356 HeapReAlloc(GetProcessHeap(), 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
2357 sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
2358 /* re-build the translation table */
2359 if (llTypes[type].nMapper != -1) {
2360 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, -1, MMDrvs[llTypes[type].nMapper].drvname);
2361 llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
2362 llTypes[type].lpMlds[-1].type = type;
2363 llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
2364 llTypes[type].lpMlds[-1].dwDriverInstance = 0;
2366 for (i = k = 0; i <= MMDrvsHi; i++) {
2367 while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
2368 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, k, MMDrvs[i].drvname);
2369 llTypes[type].lpMlds[k].uDeviceID = k;
2370 llTypes[type].lpMlds[k].type = type;
2371 llTypes[type].lpMlds[k].mmdIndex = i;
2372 llTypes[type].lpMlds[k].dwDriverInstance = 0;
2379 /**************************************************************************
2380 * MMDRV_Install [internal]
2382 static BOOL MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
2386 LPWINE_MM_DRIVER lpDrv = &MMDrvs[MMDrvsHi];
2389 TRACE("('%s', '%s', mapper=%c);\n", drvRegName, drvFileName, bIsMapper ? 'Y' : 'N');
2391 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2392 * if not just increase size of MMDrvs */
2393 assert(MMDrvsHi <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
2395 for (i = 0; i < MMDrvsHi; i++) {
2396 if (!strcmp(drvRegName, MMDrvs[i].drvname)) return FALSE;
2399 memset(lpDrv, 0, sizeof(*lpDrv));
2401 if (!(lpDrv->hDriver = OpenDriverA(drvFileName, 0, 0))) {
2402 WARN("Couldn't open driver '%s'\n", drvFileName);
2406 d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
2407 lpDrv->bIs32 = (d->dwFlags & WINE_GDF_16BIT) ? FALSE : TRUE;
2409 /* Then look for xxxMessage functions */
2410 #define AA(_h,_w,_x,_y,_z) \
2411 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
2413 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2414 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2417 WINEMM_msgFunc32 func;
2419 if (d->d.d32.hModule) {
2420 #define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
2421 A(MMDRV_AUX, auxMessage);
2422 A(MMDRV_MIXER, mixMessage);
2423 A(MMDRV_MIDIIN, midMessage);
2424 A(MMDRV_MIDIOUT, modMessage);
2425 A(MMDRV_WAVEIN, widMessage);
2426 A(MMDRV_WAVEOUT, wodMessage);
2430 WINEMM_msgFunc16 func;
2433 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2434 * The beginning of the module description indicates the driver supports
2435 * waveform, auxiliary, and mixer devices. Use one of the following
2436 * device-type names, followed by a colon (:) to indicate the type of
2437 * device your driver supports. If the driver supports more than one
2438 * type of device, separate each device-type name with a comma (,).
2440 * wave for waveform audio devices
2441 * wavemapper for wave mappers
2442 * midi for MIDI audio devices
2443 * midimapper for midi mappers
2444 * aux for auxiliary audio devices
2445 * mixer for mixer devices
2448 if (d->d.d16.hDriver16) {
2449 HMODULE16 hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16);
2451 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
2452 A(MMDRV_AUX, auxMessage);
2453 A(MMDRV_MIXER, mixMessage);
2454 A(MMDRV_MIDIIN, midMessage);
2455 A(MMDRV_MIDIOUT, modMessage);
2456 A(MMDRV_WAVEIN, widMessage);
2457 A(MMDRV_WAVEOUT, wodMessage);
2463 if (TRACE_ON(mmsys)) {
2464 if ((lpDrv->bIs32) ? MMDRV_GetDescription32(drvFileName, buffer, sizeof(buffer)) :
2465 MMDRV_GetDescription16(drvFileName, buffer, sizeof(buffer)))
2466 TRACE("%s => %s\n", drvFileName, buffer);
2468 TRACE("%s => No description\n", drvFileName);
2472 CloseDriver(lpDrv->hDriver, 0, 0);
2473 WARN("No message functions found\n");
2477 /* FIXME: being a mapper or not should be known by another way */
2478 /* it's known for NE drvs (the description is of the form '*mapper: *'
2479 * I don't have any clue for PE drvs
2481 lpDrv->bIsMapper = bIsMapper;
2482 lpDrv->drvname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(drvRegName) + 1), drvRegName);
2484 /* Finish init and get the count of the devices */
2485 MMDRV_InitPerType(lpDrv, MMDRV_AUX, AUXDM_GETNUMDEVS);
2486 MMDRV_InitPerType(lpDrv, MMDRV_MIXER, MXDM_GETNUMDEVS);
2487 MMDRV_InitPerType(lpDrv, MMDRV_MIDIIN, MIDM_GETNUMDEVS);
2488 MMDRV_InitPerType(lpDrv, MMDRV_MIDIOUT, MODM_GETNUMDEVS);
2489 MMDRV_InitPerType(lpDrv, MMDRV_WAVEIN, WIDM_GETNUMDEVS);
2490 MMDRV_InitPerType(lpDrv, MMDRV_WAVEOUT, WODM_GETNUMDEVS);
2491 /* FIXME: if all those func calls return FALSE,
2492 * then the driver must be unloaded
2500 /**************************************************************************
2501 * MMDRV_InitFromRegistry [internal]
2503 static BOOL MMDRV_InitFromRegistry(void)
2512 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\WinMM", &hKey)) {
2513 TRACE("Cannot open WinMM config key\n");
2517 size = sizeof(buffer);
2518 if (!RegQueryValueExA(hKey, "Drivers", 0, &type, (LPVOID)buffer, &size)) {
2521 p2 = strchr(p1, ';');
2522 if (p2) *p2++ = '\0';
2523 ret |= MMDRV_Install(p1, p1, FALSE);
2528 /* finish with mappers */
2529 size = sizeof(buffer);
2530 if (!RegQueryValueExA(hKey, "WaveMapper", 0, &type, (LPVOID)buffer, &size))
2531 ret |= MMDRV_Install("wavemapper", buffer, TRUE);
2532 size = sizeof(buffer);
2533 if (!RegQueryValueExA(hKey, "MidiMapper", 0, &type, (LPVOID)buffer, &size))
2534 ret |= MMDRV_Install("midimapper", buffer, TRUE);
2541 /**************************************************************************
2542 * MMDRV_InitHardcoded [internal]
2544 static BOOL MMDRV_InitHardcoded(void)
2546 ERR("You didn't setup properly the config file for the Wine multimedia modules.\n"
2547 "Will use the hard-coded setup, but this will disapear soon.\n"
2548 "Please add a WinMM section to your Wine config file.\n");
2550 /* first load hardware drivers */
2551 MMDRV_Install("wineoss.drv", "wineoss.drv", FALSE);
2553 /* finish with mappers */
2554 MMDRV_Install("wavemapper", "msacm.drv", TRUE);
2555 MMDRV_Install("midimapper", "midimap.drv", TRUE);
2560 /**************************************************************************
2561 * MMDRV_Init [internal]
2563 BOOL MMDRV_Init(void)
2565 /* FIXME: MMDRV_InitFromRegistry shall be MMDRV_Init in a near future */
2566 return MMDRV_InitFromRegistry() || MMDRV_InitHardcoded();