1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * MMSYTEM low level drivers handling functions
6 * Copyright 1999 Eric Pouech
12 #include "user.h" /* should be removed asap; used in MMDRV_(Get|Alloc|Free) */
13 #include "selectors.h"
18 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(mmsys)
22 typedef DWORD CALLBACK (*WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
23 typedef DWORD CALLBACK (*WINEMM_msgFunc32)(UINT , UINT, DWORD, DWORD, DWORD);
25 /* for each loaded driver and each known type of driver, this structure contains
26 * the information needed to access it
28 typedef struct tagWINE_MM_DRIVER_PART {
29 int nIDMin; /* lower bound of global indexes for this type */
30 int nIDMax; /* hhigher bound of global indexes for this type */
32 WINEMM_msgFunc32 fnMessage32; /* pointer to fonction */
33 WINEMM_msgFunc16 fnMessage16;
35 } WINE_MM_DRIVER_PART;
37 /* each low-level .drv will be associated with an instance of this structure */
38 typedef struct tagWINE_MM_DRIVER {
39 HDRVR hDrvr; /* handle of loader driver */
40 LPSTR name; /* name of the driver */
41 BOOL bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */
42 bIsMapper : 1; /* TRUE if mapper */
43 WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */
44 } WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
47 MMDRV_MAP_NOMEM, /* ko, memory problem */
48 MMDRV_MAP_MSGERROR, /* ko, unknown message */
49 MMDRV_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
50 MMDRV_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
51 MMDRV_MAP_PASS /* not handled (no memory allocated) to be sent to the driver */
54 typedef MMDRV_MapType (*MMDRV_MAPFUNC )(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
56 /* each known type of driver has an instance of this structure */
57 typedef struct tagWINE_LLTYPE {
58 /* those attributes depend on the specification of the type */
59 LPSTR name; /* name (for debugging) */
60 BOOL bSupportMapper; /* if type is allowed to support mapper */
61 MMDRV_MAPFUNC Map16To32A; /* those are function pointers to handle */
62 MMDRV_MAPFUNC UnMap16To32A; /* the parameter conversion (16 vs 32 bit) */
63 MMDRV_MAPFUNC Map32ATo16; /* when hi-func (in mmsystem or winmm) and */
64 MMDRV_MAPFUNC UnMap32ATo16; /* low-func (in .drv) do not match */
65 LPDRVCALLBACK Callback; /* handles callback for a specified type */
66 /* those attributes reflect the loaded/current situation for the type */
67 UINT wMaxId; /* number of loaded devices (sum across all loaded drivers */
68 LPWINE_MLD lpMlds; /* "static" mlds to access the part though device IDs */
69 int nMapper; /* index to mapper */
72 static WINE_MM_DRIVER MMDrvs[3];
74 /* ### start build ### */
75 extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
76 /* ### stop build ### */
78 /**************************************************************************
79 * MMDRV_GetDescription16 [internal]
81 static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
89 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
90 ERR("Can't open file %s\n", fname);
94 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
96 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
97 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
98 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
99 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
100 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
101 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
102 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %lu\n", dw));
103 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
104 buflen = MIN((BYTE)buf[0], buflen - 1);
105 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
108 TRACE("Got '%s' [%d]\n", buf, buflen);
114 /**************************************************************************
115 * MMDRV_GetDescription32 [internal]
117 static BOOL MMDRV_GetDescription32(const char* fname, char* buf, int buflen)
127 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
129 if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR) E(("Can't find file %s\n", fname));
131 /* should load version.dll */
132 if (!(dw = GetFileVersionInfoSizeA(ofs.szPathName, &h))) E(("Can't get FVIS\n"));
133 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw))) E(("OOM\n"));
134 if (!GetFileVersionInfoA(ofs.szPathName, h, dw, ptr)) E(("Can't get FVI\n"));
136 #define A(_x) if (VerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
137 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
153 if (!VerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
154 lstrcpynA(buf, val, buflen);
159 HeapFree(GetProcessHeap(), 0, ptr);
163 /**************************************************************************
164 * MMDRV_Callback [internal]
166 static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
168 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
169 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
171 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
172 /* 16 bit func, call it */
173 TRACE("Function (16 bit) !\n");
174 MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, hDev, uMsg,
175 mld->dwClientInstance, dwParam1, dwParam2);
177 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
178 mld->dwClientInstance, dwParam1, dwParam2);
182 /* =================================
183 * A U X M A P P E R S
184 * ================================= */
186 /**************************************************************************
187 * MMDRV_Aux_Map16To32A [internal]
189 static MMDRV_MapType MMDRV_Aux_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
191 return MMDRV_MAP_MSGERROR;
194 /**************************************************************************
195 * MMDRV_Aux_UnMap16To32A [internal]
197 static MMDRV_MapType MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
199 return MMDRV_MAP_MSGERROR;
202 /**************************************************************************
203 * MMDRV_Aux_Map32ATo16 [internal]
205 static MMDRV_MapType MMDRV_Aux_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
207 return MMDRV_MAP_MSGERROR;
210 /**************************************************************************
211 * MMDRV_Aux_UnMap32ATo16 [internal]
213 static MMDRV_MapType MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
216 case AUXDM_GETDEVCAPS:
217 lpCaps->wMid = ac16.wMid;
218 lpCaps->wPid = ac16.wPid;
219 lpCaps->vDriverVersion = ac16.vDriverVersion;
220 strcpy(lpCaps->szPname, ac16.szPname);
221 lpCaps->wTechnology = ac16.wTechnology;
222 lpCaps->dwSupport = ac16.dwSupport;
224 return MMDRV_MAP_MSGERROR;
227 /**************************************************************************
228 * MMDRV_Aux_Callback [internal]
230 static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
232 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
235 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
238 /* =================================
239 * M I X E R M A P P E R S
240 * ================================= */
242 /**************************************************************************
243 * xMMDRV_Mixer_Map16To32A [internal]
245 static MMDRV_MapType MMDRV_Mixer_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
247 return MMDRV_MAP_MSGERROR;
250 /**************************************************************************
251 * MMDRV_Mixer_UnMap16To32A [internal]
253 static MMDRV_MapType MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
257 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
259 if (ret == MMSYSERR_NOERROR) {
260 mixcaps->wMid = micA.wMid;
261 mixcaps->wPid = micA.wPid;
262 mixcaps->vDriverVersion = micA.vDriverVersion;
263 strcpy(mixcaps->szPname, micA.szPname);
264 mixcaps->fdwSupport = micA.fdwSupport;
265 mixcaps->cDestinations = micA.cDestinations;
269 return MMDRV_MAP_MSGERROR;
272 /**************************************************************************
273 * MMDRV_Mixer_Map32ATo16 [internal]
275 static MMDRV_MapType MMDRV_Mixer_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
277 return MMDRV_MAP_MSGERROR;
280 /**************************************************************************
281 * MMDRV_Mixer_UnMap32ATo16 [internal]
283 static MMDRV_MapType MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
285 return MMDRV_MAP_MSGERROR;
288 /**************************************************************************
289 * MMDRV_Mixer_Callback [internal]
291 static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
293 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
296 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
299 /* =================================
300 * M I D I I N M A P P E R S
301 * ================================= */
303 /**************************************************************************
304 * MMDRV_MidiIn_Map16To32A [internal]
306 static MMDRV_MapType MMDRV_MidiIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
308 return MMDRV_MAP_MSGERROR;
311 /**************************************************************************
312 * MMDRV_MidiIn_UnMap16To32A [internal]
314 static MMDRV_MapType MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
316 return MMDRV_MAP_MSGERROR;
319 /**************************************************************************
320 * MMDRV_MidiIn_Map32ATo16 [internal]
322 static MMDRV_MapType MMDRV_MidiIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
324 return MMDRV_MAP_MSGERROR;
327 /**************************************************************************
328 * MMDRV_MidiIn_UnMap32ATo16 [internal]
330 static MMDRV_MapType MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
332 return MMDRV_MAP_MSGERROR;
335 /**************************************************************************
336 * MMDRV_MidiIn_Callback [internal]
338 static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
340 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
345 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
350 /* dwParam1 & dwParam2 are are data, nothing to do */
354 /* dwParam1 points to a MidiHdr, work to be done !!! */
355 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
356 /* initial map is: 32 => 16 */
357 LPMIDIHDR wh16 = (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1);
358 LPMIDIHDR wh32 = *(LPMIDIHDR*)((LPSTR)wh16 - sizeof(LPMIDIHDR));
360 dwParam1 = (DWORD)wh32;
361 wh32->dwFlags = wh16->dwFlags;
362 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
363 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
364 /* initial map is: 16 => 32 */
365 LPMIDIHDR wh32 = (LPMIDIHDR)(dwParam1);
366 LPMIDIHDR segwh16 = *(LPMIDIHDR*)((LPSTR)wh32 - sizeof(LPMIDIHDR));
367 LPMIDIHDR wh16 = PTR_SEG_TO_LIN(segwh16);
369 dwParam1 = (DWORD)segwh16;
370 wh16->dwFlags = wh32->dwFlags;
371 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
373 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
375 /* case MOM_POSITIONCB: */
377 ERR("Unknown msg %u\n", uMsg);
380 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
383 /* =================================
384 * M I D I O U T M A P P E R S
385 * ================================= */
387 /**************************************************************************
388 * MMDRV_MidiOut_Map16To32A [internal]
390 static MMDRV_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
392 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
395 case MODM_GETNUMDEVS:
404 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
407 case MODM_GETDEVCAPS:
409 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
410 LPMIDIOUTCAPS16 moc16 = PTR_SEG_TO_LIN(*lpParam1);
413 *(LPMIDIOUTCAPS16*)moc32 = moc16;
414 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
415 *lpParam1 = (DWORD)moc32;
416 *lpParam2 = sizeof(MIDIOUTCAPSA);
418 ret = MMDRV_MAP_OKMEM;
420 ret = MMDRV_MAP_NOMEM;
428 case MODM_CACHEPATCHES:
429 case MODM_CACHEDRUMPATCHES:
431 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
437 /**************************************************************************
438 * MMDRV_MidiOut_UnMap16To32A [internal]
440 static MMDRV_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
442 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
445 case MODM_GETNUMDEVS:
454 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
457 case MODM_GETDEVCAPS:
459 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
460 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
462 moc16->wMid = moc32->wMid;
463 moc16->wPid = moc32->wPid;
464 moc16->vDriverVersion = moc32->vDriverVersion;
465 strcpy(moc16->szPname, moc32->szPname);
466 moc16->wTechnology = moc32->wTechnology;
467 moc16->wVoices = moc32->wVoices;
468 moc16->wNotes = moc32->wNotes;
469 moc16->wChannelMask = moc32->wChannelMask;
470 moc16->dwSupport = moc32->dwSupport;
471 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
479 case MODM_CACHEPATCHES:
480 case MODM_CACHEDRUMPATCHES:
482 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
488 /**************************************************************************
489 * MMDRV_MidiOut_Map32ATo16 [internal]
491 static MMDRV_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
493 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
497 case MODM_GETNUMDEVS:
503 case MODM_GETDEVCAPS:
505 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
506 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMIDIOUTCAPSA) + sizeof(MIDIOUTCAPS16));
509 *(LPMIDIOUTCAPSA*)ptr = moc32;
510 ret = MMDRV_MAP_OKMEM;
512 ret = MMDRV_MAP_NOMEM;
514 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOUTCAPSA);
515 *lpParam2 = sizeof(MIDIOUTCAPS16);
523 case MODM_CACHEPATCHES:
524 case MODM_CACHEDRUMPATCHES:
526 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
532 /**************************************************************************
533 * MMDRV_MidiOut_UnMap32ATo16 [internal]
535 static MMDRV_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
537 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
541 case MODM_GETNUMDEVS:
547 case MODM_GETDEVCAPS:
549 LPMIDIOUTCAPS16 moc16 = (LPMIDIOUTCAPS16)PTR_SEG_TO_LIN(*lpParam1);
550 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
551 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
553 moc32->wMid = moc16->wMid;
554 moc32->wPid = moc16->wPid;
555 moc32->vDriverVersion = moc16->vDriverVersion;
556 strcpy(moc32->szPname, moc16->szPname);
557 moc32->wTechnology = moc16->wTechnology;
558 moc32->wVoices = moc16->wVoices;
559 moc32->wNotes = moc16->wNotes;
560 moc32->wChannelMask = moc16->wChannelMask;
561 moc32->dwSupport = moc16->dwSupport;
563 if (!SEGPTR_FREE(ptr))
564 FIXME("bad free line=%d\n", __LINE__);
573 case MODM_CACHEPATCHES:
574 case MODM_CACHEDRUMPATCHES:
576 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
582 /**************************************************************************
583 * MMDRV_MidiOut_Callback [internal]
585 static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
587 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
592 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
595 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
596 /* initial map is: 32 => 16 */
597 LPMIDIHDR wh16 = (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1);
598 LPMIDIHDR wh32 = *(LPMIDIHDR*)((LPSTR)wh16 - sizeof(LPMIDIHDR));
600 dwParam1 = (DWORD)wh32;
601 wh32->dwFlags = wh16->dwFlags;
602 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
603 /* initial map is: 16 => 32 */
604 LPMIDIHDR wh32 = (LPMIDIHDR)(dwParam1);
605 LPMIDIHDR segwh16 = *(LPMIDIHDR*)((LPSTR)wh32 - sizeof(LPMIDIHDR));
606 LPMIDIHDR wh16 = PTR_SEG_TO_LIN(segwh16);
608 dwParam1 = (DWORD)segwh16;
609 wh16->dwFlags = wh32->dwFlags;
611 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
613 /* case MOM_POSITIONCB: */
615 ERR("Unknown msg %u\n", uMsg);
618 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
621 /* =================================
622 * W A V E I N M A P P E R S
623 * ================================= */
625 /**************************************************************************
626 * MMDRV_WaveIn_Map16To32A [internal]
628 static MMDRV_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
630 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
633 case WIDM_GETNUMDEVS:
641 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
643 case WIDM_GETDEVCAPS:
645 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
646 LPWAVEINCAPS16 wic16 = PTR_SEG_TO_LIN(*lpParam1);
649 *(LPWAVEINCAPS16*)wic32 = wic16;
650 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
651 *lpParam1 = (DWORD)wic32;
652 *lpParam2 = sizeof(WAVEINCAPSA);
654 ret = MMDRV_MAP_OKMEM;
656 ret = MMDRV_MAP_NOMEM;
662 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
663 LPMMTIME16 mmt16 = PTR_SEG_TO_LIN(*lpParam1);
666 *(LPMMTIME16*)mmt32 = mmt16;
667 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
669 mmt32->wType = mmt16->wType;
670 *lpParam1 = (DWORD)mmt32;
671 *lpParam2 = sizeof(MMTIME);
673 ret = MMDRV_MAP_OKMEM;
675 ret = MMDRV_MAP_NOMEM;
681 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
682 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
685 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
686 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
687 wh32->lpData = PTR_SEG_TO_LIN(wh16->lpData);
688 wh32->dwBufferLength = wh16->dwBufferLength;
689 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
690 wh32->dwUser = wh16->dwUser;
691 wh32->dwFlags = wh16->dwFlags;
692 wh32->dwLoops = wh16->dwLoops;
693 /* FIXME: nothing on wh32->lpNext */
694 /* could link the wh32->lpNext at this level for memory house keeping */
695 wh16->lpNext = wh32; /* for reuse in unprepare and write */
696 *lpParam1 = (DWORD)wh32;
697 *lpParam2 = sizeof(WAVEHDR);
699 ret = MMDRV_MAP_OKMEM;
701 ret = MMDRV_MAP_NOMEM;
708 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
709 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
711 *lpParam1 = (DWORD)wh32;
712 *lpParam2 = sizeof(WAVEHDR);
713 ret = MMDRV_MAP_OKMEM;
717 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
718 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
724 /**************************************************************************
725 * MMDRV_WaveIn_UnMap16To32A [internal]
727 static MMDRV_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
729 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
732 case WIDM_GETNUMDEVS:
740 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
742 case WIDM_GETDEVCAPS:
744 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
745 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
747 wic16->wMid = wic32->wMid;
748 wic16->wPid = wic32->wPid;
749 wic16->vDriverVersion = wic32->vDriverVersion;
750 strcpy(wic16->szPname, wic32->szPname);
751 wic16->dwFormats = wic32->dwFormats;
752 wic16->wChannels = wic32->wChannels;
753 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
759 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
760 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
762 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
763 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
771 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
772 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
774 assert(wh16->lpNext == wh32);
775 wh16->dwBufferLength = wh32->dwBufferLength;
776 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
777 wh16->dwUser = wh32->dwUser;
778 wh16->dwFlags = wh32->dwFlags;
779 wh16->dwLoops = wh32->dwLoops;
781 if (wMsg == WIDM_UNPREPARE) {
782 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
789 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
795 /**************************************************************************
796 * MMDRV_WaveIn_Map32ATo16 [internal]
798 static MMDRV_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
800 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
804 case WIDM_GETNUMDEVS:
813 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
814 int sz = sizeof(WAVEFORMATEX);
816 LPWAVEOPENDESC16 wod16;
818 /* allocated data are mapped as follows:
819 LPWAVEOPENDESC ptr to orig lParam1
820 DWORD ptr to orig dwUser, which is a pointer to DWORD:driver dwInstance
821 DWORD dwUser passed to driver
822 WAVEOPENDESC16 wod16: openDesc passed to driver
823 WAVEFORMATEX openDesc->lpFormat passed to driver
824 xxx extra bytes to WAVEFORMATEX
826 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
827 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
828 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
831 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
834 *(LPWAVEOPENDESC*)ptr = wod32;
835 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
836 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
838 wod16->hWave = wod32->hWave;
839 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
840 memcpy(wod16 + 1, wod32->lpFormat, sz);
842 wod16->dwCallback = wod32->dwCallback;
843 wod16->dwInstance = wod32->dwInstance;
844 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
845 wod16->dnDevNode = wod32->dnDevNode;
847 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
848 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
850 ret = MMDRV_MAP_OKMEM;
852 ret = MMDRV_MAP_NOMEM;
858 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
860 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
863 *(LPWAVEHDR*)ptr = wh32;
864 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
865 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
866 /* data will be copied on WODM_WRITE */
867 wh16->dwBufferLength = wh32->dwBufferLength;
868 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
869 wh16->dwUser = wh32->dwUser;
870 wh16->dwFlags = wh32->dwFlags;
871 wh16->dwLoops = wh32->dwLoops;
872 /* FIXME: nothing on wh32->lpNext */
873 /* could link the wh32->lpNext at this level for memory house keeping */
874 wh32->lpNext = wh16; /* for reuse in unprepare and write */
875 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
876 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
877 wh32->dwBufferLength, (DWORD)wh32->lpData);
878 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
879 *lpParam2 = sizeof(WAVEHDR);
881 ret = MMDRV_MAP_OKMEM;
883 ret = MMDRV_MAP_NOMEM;
890 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
891 LPWAVEHDR wh16 = wh32->lpNext;
892 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
894 assert(*(LPWAVEHDR*)ptr == wh32);
896 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
897 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
898 wh32->dwBufferLength, (DWORD)wh32->lpData);
900 if (wMsg == WODM_WRITE)
901 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
903 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
904 *lpParam2 = sizeof(WAVEHDR);
905 ret = MMDRV_MAP_OKMEM;
908 case WIDM_GETDEVCAPS:
910 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
911 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
914 *(LPWAVEINCAPSA*)ptr = wic32;
915 ret = MMDRV_MAP_OKMEM;
917 ret = MMDRV_MAP_NOMEM;
919 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEINCAPSA);
920 *lpParam2 = sizeof(WAVEINCAPS16);
925 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
926 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
927 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
930 *(LPMMTIME*)ptr = mmt32;
931 mmt16->wType = mmt32->wType;
932 ret = MMDRV_MAP_OKMEM;
934 ret = MMDRV_MAP_NOMEM;
936 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
937 *lpParam2 = sizeof(MMTIME16);
941 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
947 /**************************************************************************
948 * MMDRV_WaveIn_UnMap32ATo16 [internal]
950 static MMDRV_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
952 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
956 case WIDM_GETNUMDEVS:
965 LPWAVEOPENDESC16 wod16 = (LPWAVEOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
966 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
967 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
969 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
970 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
972 if (!SEGPTR_FREE(ptr))
973 FIXME("bad free line=%d\n", __LINE__);
983 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(*lpParam1);
984 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
985 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
987 assert(wh32->lpNext == wh16);
988 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
989 wh32->dwUser = wh16->dwUser;
990 wh32->dwFlags = wh16->dwFlags;
991 wh32->dwLoops = wh16->dwLoops;
993 if (wMsg == WODM_UNPREPARE) {
994 if (!SEGPTR_FREE(ptr))
995 FIXME("bad free line=%d\n", __LINE__);
1001 case WIDM_GETDEVCAPS:
1003 LPWAVEINCAPS16 wic16 = (LPWAVEINCAPS16)PTR_SEG_TO_LIN(*lpParam1);
1004 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1005 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
1007 wic32->wMid = wic16->wMid;
1008 wic32->wPid = wic16->wPid;
1009 wic32->vDriverVersion = wic16->vDriverVersion;
1010 strcpy(wic32->szPname, wic16->szPname);
1011 wic32->dwFormats = wic16->dwFormats;
1012 wic32->wChannels = wic16->wChannels;
1013 if (!SEGPTR_FREE(ptr))
1014 FIXME("bad free line=%d\n", __LINE__);
1020 LPMMTIME16 mmt16 = (LPMMTIME16)PTR_SEG_TO_LIN(*lpParam1);
1021 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1022 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1024 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1026 if (!SEGPTR_FREE(ptr))
1027 FIXME("bad free line=%d\n", __LINE__);
1033 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1039 /**************************************************************************
1040 * MMDRV_WaveIn_Callback [internal]
1042 static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1044 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1049 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1052 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1053 /* initial map is: 32 => 16 */
1054 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1);
1055 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1057 dwParam1 = (DWORD)wh32;
1058 wh32->dwFlags = wh16->dwFlags;
1059 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1060 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1061 /* initial map is: 16 => 32 */
1062 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1063 LPWAVEHDR segwh16 = *(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1064 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(segwh16);
1066 dwParam1 = (DWORD)segwh16;
1067 wh16->dwFlags = wh32->dwFlags;
1068 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1070 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1073 ERR("Unknown msg %u\n", uMsg);
1076 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1079 /* =================================
1080 * W A V E O U T M A P P E R S
1081 * ================================= */
1083 /**************************************************************************
1084 * MMDRV_WaveOut_Map16To32A [internal]
1086 static MMDRV_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1088 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1092 case WODM_BREAKLOOP:
1094 case WODM_GETNUMDEVS:
1099 case WODM_SETPLAYBACKRATE:
1100 case WODM_SETVOLUME:
1105 case WODM_GETPLAYBACKRATE:
1106 case WODM_GETVOLUME:
1108 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1111 case WODM_GETDEVCAPS:
1113 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1114 LPWAVEOUTCAPS16 woc16 = PTR_SEG_TO_LIN(*lpParam1);
1117 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1118 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1119 *lpParam1 = (DWORD)woc32;
1120 *lpParam2 = sizeof(WAVEOUTCAPSA);
1122 ret = MMDRV_MAP_OKMEM;
1124 ret = MMDRV_MAP_NOMEM;
1130 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1131 LPMMTIME16 mmt16 = PTR_SEG_TO_LIN(*lpParam1);
1134 *(LPMMTIME16*)mmt32 = mmt16;
1135 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1137 mmt32->wType = mmt16->wType;
1138 *lpParam1 = (DWORD)mmt32;
1139 *lpParam2 = sizeof(MMTIME);
1141 ret = MMDRV_MAP_OKMEM;
1143 ret = MMDRV_MAP_NOMEM;
1149 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1150 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
1153 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1154 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1155 wh32->lpData = PTR_SEG_TO_LIN(wh16->lpData);
1156 wh32->dwBufferLength = wh16->dwBufferLength;
1157 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1158 wh32->dwUser = wh16->dwUser;
1159 wh32->dwFlags = wh16->dwFlags;
1160 wh32->dwLoops = wh16->dwLoops;
1161 /* FIXME: nothing on wh32->lpNext */
1162 /* could link the wh32->lpNext at this level for memory house keeping */
1163 wh16->lpNext = wh32; /* for reuse in unprepare and write */
1164 *lpParam1 = (DWORD)wh32;
1165 *lpParam2 = sizeof(WAVEHDR);
1167 ret = MMDRV_MAP_OKMEM;
1169 ret = MMDRV_MAP_NOMEM;
1173 case WODM_UNPREPARE:
1176 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
1177 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1179 *lpParam1 = (DWORD)wh32;
1180 *lpParam2 = sizeof(WAVEHDR);
1181 ret = MMDRV_MAP_OKMEM;
1185 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1191 /**************************************************************************
1192 * MMDRV_WaveOut_UnMap16To32A [internal]
1194 static MMDRV_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1196 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1200 case WODM_BREAKLOOP:
1202 case WODM_GETNUMDEVS:
1207 case WODM_SETPLAYBACKRATE:
1208 case WODM_SETVOLUME:
1213 case WODM_GETPLAYBACKRATE:
1214 case WODM_GETVOLUME:
1216 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1219 case WODM_GETDEVCAPS:
1221 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1222 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1224 woc16->wMid = woc32->wMid;
1225 woc16->wPid = woc32->wPid;
1226 woc16->vDriverVersion = woc32->vDriverVersion;
1227 strcpy(woc16->szPname, woc32->szPname);
1228 woc16->dwFormats = woc32->dwFormats;
1229 woc16->wChannels = woc32->wChannels;
1230 woc16->dwSupport = woc32->dwSupport;
1231 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1237 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1238 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1240 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1241 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1246 case WODM_UNPREPARE:
1249 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1250 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1252 assert(wh16->lpNext == wh32);
1253 wh16->dwBufferLength = wh32->dwBufferLength;
1254 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1255 wh16->dwUser = wh32->dwUser;
1256 wh16->dwFlags = wh32->dwFlags;
1257 wh16->dwLoops = wh32->dwLoops;
1259 if (wMsg == WODM_UNPREPARE) {
1260 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1267 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
1273 /**************************************************************************
1274 * MMDRV_WaveOut_Map32ATo16 [internal]
1276 static MMDRV_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1282 case WODM_BREAKLOOP:
1284 case WODM_GETNUMDEVS:
1289 case WODM_SETPLAYBACKRATE:
1290 case WODM_SETVOLUME:
1294 case WODM_GETDEVCAPS:
1296 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1297 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1300 *(LPWAVEOUTCAPSA*)ptr = woc32;
1301 ret = MMDRV_MAP_OKMEM;
1303 ret = MMDRV_MAP_NOMEM;
1305 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOUTCAPSA);
1306 *lpParam2 = sizeof(WAVEOUTCAPS16);
1310 FIXME("NIY: no conversion yet\n");
1311 ret = MMDRV_MAP_MSGERROR;
1313 case WODM_GETPLAYBACKRATE:
1314 FIXME("NIY: no conversion yet\n");
1315 ret = MMDRV_MAP_MSGERROR;
1319 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1320 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
1321 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1324 *(LPMMTIME*)ptr = mmt32;
1325 mmt16->wType = mmt32->wType;
1326 ret = MMDRV_MAP_OKMEM;
1328 ret = MMDRV_MAP_NOMEM;
1330 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
1331 *lpParam2 = sizeof(MMTIME16);
1334 case WODM_GETVOLUME:
1335 FIXME("NIY: no conversion yet\n");
1336 ret = MMDRV_MAP_MSGERROR;
1340 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1341 int sz = sizeof(WAVEFORMATEX);
1343 LPWAVEOPENDESC16 wod16;
1345 /* allocated data are mapped as follows:
1346 LPWAVEOPENDESC ptr to orig lParam1
1347 DWORD ptr to orig dwUser, which is a pointer to DWORD:driver dwInstance
1348 DWORD dwUser passed to driver
1349 WAVEOPENDESC16 wod16: openDesc passed to driver
1350 WAVEFORMATEX openDesc->lpFormat passed to driver
1351 xxx extra bytes to WAVEFORMATEX
1353 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1354 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1355 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1358 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1361 *(LPWAVEOPENDESC*)ptr = wod32;
1362 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1363 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1365 wod16->hWave = wod32->hWave;
1366 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1367 memcpy(wod16 + 1, wod32->lpFormat, sz);
1369 wod16->dwCallback = wod32->dwCallback;
1370 wod16->dwInstance = wod32->dwInstance;
1371 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1372 wod16->dnDevNode = wod32->dnDevNode;
1374 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1375 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1377 ret = MMDRV_MAP_OKMEM;
1379 ret = MMDRV_MAP_NOMEM;
1385 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1387 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1390 *(LPWAVEHDR*)ptr = wh32;
1391 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1392 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1393 /* data will be copied on WODM_WRITE */
1394 wh16->dwBufferLength = wh32->dwBufferLength;
1395 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1396 wh16->dwUser = wh32->dwUser;
1397 wh16->dwFlags = wh32->dwFlags;
1398 wh16->dwLoops = wh32->dwLoops;
1399 /* FIXME: nothing on wh32->lpNext */
1400 /* could link the wh32->lpNext at this level for memory house keeping */
1401 wh32->lpNext = wh16; /* for reuse in unprepare and write */
1402 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1403 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1404 wh32->dwBufferLength, (DWORD)wh32->lpData);
1405 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1406 *lpParam2 = sizeof(WAVEHDR);
1408 ret = MMDRV_MAP_OKMEM;
1410 ret = MMDRV_MAP_NOMEM;
1414 case WODM_UNPREPARE:
1417 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1418 LPWAVEHDR wh16 = wh32->lpNext;
1419 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1421 assert(*(LPWAVEHDR*)ptr == wh32);
1423 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1424 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1425 wh32->dwBufferLength, (DWORD)wh32->lpData);
1427 if (wMsg == WODM_WRITE)
1428 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1430 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1431 *lpParam2 = sizeof(WAVEHDR);
1432 ret = MMDRV_MAP_OKMEM;
1436 FIXME("NIY: no conversion yet\n");
1437 ret = MMDRV_MAP_MSGERROR;
1443 /**************************************************************************
1444 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1446 static MMDRV_MapType MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1452 case WODM_BREAKLOOP:
1454 case WODM_GETNUMDEVS:
1459 case WODM_SETPLAYBACKRATE:
1460 case WODM_SETVOLUME:
1464 case WODM_GETDEVCAPS:
1466 LPWAVEOUTCAPS16 woc16 = (LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(*lpParam1);
1467 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1468 LPWAVEOUTCAPSA woc32 = *(LPWAVEOUTCAPSA*)ptr;
1470 woc32->wMid = woc16->wMid;
1471 woc32->wPid = woc16->wPid;
1472 woc32->vDriverVersion = woc16->vDriverVersion;
1473 strcpy(woc32->szPname, woc16->szPname);
1474 woc32->dwFormats = woc16->dwFormats;
1475 woc32->wChannels = woc16->wChannels;
1476 woc32->dwSupport = woc16->dwSupport;
1477 if (!SEGPTR_FREE(ptr))
1478 FIXME("bad free line=%d\n", __LINE__);
1483 FIXME("NIY: no conversion yet\n");
1484 ret = MMDRV_MAP_MSGERROR;
1486 case WODM_GETPLAYBACKRATE:
1487 FIXME("NIY: no conversion yet\n");
1488 ret = MMDRV_MAP_MSGERROR;
1492 LPMMTIME16 mmt16 = (LPMMTIME16)PTR_SEG_TO_LIN(*lpParam1);
1493 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1494 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1496 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1498 if (!SEGPTR_FREE(ptr))
1499 FIXME("bad free line=%d\n", __LINE__);
1506 LPWAVEOPENDESC16 wod16 = (LPWAVEOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
1507 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1508 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1510 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1511 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1513 if (!SEGPTR_FREE(ptr))
1514 FIXME("bad free line=%d\n", __LINE__);
1520 case WODM_UNPREPARE:
1523 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(*lpParam1);
1524 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1525 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1527 assert(wh32->lpNext == wh16);
1528 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1529 wh32->dwUser = wh16->dwUser;
1530 wh32->dwFlags = wh16->dwFlags;
1531 wh32->dwLoops = wh16->dwLoops;
1533 if (wMsg == WODM_UNPREPARE) {
1534 if (!SEGPTR_FREE(ptr))
1535 FIXME("bad free line=%d\n", __LINE__);
1541 case WODM_GETVOLUME:
1542 FIXME("NIY: no conversion yet\n");
1543 ret = MMDRV_MAP_MSGERROR;
1546 FIXME("NIY: no conversion yet\n");
1547 ret = MMDRV_MAP_MSGERROR;
1553 /**************************************************************************
1554 * MMDRV_WaveOut_Callback [internal]
1556 static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1558 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1563 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1566 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1567 /* initial map is: 32 => 16 */
1568 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1);
1569 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1571 dwParam1 = (DWORD)wh32;
1572 wh32->dwFlags = wh16->dwFlags;
1573 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1574 /* initial map is: 16 => 32 */
1575 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1576 LPWAVEHDR segwh16 = *(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1577 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(segwh16);
1579 dwParam1 = (DWORD)segwh16;
1580 wh16->dwFlags = wh32->dwFlags;
1582 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1585 ERR("Unknown msg %u\n", uMsg);
1588 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1591 #define A(_x,_y) {#_y, _x, \
1592 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1593 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1594 MMDRV_##_y##_Callback, 0, NULL, -1}
1596 /* Note: the indices of this array must match the definitions
1597 * of the MMDRV_???? manifest constants
1599 static WINE_LLTYPE llTypes[MMDRV_MAX] = {
1609 /**************************************************************************
1610 * MMDRV_GetNum [internal]
1612 UINT MMDRV_GetNum(UINT type)
1614 assert(type < MMDRV_MAX);
1615 return llTypes[type].wMaxId;
1618 /**************************************************************************
1619 * WINE_Message [internal]
1621 DWORD MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1,
1622 DWORD dwParam2, BOOL bFrom32)
1624 LPWINE_MM_DRIVER lpDrv;
1626 WINE_MM_DRIVER_PART* part;
1627 WINE_LLTYPE* llType = &llTypes[mld->type];
1631 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1632 llTypes[mld->type].name, mld->uDeviceID, wMsg,
1633 mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
1635 if (mld->uDeviceID == (UINT16)-1) {
1636 if (!llType->bSupportMapper) {
1637 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1638 llTypes[mld->type].name);
1639 return MMSYSERR_BADDEVICEID;
1643 if (mld->uDeviceID >= llType->wMaxId) {
1644 WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
1645 return MMSYSERR_BADDEVICEID;
1647 devID = mld->uDeviceID;
1650 lpDrv = &MMDrvs[mld->mmdIndex];
1651 part = &lpDrv->parts[mld->type];
1654 /* some sanity checks */
1655 if (!(part->nIDMin <= devID))
1656 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
1657 if (!(devID < part->nIDMax))
1658 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
1662 assert(part->u.fnMessage32);
1665 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1666 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1667 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1668 TRACE("=> %lu\n", ret);
1670 map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1672 case MMDRV_MAP_NOMEM:
1673 ret = MMSYSERR_NOMEM;
1675 case MMDRV_MAP_MSGERROR:
1676 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
1677 ret = MMSYSERR_ERROR;
1680 case MMDRV_MAP_OKMEM:
1681 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1682 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1683 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance,
1684 dwParam1, dwParam2);
1685 TRACE("=> %lu\n", ret);
1686 if (map == MMDRV_MAP_OKMEM)
1687 llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1690 case MMDRV_MAP_PASS:
1691 FIXME("NIY: pass used ?\n");
1692 ret = MMSYSERR_NOTSUPPORTED;
1697 assert(part->u.fnMessage16);
1700 map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1702 case MMDRV_MAP_NOMEM:
1703 ret = MMSYSERR_NOMEM;
1705 case MMDRV_MAP_MSGERROR:
1706 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
1707 ret = MMSYSERR_ERROR;
1710 case MMDRV_MAP_OKMEM:
1711 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1712 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1713 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1714 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1715 TRACE("=> %lu\n", ret);
1716 if (map == MMDRV_MAP_OKMEM)
1717 llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1720 case MMDRV_MAP_PASS:
1721 FIXME("NIY: pass used ?\n");
1722 ret = MMSYSERR_NOTSUPPORTED;
1726 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1727 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1728 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1729 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1730 TRACE("=> %lu\n", ret);
1736 /**************************************************************************
1737 * MMDRV_Alloc [internal]
1739 LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
1740 DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
1744 if ((*hndl = USER_HEAP_ALLOC(size)) == 0)
1747 mld = (LPWINE_MLD) USER_HEAP_LIN_ADDR(*hndl);
1748 if (!mld) return NULL;
1750 if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
1751 /* FIXME: those conditions must be fulfilled so that:
1752 * - we can distinguish between device IDs and handles
1753 * - we can use handles as 16 or 32 bit entities
1755 ERR("Shouldn't happen. Bad allocation scheme\n");
1758 mld->bFrom32 = bFrom32;
1759 mld->dwFlags = HIWORD(*dwFlags);
1760 mld->dwCallback = *dwCallback;
1761 mld->dwClientInstance = *dwInstance;
1763 *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
1764 *dwCallback = (DWORD)llTypes[type].Callback;
1765 *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
1770 /**************************************************************************
1771 * MMDRV_Free [internal]
1773 void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
1775 USER_HEAP_FREE(hndl);
1778 /**************************************************************************
1779 * MMDRV_Open [internal]
1781 DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
1783 DWORD dwRet = MMSYSERR_BADDEVICEID;
1785 WINE_LLTYPE* llType = &llTypes[mld->type];
1787 mld->dwDriverInstance = (DWORD)&dwInstance;
1789 if (mld->uDeviceID == (UINT)-1) {
1790 TRACE("MAPPER mode requested !\n");
1791 /* check if mapper is supported by type */
1792 if (llType->bSupportMapper) {
1793 if (llType->nMapper == -1) {
1794 /* no driver for mapper has been loaded, try a dumb implementation */
1795 TRACE("No mapper loaded, doing it by hand\n");
1796 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
1797 if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
1798 /* to share this function epilog */
1799 dwInstance = mld->dwDriverInstance;
1804 mld->uDeviceID = (UINT16)-1;
1805 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
1806 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
1807 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
1811 if (mld->uDeviceID < llType->wMaxId) {
1812 mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
1813 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
1814 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
1817 if (dwRet == MMSYSERR_NOERROR)
1818 mld->dwDriverInstance = dwInstance;
1822 /**************************************************************************
1823 * MMDRV_Close [internal]
1825 DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
1827 return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
1830 /**************************************************************************
1831 * MMDRV_GetByID [internal]
1833 LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
1835 if (uDevID < llTypes[type].wMaxId)
1836 return &llTypes[type].lpMlds[uDevID];
1837 if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
1838 return &llTypes[type].lpMlds[-1];
1842 /**************************************************************************
1843 * MMDRV_Get [internal]
1845 LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
1847 LPWINE_MLD mld = NULL;
1849 assert(type < MMDRV_MAX);
1851 if ((UINT)hndl >= llTypes[type].wMaxId) {
1852 mld = (LPWINE_MLD)USER_HEAP_LIN_ADDR(hndl);
1854 if (!IsBadWritePtr(mld, sizeof(*mld)) && mld->type != type) mld = NULL;
1856 if (mld == NULL && bCanBeID) {
1857 mld = MMDRV_GetByID((UINT)hndl, type);
1862 /**************************************************************************
1863 * MMDRV_GetRelated [internal]
1865 LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
1866 BOOL bSrcCanBeID, UINT dstType)
1870 if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
1871 WINE_MM_DRIVER_PART* part = &MMDrvs[mld->mmdIndex].parts[dstType];
1872 if (part->nIDMin < part->nIDMax)
1873 return MMDRV_GetByID(part->nIDMin, dstType);
1878 /**************************************************************************
1879 * MMDRV_PhysicalFeatures [internal]
1881 UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
1884 WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
1886 TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
1888 /* all those function calls are undocumented */
1890 case 0x801: /* DRV_QUERYDRVENTRY */
1891 lstrcpynA((LPSTR)dwParam1, lpDrv->name, LOWORD(dwParam2));
1893 case 0x802: /* DRV_QUERYDEVNODE */
1894 *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
1896 case 0x803: /* DRV_QUERYNAME */
1897 WARN("NIY 0x803\n");
1899 case 0x804: /* DRV_QUERYDRIVERIDS */
1900 WARN("NIY call VxD\n");
1901 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
1902 * dwParam1 is buffer and dwParam2 is sizeof buffer
1903 * I don't know where the result is stored though
1906 case 0x805: /* DRV_QUERYMAPPABLE */
1907 return (lpDrv->bIsMapper) ? 2 : 0;
1909 WARN("Unknown call %04x\n", uMsg);
1910 return MMSYSERR_INVALPARAM;
1915 /**************************************************************************
1916 * MMDRV_InitPerType [internal]
1918 static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT num,
1919 UINT type, UINT wMsg)
1921 WINE_MM_DRIVER_PART* part = &lpDrv->parts[type];
1926 part->nIDMin = part->nIDMax = 0;
1928 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
1929 /* the DRVM_ENABLE is only required when the PnP node is non zero */
1931 if (lpDrv->bIs32 && part->u.fnMessage32) {
1932 ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
1933 TRACE("DRVM_INIT => %08lx\n", ret);
1935 ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
1936 TRACE("DRVM_ENABLE => %08lx\n", ret);
1938 count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
1941 if (!lpDrv->bIs32 && part->u.fnMessage16) {
1942 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1943 0, DRVM_INIT, 0L, 0L, 0L);
1944 TRACE("DRVM_INIT => %08lx\n", ret);
1946 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1947 0, DRVM_ENABLE, 0L, 0L, 0L);
1948 TRACE("DRVM_ENABLE => %08lx\n", ret);
1950 count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1951 0, wMsg, 0L, 0L, 0L);
1954 TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->name, llTypes[type].name);
1958 /* got some drivers */
1959 if (lpDrv->bIsMapper) {
1960 if (llTypes[type].nMapper != -1)
1961 ERR("Two mappers for type %s (%d, %s)\n",
1962 llTypes[type].name, llTypes[type].nMapper, lpDrv->name);
1964 ERR("Strange: mapper with %d > 1 devices\n", count);
1965 llTypes[type].nMapper = num;
1967 part->nIDMin = llTypes[type].wMaxId;
1968 llTypes[type].wMaxId += count;
1969 part->nIDMax = llTypes[type].wMaxId;
1971 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
1972 part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
1973 lpDrv->name, llTypes[type].name);
1974 /* realloc translation table */
1975 llTypes[type].lpMlds = (LPWINE_MLD)
1976 HeapReAlloc(SystemHeap, 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
1977 sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
1978 /* re-build the translation table */
1979 if (llTypes[type].nMapper != -1) {
1980 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].name, -1, MMDrvs[llTypes[type].nMapper].name);
1981 llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
1982 llTypes[type].lpMlds[-1].type = type;
1983 llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
1984 llTypes[type].lpMlds[-1].dwDriverInstance = 0;
1986 for (i = k = 0; i <= num; i++) {
1987 while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
1988 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].name, k, MMDrvs[i].name);
1989 llTypes[type].lpMlds[k].uDeviceID = k;
1990 llTypes[type].lpMlds[k].type = type;
1991 llTypes[type].lpMlds[k].mmdIndex = i;
1992 llTypes[type].lpMlds[k].dwDriverInstance = 0;
1999 /**************************************************************************
2000 * MMDRV_Install [internal]
2002 static BOOL MMDRV_Install(LPCSTR name, int num, BOOL bIsMapper)
2007 LPWINE_MM_DRIVER lpDrv = &MMDrvs[num];
2009 TRACE("('%s');\n", name);
2011 memset(lpDrv, 0, sizeof(*lpDrv));
2013 /* First load driver */
2014 if ((lpDrv->hDrvr = OpenDriverA(name, 0, 0)) == 0) {
2015 WARN("Couldn't open driver '%s'\n", name);
2019 /* Then look for xxxMessage functions */
2020 #define AA(_w,_x,_y,_z) \
2021 func = (WINEMM_msgFunc##_y) _z (hModule, #_x); \
2023 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2024 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2026 if ((DRIVER_GetType(lpDrv->hDrvr) & WINE_DI_TYPE_MASK) == WINE_DI_TYPE_32) {
2027 WINEMM_msgFunc32 func;
2029 lpDrv->bIs32 = TRUE;
2030 if ((hModule = GetDriverModuleHandle(lpDrv->hDrvr))) {
2031 #define A(_x,_y) AA(_x,_y,32,GetProcAddress)
2032 A(MMDRV_AUX, auxMessage);
2033 A(MMDRV_MIXER, mixMessage);
2034 A(MMDRV_MIDIIN, midMessage);
2035 A(MMDRV_MIDIOUT, modMessage);
2036 A(MMDRV_WAVEIN, widMessage);
2037 A(MMDRV_WAVEOUT, wodMessage);
2041 WINEMM_msgFunc16 func;
2044 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2045 * The beginning of the module description indicates the driver supports
2046 * waveform, auxiliary, and mixer devices. Use one of the following
2047 * device-type names, followed by a colon (:) to indicate the type of
2048 * device your driver supports. If the driver supports more than one
2049 * type of device, separate each device-type name with a comma (,).
2051 * wave for waveform audio devices
2052 * wavemapper for wave mappers
2053 * midi for MIDI audio devices
2054 * midimapper for midi mappers
2055 * aux for auxiliary audio devices
2056 * mixer for mixer devices
2059 lpDrv->bIs32 = FALSE;
2060 if ((hModule = GetDriverModuleHandle16(lpDrv->hDrvr))) {
2061 #define A(_x,_y) AA(_x,_y,16,WIN32_GetProcAddress16)
2062 A(MMDRV_AUX, auxMessage);
2063 A(MMDRV_MIXER, mixMessage);
2064 A(MMDRV_MIDIIN, midMessage);
2065 A(MMDRV_MIDIOUT, modMessage);
2066 A(MMDRV_WAVEIN, widMessage);
2067 A(MMDRV_WAVEOUT, wodMessage);
2073 if (TRACE_ON(mmsys)) {
2074 if ((lpDrv->bIs32) ? MMDRV_GetDescription32(name, buffer, sizeof(buffer)) :
2075 MMDRV_GetDescription16(name, buffer, sizeof(buffer)))
2076 TRACE("%s => %s\n", name, buffer);
2078 TRACE("%s => No description\n", name);
2082 CloseDriver(lpDrv->hDrvr, 0, 0);
2083 WARN("No message functions found\n");
2087 /* FIXME: being a mapper or not should be known by another way */
2088 /* it's known for NE drvs (the description is of the form '*mapper: *'
2089 * I don't have any clue for PE drvs
2090 * on Win 9x, the value is gotten from the key mappable under
2091 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\MediaResources\
2093 lpDrv->bIsMapper = bIsMapper;
2094 lpDrv->name = HEAP_strdupA(GetProcessHeap(), 0, name);
2096 /* Finish init and get the count of the devices */
2097 MMDRV_InitPerType(lpDrv, num, MMDRV_AUX, AUXDM_GETNUMDEVS);
2098 MMDRV_InitPerType(lpDrv, num, MMDRV_MIXER, MXDM_GETNUMDEVS);
2099 MMDRV_InitPerType(lpDrv, num, MMDRV_MIDIIN, MIDM_GETNUMDEVS);
2100 MMDRV_InitPerType(lpDrv, num, MMDRV_MIDIOUT, MODM_GETNUMDEVS);
2101 MMDRV_InitPerType(lpDrv, num, MMDRV_WAVEIN, WIDM_GETNUMDEVS);
2102 MMDRV_InitPerType(lpDrv, num, MMDRV_WAVEOUT, WODM_GETNUMDEVS);
2103 /* FIXME: if all those func calls return FALSE, then the driver must be unloaded */
2107 /**************************************************************************
2108 * MMDRV_Init [internal]
2110 BOOL MMDRV_Init(void)
2114 /* FIXME: this should be moved to init files;
2115 * - either .winerc/wine.conf
2116 * - or made of registry keys
2117 * this is a temporary hack, shall be removed anytime now
2119 /* first load hardware drivers */
2120 if (MMDRV_Install("wineoss.drv", num, FALSE)) num++;
2122 /* finish with mappers */
2123 if (MMDRV_Install("msacm.drv", num, TRUE )) num++;
2124 if (MMDRV_Install("midimap.drv", num, TRUE )) num++;
2127 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2128 * if not just increase size of MMDrvs */
2129 assert(num <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));