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 strncpy(buf
, val
, buflen
- 1);
155 buf
[buflen
- 1] = '\0';
160 HeapFree(GetProcessHeap(), 0, ptr
);
164 /**************************************************************************
165 * MMDRV_Callback [internal]
167 static void MMDRV_Callback(LPWINE_MLD mld
, HDRVR hDev
, UINT uMsg
, DWORD dwParam1
, DWORD dwParam2
)
169 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
170 mld
->dwCallback
, hDev
, uMsg
, mld
->dwClientInstance
, dwParam1
, dwParam2
);
172 if (!mld
->bFrom32
&& (mld
->dwFlags
& DCB_TYPEMASK
) == DCB_FUNCTION
) {
173 /* 16 bit func, call it */
174 TRACE("Function (16 bit) !\n");
175 MMDRV_CallTo16_word_wwlll((FARPROC16
)mld
->dwCallback
, hDev
, uMsg
,
176 mld
->dwClientInstance
, dwParam1
, dwParam2
);
178 DriverCallback(mld
->dwCallback
, mld
->dwFlags
, hDev
, uMsg
,
179 mld
->dwClientInstance
, dwParam1
, dwParam2
);
183 /* =================================
184 * A U X M A P P E R S
185 * ================================= */
187 /**************************************************************************
188 * MMDRV_Aux_Map16To32A [internal]
190 static MMDRV_MapType
MMDRV_Aux_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
192 return MMDRV_MAP_MSGERROR
;
195 /**************************************************************************
196 * MMDRV_Aux_UnMap16To32A [internal]
198 static MMDRV_MapType
MMDRV_Aux_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
200 return MMDRV_MAP_MSGERROR
;
203 /**************************************************************************
204 * MMDRV_Aux_Map32ATo16 [internal]
206 static MMDRV_MapType
MMDRV_Aux_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
208 return MMDRV_MAP_MSGERROR
;
211 /**************************************************************************
212 * MMDRV_Aux_UnMap32ATo16 [internal]
214 static MMDRV_MapType
MMDRV_Aux_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
217 case AUXDM_GETDEVCAPS
:
218 lpCaps
->wMid
= ac16
.wMid
;
219 lpCaps
->wPid
= ac16
.wPid
;
220 lpCaps
->vDriverVersion
= ac16
.vDriverVersion
;
221 strcpy(lpCaps
->szPname
, ac16
.szPname
);
222 lpCaps
->wTechnology
= ac16
.wTechnology
;
223 lpCaps
->dwSupport
= ac16
.dwSupport
;
225 return MMDRV_MAP_MSGERROR
;
228 /**************************************************************************
229 * MMDRV_Aux_Callback [internal]
231 static void CALLBACK
MMDRV_Aux_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
233 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
236 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
239 /* =================================
240 * M I X E R M A P P E R S
241 * ================================= */
243 /**************************************************************************
244 * xMMDRV_Mixer_Map16To32A [internal]
246 static MMDRV_MapType
MMDRV_Mixer_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
248 return MMDRV_MAP_MSGERROR
;
251 /**************************************************************************
252 * MMDRV_Mixer_UnMap16To32A [internal]
254 static MMDRV_MapType
MMDRV_Mixer_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
258 UINT ret
= mixerGetDevCapsA(devid
, &micA
, sizeof(micA
));
260 if (ret
== MMSYSERR_NOERROR
) {
261 mixcaps
->wMid
= micA
.wMid
;
262 mixcaps
->wPid
= micA
.wPid
;
263 mixcaps
->vDriverVersion
= micA
.vDriverVersion
;
264 strcpy(mixcaps
->szPname
, micA
.szPname
);
265 mixcaps
->fdwSupport
= micA
.fdwSupport
;
266 mixcaps
->cDestinations
= micA
.cDestinations
;
270 return MMDRV_MAP_MSGERROR
;
273 /**************************************************************************
274 * MMDRV_Mixer_Map32ATo16 [internal]
276 static MMDRV_MapType
MMDRV_Mixer_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
278 return MMDRV_MAP_MSGERROR
;
281 /**************************************************************************
282 * MMDRV_Mixer_UnMap32ATo16 [internal]
284 static MMDRV_MapType
MMDRV_Mixer_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
286 return MMDRV_MAP_MSGERROR
;
289 /**************************************************************************
290 * MMDRV_Mixer_Callback [internal]
292 static void CALLBACK
MMDRV_Mixer_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
294 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
297 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
300 /* =================================
301 * M I D I I N M A P P E R S
302 * ================================= */
304 /**************************************************************************
305 * MMDRV_MidiIn_Map16To32A [internal]
307 static MMDRV_MapType
MMDRV_MidiIn_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
309 return MMDRV_MAP_MSGERROR
;
312 /**************************************************************************
313 * MMDRV_MidiIn_UnMap16To32A [internal]
315 static MMDRV_MapType
MMDRV_MidiIn_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
317 return MMDRV_MAP_MSGERROR
;
320 /**************************************************************************
321 * MMDRV_MidiIn_Map32ATo16 [internal]
323 static MMDRV_MapType
MMDRV_MidiIn_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
325 return MMDRV_MAP_MSGERROR
;
328 /**************************************************************************
329 * MMDRV_MidiIn_UnMap32ATo16 [internal]
331 static MMDRV_MapType
MMDRV_MidiIn_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
333 return MMDRV_MAP_MSGERROR
;
336 /**************************************************************************
337 * MMDRV_MidiIn_Callback [internal]
339 static void CALLBACK
MMDRV_MidiIn_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
341 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
344 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
347 /* =================================
348 * M I D I O U T M A P P E R S
349 * ================================= */
351 /**************************************************************************
352 * MMDRV_MidiOut_Map16To32A [internal]
354 static MMDRV_MapType
MMDRV_MidiOut_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
356 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
359 case MODM_GETNUMDEVS
:
368 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
371 case MODM_GETDEVCAPS
:
373 LPMIDIOUTCAPSA moc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16
) + sizeof(MIDIOUTCAPSA
));
374 LPMIDIOUTCAPS16 moc16
= PTR_SEG_TO_LIN(*lpParam1
);
377 *(LPMIDIOUTCAPS16
*)moc32
= moc16
;
378 moc32
= (LPMIDIOUTCAPSA
)((LPSTR
)moc32
+ sizeof(LPMIDIOUTCAPS16
));
379 *lpParam1
= (DWORD
)moc32
;
380 *lpParam2
= sizeof(MIDIOUTCAPSA
);
382 ret
= MMDRV_MAP_OKMEM
;
384 ret
= MMDRV_MAP_NOMEM
;
392 case MODM_CACHEPATCHES
:
393 case MODM_CACHEDRUMPATCHES
:
395 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
401 /**************************************************************************
402 * MMDRV_MidiOut_UnMap16To32A [internal]
404 static MMDRV_MapType
MMDRV_MidiOut_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
406 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
409 case MODM_GETNUMDEVS
:
418 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
421 case MODM_GETDEVCAPS
:
423 LPMIDIOUTCAPSA moc32
= (LPMIDIOUTCAPSA
)(*lpParam1
);
424 LPMIDIOUTCAPS16 moc16
= *(LPMIDIOUTCAPS16
*)((LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
426 moc16
->wMid
= moc32
->wMid
;
427 moc16
->wPid
= moc32
->wPid
;
428 moc16
->vDriverVersion
= moc32
->vDriverVersion
;
429 strcpy(moc16
->szPname
, moc32
->szPname
);
430 moc16
->wTechnology
= moc32
->wTechnology
;
431 moc16
->wVoices
= moc32
->wVoices
;
432 moc16
->wNotes
= moc32
->wNotes
;
433 moc16
->wChannelMask
= moc32
->wChannelMask
;
434 moc16
->dwSupport
= moc32
->dwSupport
;
435 HeapFree(GetProcessHeap(), 0, (LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
443 case MODM_CACHEPATCHES
:
444 case MODM_CACHEDRUMPATCHES
:
446 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
452 /**************************************************************************
453 * MMDRV_MidiOut_Map32ATo16 [internal]
455 static MMDRV_MapType
MMDRV_MidiOut_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
457 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
461 case MODM_GETNUMDEVS
:
467 case MODM_GETDEVCAPS
:
469 LPMIDIOUTCAPSA moc32
= (LPMIDIOUTCAPSA
)*lpParam1
;
470 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMIDIOUTCAPSA
) + sizeof(MIDIOUTCAPS16
));
473 *(LPMIDIOUTCAPSA
*)ptr
= moc32
;
474 ret
= MMDRV_MAP_OKMEM
;
476 ret
= MMDRV_MAP_NOMEM
;
478 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIOUTCAPSA
);
479 *lpParam2
= sizeof(MIDIOUTCAPS16
);
487 case MODM_CACHEPATCHES
:
488 case MODM_CACHEDRUMPATCHES
:
490 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
496 /**************************************************************************
497 * MMDRV_MidiOut_UnMap32ATo16 [internal]
499 static MMDRV_MapType
MMDRV_MidiOut_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
501 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
505 case MODM_GETNUMDEVS
:
511 case MODM_GETDEVCAPS
:
513 LPMIDIOUTCAPS16 moc16
= (LPMIDIOUTCAPS16
)PTR_SEG_TO_LIN(*lpParam1
);
514 LPSTR ptr
= (LPSTR
)moc16
- sizeof(LPMIDIOUTCAPSA
);
515 LPMIDIOUTCAPSA moc32
= *(LPMIDIOUTCAPSA
*)ptr
;
517 moc32
->wMid
= moc16
->wMid
;
518 moc32
->wPid
= moc16
->wPid
;
519 moc32
->vDriverVersion
= moc16
->vDriverVersion
;
520 strcpy(moc32
->szPname
, moc16
->szPname
);
521 moc32
->wTechnology
= moc16
->wTechnology
;
522 moc32
->wVoices
= moc16
->wVoices
;
523 moc32
->wNotes
= moc16
->wNotes
;
524 moc32
->wChannelMask
= moc16
->wChannelMask
;
525 moc32
->dwSupport
= moc16
->dwSupport
;
527 if (!SEGPTR_FREE(ptr
))
528 FIXME("bad free line=%d\n", __LINE__
);
537 case MODM_CACHEPATCHES
:
538 case MODM_CACHEDRUMPATCHES
:
540 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
546 /**************************************************************************
547 * MMDRV_MidiOut_Callback [internal]
549 static void CALLBACK
MMDRV_MidiOut_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
551 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
556 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
559 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
560 /* initial map is: 32 => 16 */
561 LPMIDIHDR wh16
= (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
);
562 LPMIDIHDR wh32
= *(LPMIDIHDR
*)((LPSTR
)wh16
- sizeof(LPMIDIHDR
));
564 dwParam1
= (DWORD
)wh32
;
565 wh32
->dwFlags
= wh16
->dwFlags
;
566 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
567 /* initial map is: 16 => 32 */
568 LPMIDIHDR wh32
= (LPMIDIHDR
)(dwParam1
);
569 LPMIDIHDR segwh16
= *(LPMIDIHDR
*)((LPSTR
)wh32
- sizeof(LPMIDIHDR
));
570 LPMIDIHDR wh16
= PTR_SEG_TO_LIN(segwh16
);
572 dwParam1
= (DWORD
)segwh16
;
573 wh16
->dwFlags
= wh32
->dwFlags
;
575 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
577 /* case MOM_POSITIONCB: */
579 ERR("Unknown msg %u\n", uMsg
);
582 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
585 /* =================================
586 * W A V E I N M A P P E R S
587 * ================================= */
589 /**************************************************************************
590 * MMDRV_WaveIn_Map16To32A [internal]
592 static MMDRV_MapType
MMDRV_WaveIn_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
594 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
597 case WIDM_GETNUMDEVS
:
605 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
607 case WIDM_GETDEVCAPS
:
609 LPWAVEINCAPSA wic32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16
) + sizeof(WAVEINCAPSA
));
610 LPWAVEINCAPS16 wic16
= PTR_SEG_TO_LIN(*lpParam1
);
613 *(LPWAVEINCAPS16
*)wic32
= wic16
;
614 wic32
= (LPWAVEINCAPSA
)((LPSTR
)wic32
+ sizeof(LPWAVEINCAPS16
));
615 *lpParam1
= (DWORD
)wic32
;
616 *lpParam2
= sizeof(WAVEINCAPSA
);
618 ret
= MMDRV_MAP_OKMEM
;
620 ret
= MMDRV_MAP_NOMEM
;
626 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
627 LPMMTIME16 mmt16
= PTR_SEG_TO_LIN(*lpParam1
);
630 *(LPMMTIME16
*)mmt32
= mmt16
;
631 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
633 mmt32
->wType
= mmt16
->wType
;
634 *lpParam1
= (DWORD
)mmt32
;
635 *lpParam2
= sizeof(MMTIME
);
637 ret
= MMDRV_MAP_OKMEM
;
639 ret
= MMDRV_MAP_NOMEM
;
645 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
646 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*lpParam1
);
649 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
650 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
651 wh32
->lpData
= PTR_SEG_TO_LIN(wh16
->lpData
);
652 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
653 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
654 wh32
->dwUser
= wh16
->dwUser
;
655 wh32
->dwFlags
= wh16
->dwFlags
;
656 wh32
->dwLoops
= wh16
->dwLoops
;
657 /* FIXME: nothing on wh32->lpNext */
658 /* could link the wh32->lpNext at this level for memory house keeping */
659 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
660 *lpParam1
= (DWORD
)wh32
;
661 *lpParam2
= sizeof(WAVEHDR
);
663 ret
= MMDRV_MAP_OKMEM
;
665 ret
= MMDRV_MAP_NOMEM
;
672 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*lpParam1
);
673 LPWAVEHDR wh32
= (LPWAVEHDR
)wh16
->lpNext
;
675 *lpParam1
= (DWORD
)wh32
;
676 *lpParam2
= sizeof(WAVEHDR
);
677 ret
= MMDRV_MAP_OKMEM
;
681 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
682 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
688 /**************************************************************************
689 * MMDRV_WaveIn_UnMap16To32A [internal]
691 static MMDRV_MapType
MMDRV_WaveIn_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
693 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
696 case WIDM_GETNUMDEVS
:
704 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
706 case WIDM_GETDEVCAPS
:
708 LPWAVEINCAPSA wic32
= (LPWAVEINCAPSA
)(*lpParam1
);
709 LPWAVEINCAPS16 wic16
= *(LPWAVEINCAPS16
*)((LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
711 wic16
->wMid
= wic32
->wMid
;
712 wic16
->wPid
= wic32
->wPid
;
713 wic16
->vDriverVersion
= wic32
->vDriverVersion
;
714 strcpy(wic16
->szPname
, wic32
->szPname
);
715 wic16
->dwFormats
= wic32
->dwFormats
;
716 wic16
->wChannels
= wic32
->wChannels
;
717 HeapFree(GetProcessHeap(), 0, (LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
723 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
724 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
726 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
727 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
735 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
736 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*(LPWAVEHDR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
738 assert(wh16
->lpNext
== wh32
);
739 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
740 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
741 wh16
->dwUser
= wh32
->dwUser
;
742 wh16
->dwFlags
= wh32
->dwFlags
;
743 wh16
->dwLoops
= wh32
->dwLoops
;
745 if (wMsg
== WIDM_UNPREPARE
) {
746 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
753 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
759 /**************************************************************************
760 * MMDRV_WaveIn_Map32ATo16 [internal]
762 static MMDRV_MapType
MMDRV_WaveIn_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
764 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
768 case WIDM_GETNUMDEVS
:
777 LPWAVEOPENDESC wod32
= (LPWAVEOPENDESC
)*lpParam1
;
778 int sz
= sizeof(WAVEFORMATEX
);
780 LPWAVEOPENDESC16 wod16
;
782 /* allocated data are mapped as follows:
783 LPWAVEOPENDESC ptr to orig lParam1
784 DWORD ptr to orig dwUser, which is a pointer to DWORD:driver dwInstance
785 DWORD dwUser passed to driver
786 WAVEOPENDESC16 wod16: openDesc passed to driver
787 WAVEFORMATEX openDesc->lpFormat passed to driver
788 xxx extra bytes to WAVEFORMATEX
790 if (wod32
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
791 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
, wod32
->lpFormat
->wFormatTag
);
792 sz
+= ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
;
795 ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
) + sz
);
798 *(LPWAVEOPENDESC
*)ptr
= wod32
;
799 *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *lpdwUser
;
800 wod16
= (LPWAVEOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
));
802 wod16
->hWave
= wod32
->hWave
;
803 wod16
->lpFormat
= (LPWAVEFORMATEX
)((DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
));
804 memcpy(wod16
+ 1, wod32
->lpFormat
, sz
);
806 wod16
->dwCallback
= wod32
->dwCallback
;
807 wod16
->dwInstance
= wod32
->dwInstance
;
808 wod16
->uMappedDeviceID
= wod32
->uMappedDeviceID
;
809 wod16
->dnDevNode
= wod32
->dnDevNode
;
811 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
);
812 *lpdwUser
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
);
814 ret
= MMDRV_MAP_OKMEM
;
816 ret
= MMDRV_MAP_NOMEM
;
822 LPWAVEHDR wh32
= (LPWAVEHDR
)*lpParam1
;
824 LPVOID ptr
= SEGPTR_ALLOC(sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
) + wh32
->dwBufferLength
);
827 *(LPWAVEHDR
*)ptr
= wh32
;
828 wh16
= (LPWAVEHDR
)((LPSTR
)ptr
+ sizeof(LPWAVEHDR
));
829 wh16
->lpData
= (LPSTR
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
);
830 /* data will be copied on WODM_WRITE */
831 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
832 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
833 wh16
->dwUser
= wh32
->dwUser
;
834 wh16
->dwFlags
= wh32
->dwFlags
;
835 wh16
->dwLoops
= wh32
->dwLoops
;
836 /* FIXME: nothing on wh32->lpNext */
837 /* could link the wh32->lpNext at this level for memory house keeping */
838 wh32
->lpNext
= wh16
; /* for reuse in unprepare and write */
839 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
840 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
841 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
842 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
843 *lpParam2
= sizeof(WAVEHDR
);
845 ret
= MMDRV_MAP_OKMEM
;
847 ret
= MMDRV_MAP_NOMEM
;
854 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
855 LPWAVEHDR wh16
= wh32
->lpNext
;
856 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
858 assert(*(LPWAVEHDR
*)ptr
== wh32
);
860 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
861 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
862 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
864 if (wMsg
== WODM_WRITE
)
865 memcpy((LPSTR
)wh16
+ sizeof(WAVEHDR
), wh32
->lpData
, wh32
->dwBufferLength
);
867 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
868 *lpParam2
= sizeof(WAVEHDR
);
869 ret
= MMDRV_MAP_OKMEM
;
872 case WIDM_GETDEVCAPS
:
874 LPWAVEINCAPSA wic32
= (LPWAVEINCAPSA
)*lpParam1
;
875 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPWAVEINCAPSA
) + sizeof(WAVEINCAPS16
));
878 *(LPWAVEINCAPSA
*)ptr
= wic32
;
879 ret
= MMDRV_MAP_OKMEM
;
881 ret
= MMDRV_MAP_NOMEM
;
883 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEINCAPSA
);
884 *lpParam2
= sizeof(WAVEINCAPS16
);
889 LPMMTIME mmt32
= (LPMMTIME
)*lpParam1
;
890 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMMTIME
) + sizeof(MMTIME16
));
891 LPMMTIME16 mmt16
= (LPMMTIME16
)(ptr
+ sizeof(LPMMTIME
));
894 *(LPMMTIME
*)ptr
= mmt32
;
895 mmt16
->wType
= mmt32
->wType
;
896 ret
= MMDRV_MAP_OKMEM
;
898 ret
= MMDRV_MAP_NOMEM
;
900 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMMTIME
);
901 *lpParam2
= sizeof(MMTIME16
);
905 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
911 /**************************************************************************
912 * MMDRV_WaveIn_UnMap32ATo16 [internal]
914 static MMDRV_MapType
MMDRV_WaveIn_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
916 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
920 case WIDM_GETNUMDEVS
:
929 LPWAVEOPENDESC16 wod16
= (LPWAVEOPENDESC16
)PTR_SEG_TO_LIN(*lpParam1
);
930 LPSTR ptr
= (LPSTR
)wod16
- sizeof(LPWAVEOPENDESC
) - 2*sizeof(DWORD
);
931 LPWAVEOPENDESC wod32
= *(LPWAVEOPENDESC
*)ptr
;
933 wod32
->uMappedDeviceID
= wod16
->uMappedDeviceID
;
934 **(DWORD
**)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
));
936 if (!SEGPTR_FREE(ptr
))
937 FIXME("bad free line=%d\n", __LINE__
);
947 LPWAVEHDR wh16
= (LPWAVEHDR
)PTR_SEG_TO_LIN(*lpParam1
);
948 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
949 LPWAVEHDR wh32
= *(LPWAVEHDR
*)ptr
;
951 assert(wh32
->lpNext
== wh16
);
952 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
953 wh32
->dwUser
= wh16
->dwUser
;
954 wh32
->dwFlags
= wh16
->dwFlags
;
955 wh32
->dwLoops
= wh16
->dwLoops
;
957 if (wMsg
== WODM_UNPREPARE
) {
958 if (!SEGPTR_FREE(ptr
))
959 FIXME("bad free line=%d\n", __LINE__
);
965 case WIDM_GETDEVCAPS
:
967 LPWAVEINCAPS16 wic16
= (LPWAVEINCAPS16
)PTR_SEG_TO_LIN(*lpParam1
);
968 LPSTR ptr
= (LPSTR
)wic16
- sizeof(LPWAVEINCAPSA
);
969 LPWAVEINCAPSA wic32
= *(LPWAVEINCAPSA
*)ptr
;
971 wic32
->wMid
= wic16
->wMid
;
972 wic32
->wPid
= wic16
->wPid
;
973 wic32
->vDriverVersion
= wic16
->vDriverVersion
;
974 strcpy(wic32
->szPname
, wic16
->szPname
);
975 wic32
->dwFormats
= wic16
->dwFormats
;
976 wic32
->wChannels
= wic16
->wChannels
;
977 if (!SEGPTR_FREE(ptr
))
978 FIXME("bad free line=%d\n", __LINE__
);
984 LPMMTIME16 mmt16
= (LPMMTIME16
)PTR_SEG_TO_LIN(*lpParam1
);
985 LPSTR ptr
= (LPSTR
)mmt16
- sizeof(LPMMTIME
);
986 LPMMTIME mmt32
= *(LPMMTIME
*)ptr
;
988 MMSYSTEM_MMTIME16to32(mmt32
, mmt16
);
990 if (!SEGPTR_FREE(ptr
))
991 FIXME("bad free line=%d\n", __LINE__
);
997 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1003 /**************************************************************************
1004 * MMDRV_WaveIn_Callback [internal]
1006 static void CALLBACK
MMDRV_WaveIn_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
1008 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
1013 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1016 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
1017 /* initial map is: 32 => 16 */
1018 LPWAVEHDR wh16
= (LPWAVEHDR
)PTR_SEG_TO_LIN(dwParam1
);
1019 LPWAVEHDR wh32
= *(LPWAVEHDR
*)((LPSTR
)wh16
- sizeof(LPWAVEHDR
));
1021 dwParam1
= (DWORD
)wh32
;
1022 wh32
->dwFlags
= wh16
->dwFlags
;
1023 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1024 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
1025 /* initial map is: 16 => 32 */
1026 LPWAVEHDR wh32
= (LPWAVEHDR
)(dwParam1
);
1027 LPWAVEHDR segwh16
= *(LPWAVEHDR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1028 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(segwh16
);
1030 dwParam1
= (DWORD
)segwh16
;
1031 wh16
->dwFlags
= wh32
->dwFlags
;
1032 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1034 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1037 ERR("Unknown msg %u\n", uMsg
);
1040 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
1043 /* =================================
1044 * W A V E O U T M A P P E R S
1045 * ================================= */
1047 /**************************************************************************
1048 * MMDRV_WaveOut_Map16To32A [internal]
1050 static MMDRV_MapType
MMDRV_WaveOut_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1052 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1056 case WODM_BREAKLOOP
:
1058 case WODM_GETNUMDEVS
:
1063 case WODM_SETPLAYBACKRATE
:
1064 case WODM_SETVOLUME
:
1069 case WODM_GETPLAYBACKRATE
:
1070 case WODM_GETVOLUME
:
1072 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1075 case WODM_GETDEVCAPS
:
1077 LPWAVEOUTCAPSA woc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16
) + sizeof(WAVEOUTCAPSA
));
1078 LPWAVEOUTCAPS16 woc16
= PTR_SEG_TO_LIN(*lpParam1
);
1081 *(LPWAVEOUTCAPS16
*)woc32
= woc16
;
1082 woc32
= (LPWAVEOUTCAPSA
)((LPSTR
)woc32
+ sizeof(LPWAVEOUTCAPS16
));
1083 *lpParam1
= (DWORD
)woc32
;
1084 *lpParam2
= sizeof(WAVEOUTCAPSA
);
1086 ret
= MMDRV_MAP_OKMEM
;
1088 ret
= MMDRV_MAP_NOMEM
;
1094 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
1095 LPMMTIME16 mmt16
= PTR_SEG_TO_LIN(*lpParam1
);
1098 *(LPMMTIME16
*)mmt32
= mmt16
;
1099 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
1101 mmt32
->wType
= mmt16
->wType
;
1102 *lpParam1
= (DWORD
)mmt32
;
1103 *lpParam2
= sizeof(MMTIME
);
1105 ret
= MMDRV_MAP_OKMEM
;
1107 ret
= MMDRV_MAP_NOMEM
;
1113 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
1114 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*lpParam1
);
1117 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
1118 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
1119 wh32
->lpData
= PTR_SEG_TO_LIN(wh16
->lpData
);
1120 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1121 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1122 wh32
->dwUser
= wh16
->dwUser
;
1123 wh32
->dwFlags
= wh16
->dwFlags
;
1124 wh32
->dwLoops
= wh16
->dwLoops
;
1125 /* FIXME: nothing on wh32->lpNext */
1126 /* could link the wh32->lpNext at this level for memory house keeping */
1127 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
1128 *lpParam1
= (DWORD
)wh32
;
1129 *lpParam2
= sizeof(WAVEHDR
);
1131 ret
= MMDRV_MAP_OKMEM
;
1133 ret
= MMDRV_MAP_NOMEM
;
1137 case WODM_UNPREPARE
:
1140 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*lpParam1
);
1141 LPWAVEHDR wh32
= (LPWAVEHDR
)wh16
->lpNext
;
1143 *lpParam1
= (DWORD
)wh32
;
1144 *lpParam2
= sizeof(WAVEHDR
);
1145 ret
= MMDRV_MAP_OKMEM
;
1149 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1155 /**************************************************************************
1156 * MMDRV_WaveOut_UnMap16To32A [internal]
1158 static MMDRV_MapType
MMDRV_WaveOut_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1160 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1164 case WODM_BREAKLOOP
:
1166 case WODM_GETNUMDEVS
:
1171 case WODM_SETPLAYBACKRATE
:
1172 case WODM_SETVOLUME
:
1177 case WODM_GETPLAYBACKRATE
:
1178 case WODM_GETVOLUME
:
1180 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1183 case WODM_GETDEVCAPS
:
1185 LPWAVEOUTCAPSA woc32
= (LPWAVEOUTCAPSA
)(*lpParam1
);
1186 LPWAVEOUTCAPS16 woc16
= *(LPWAVEOUTCAPS16
*)((LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
1188 woc16
->wMid
= woc32
->wMid
;
1189 woc16
->wPid
= woc32
->wPid
;
1190 woc16
->vDriverVersion
= woc32
->vDriverVersion
;
1191 strcpy(woc16
->szPname
, woc32
->szPname
);
1192 woc16
->dwFormats
= woc32
->dwFormats
;
1193 woc16
->wChannels
= woc32
->wChannels
;
1194 woc16
->dwSupport
= woc32
->dwSupport
;
1195 HeapFree(GetProcessHeap(), 0, (LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
1201 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
1202 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1204 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
1205 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1210 case WODM_UNPREPARE
:
1213 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1214 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*(LPWAVEHDR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
1216 assert(wh16
->lpNext
== wh32
);
1217 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1218 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1219 wh16
->dwUser
= wh32
->dwUser
;
1220 wh16
->dwFlags
= wh32
->dwFlags
;
1221 wh16
->dwLoops
= wh32
->dwLoops
;
1223 if (wMsg
== WODM_UNPREPARE
) {
1224 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1231 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1237 /**************************************************************************
1238 * MMDRV_WaveOut_Map32ATo16 [internal]
1240 static MMDRV_MapType
MMDRV_WaveOut_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1246 case WODM_BREAKLOOP
:
1248 case WODM_GETNUMDEVS
:
1253 case WODM_SETPLAYBACKRATE
:
1254 case WODM_SETVOLUME
:
1258 case WODM_GETDEVCAPS
:
1260 LPWAVEOUTCAPSA woc32
= (LPWAVEOUTCAPSA
)*lpParam1
;
1261 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOUTCAPSA
) + sizeof(WAVEOUTCAPS16
));
1264 *(LPWAVEOUTCAPSA
*)ptr
= woc32
;
1265 ret
= MMDRV_MAP_OKMEM
;
1267 ret
= MMDRV_MAP_NOMEM
;
1269 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOUTCAPSA
);
1270 *lpParam2
= sizeof(WAVEOUTCAPS16
);
1274 FIXME("NIY: no conversion yet\n");
1275 ret
= MMDRV_MAP_MSGERROR
;
1277 case WODM_GETPLAYBACKRATE
:
1278 FIXME("NIY: no conversion yet\n");
1279 ret
= MMDRV_MAP_MSGERROR
;
1283 LPMMTIME mmt32
= (LPMMTIME
)*lpParam1
;
1284 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMMTIME
) + sizeof(MMTIME16
));
1285 LPMMTIME16 mmt16
= (LPMMTIME16
)(ptr
+ sizeof(LPMMTIME
));
1288 *(LPMMTIME
*)ptr
= mmt32
;
1289 mmt16
->wType
= mmt32
->wType
;
1290 ret
= MMDRV_MAP_OKMEM
;
1292 ret
= MMDRV_MAP_NOMEM
;
1294 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMMTIME
);
1295 *lpParam2
= sizeof(MMTIME16
);
1298 case WODM_GETVOLUME
:
1299 FIXME("NIY: no conversion yet\n");
1300 ret
= MMDRV_MAP_MSGERROR
;
1304 LPWAVEOPENDESC wod32
= (LPWAVEOPENDESC
)*lpParam1
;
1305 int sz
= sizeof(WAVEFORMATEX
);
1307 LPWAVEOPENDESC16 wod16
;
1309 /* allocated data are mapped as follows:
1310 LPWAVEOPENDESC ptr to orig lParam1
1311 DWORD ptr to orig dwUser, which is a pointer to DWORD:driver dwInstance
1312 DWORD dwUser passed to driver
1313 WAVEOPENDESC16 wod16: openDesc passed to driver
1314 WAVEFORMATEX openDesc->lpFormat passed to driver
1315 xxx extra bytes to WAVEFORMATEX
1317 if (wod32
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
1318 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
, wod32
->lpFormat
->wFormatTag
);
1319 sz
+= ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
;
1322 ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
) + sz
);
1325 *(LPWAVEOPENDESC
*)ptr
= wod32
;
1326 *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *lpdwUser
;
1327 wod16
= (LPWAVEOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
));
1329 wod16
->hWave
= wod32
->hWave
;
1330 wod16
->lpFormat
= (LPWAVEFORMATEX
)((DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
));
1331 memcpy(wod16
+ 1, wod32
->lpFormat
, sz
);
1333 wod16
->dwCallback
= wod32
->dwCallback
;
1334 wod16
->dwInstance
= wod32
->dwInstance
;
1335 wod16
->uMappedDeviceID
= wod32
->uMappedDeviceID
;
1336 wod16
->dnDevNode
= wod32
->dnDevNode
;
1338 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
);
1339 *lpdwUser
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
);
1341 ret
= MMDRV_MAP_OKMEM
;
1343 ret
= MMDRV_MAP_NOMEM
;
1349 LPWAVEHDR wh32
= (LPWAVEHDR
)*lpParam1
;
1351 LPVOID ptr
= SEGPTR_ALLOC(sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
) + wh32
->dwBufferLength
);
1354 *(LPWAVEHDR
*)ptr
= wh32
;
1355 wh16
= (LPWAVEHDR
)((LPSTR
)ptr
+ sizeof(LPWAVEHDR
));
1356 wh16
->lpData
= (LPSTR
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
);
1357 /* data will be copied on WODM_WRITE */
1358 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1359 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1360 wh16
->dwUser
= wh32
->dwUser
;
1361 wh16
->dwFlags
= wh32
->dwFlags
;
1362 wh16
->dwLoops
= wh32
->dwLoops
;
1363 /* FIXME: nothing on wh32->lpNext */
1364 /* could link the wh32->lpNext at this level for memory house keeping */
1365 wh32
->lpNext
= wh16
; /* for reuse in unprepare and write */
1366 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1367 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1368 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1369 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1370 *lpParam2
= sizeof(WAVEHDR
);
1372 ret
= MMDRV_MAP_OKMEM
;
1374 ret
= MMDRV_MAP_NOMEM
;
1378 case WODM_UNPREPARE
:
1381 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1382 LPWAVEHDR wh16
= wh32
->lpNext
;
1383 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1385 assert(*(LPWAVEHDR
*)ptr
== wh32
);
1387 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1388 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1389 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1391 if (wMsg
== WODM_WRITE
)
1392 memcpy((LPSTR
)wh16
+ sizeof(WAVEHDR
), wh32
->lpData
, wh32
->dwBufferLength
);
1394 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1395 *lpParam2
= sizeof(WAVEHDR
);
1396 ret
= MMDRV_MAP_OKMEM
;
1400 FIXME("NIY: no conversion yet\n");
1401 ret
= MMDRV_MAP_MSGERROR
;
1407 /**************************************************************************
1408 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1410 static MMDRV_MapType
MMDRV_WaveOut_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1416 case WODM_BREAKLOOP
:
1418 case WODM_GETNUMDEVS
:
1423 case WODM_SETPLAYBACKRATE
:
1424 case WODM_SETVOLUME
:
1428 case WODM_GETDEVCAPS
:
1430 LPWAVEOUTCAPS16 woc16
= (LPWAVEOUTCAPS16
)PTR_SEG_TO_LIN(*lpParam1
);
1431 LPSTR ptr
= (LPSTR
)woc16
- sizeof(LPWAVEOUTCAPSA
);
1432 LPWAVEOUTCAPSA woc32
= *(LPWAVEOUTCAPSA
*)ptr
;
1434 woc32
->wMid
= woc16
->wMid
;
1435 woc32
->wPid
= woc16
->wPid
;
1436 woc32
->vDriverVersion
= woc16
->vDriverVersion
;
1437 strcpy(woc32
->szPname
, woc16
->szPname
);
1438 woc32
->dwFormats
= woc16
->dwFormats
;
1439 woc32
->wChannels
= woc16
->wChannels
;
1440 woc32
->dwSupport
= woc16
->dwSupport
;
1441 if (!SEGPTR_FREE(ptr
))
1442 FIXME("bad free line=%d\n", __LINE__
);
1447 FIXME("NIY: no conversion yet\n");
1448 ret
= MMDRV_MAP_MSGERROR
;
1450 case WODM_GETPLAYBACKRATE
:
1451 FIXME("NIY: no conversion yet\n");
1452 ret
= MMDRV_MAP_MSGERROR
;
1456 LPMMTIME16 mmt16
= (LPMMTIME16
)PTR_SEG_TO_LIN(*lpParam1
);
1457 LPSTR ptr
= (LPSTR
)mmt16
- sizeof(LPMMTIME
);
1458 LPMMTIME mmt32
= *(LPMMTIME
*)ptr
;
1460 MMSYSTEM_MMTIME16to32(mmt32
, mmt16
);
1462 if (!SEGPTR_FREE(ptr
))
1463 FIXME("bad free line=%d\n", __LINE__
);
1470 LPWAVEOPENDESC16 wod16
= (LPWAVEOPENDESC16
)PTR_SEG_TO_LIN(*lpParam1
);
1471 LPSTR ptr
= (LPSTR
)wod16
- sizeof(LPWAVEOPENDESC
) - 2*sizeof(DWORD
);
1472 LPWAVEOPENDESC wod32
= *(LPWAVEOPENDESC
*)ptr
;
1474 wod32
->uMappedDeviceID
= wod16
->uMappedDeviceID
;
1475 **(DWORD
**)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
));
1477 if (!SEGPTR_FREE(ptr
))
1478 FIXME("bad free line=%d\n", __LINE__
);
1484 case WODM_UNPREPARE
:
1487 LPWAVEHDR wh16
= (LPWAVEHDR
)PTR_SEG_TO_LIN(*lpParam1
);
1488 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1489 LPWAVEHDR wh32
= *(LPWAVEHDR
*)ptr
;
1491 assert(wh32
->lpNext
== wh16
);
1492 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1493 wh32
->dwUser
= wh16
->dwUser
;
1494 wh32
->dwFlags
= wh16
->dwFlags
;
1495 wh32
->dwLoops
= wh16
->dwLoops
;
1497 if (wMsg
== WODM_UNPREPARE
) {
1498 if (!SEGPTR_FREE(ptr
))
1499 FIXME("bad free line=%d\n", __LINE__
);
1505 case WODM_GETVOLUME
:
1506 FIXME("NIY: no conversion yet\n");
1507 ret
= MMDRV_MAP_MSGERROR
;
1510 FIXME("NIY: no conversion yet\n");
1511 ret
= MMDRV_MAP_MSGERROR
;
1517 /**************************************************************************
1518 * MMDRV_WaveOut_Callback [internal]
1520 static void CALLBACK
MMDRV_WaveOut_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
1522 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
1527 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1530 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
1531 /* initial map is: 32 => 16 */
1532 LPWAVEHDR wh16
= (LPWAVEHDR
)PTR_SEG_TO_LIN(dwParam1
);
1533 LPWAVEHDR wh32
= *(LPWAVEHDR
*)((LPSTR
)wh16
- sizeof(LPWAVEHDR
));
1535 dwParam1
= (DWORD
)wh32
;
1536 wh32
->dwFlags
= wh16
->dwFlags
;
1537 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
1538 /* initial map is: 16 => 32 */
1539 LPWAVEHDR wh32
= (LPWAVEHDR
)(dwParam1
);
1540 LPWAVEHDR segwh16
= *(LPWAVEHDR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1541 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(segwh16
);
1543 dwParam1
= (DWORD
)segwh16
;
1544 wh16
->dwFlags
= wh32
->dwFlags
;
1546 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1549 ERR("Unknown msg %u\n", uMsg
);
1552 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
1555 #define A(_x,_y) {#_y, _x, \
1556 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1557 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1558 MMDRV_##_y##_Callback, 0, NULL, -1}
1560 /* Note: the indices of this array must match the definitions
1561 * of the MMDRV_???? manifest constants
1563 static WINE_LLTYPE llTypes
[MMDRV_MAX
] = {
1573 /**************************************************************************
1574 * MMDRV_GetNum [internal]
1576 UINT
MMDRV_GetNum(UINT type
)
1578 assert(type
< MMDRV_MAX
);
1579 return llTypes
[type
].wMaxId
;
1582 /**************************************************************************
1583 * WINE_Message [internal]
1585 DWORD
MMDRV_Message(LPWINE_MLD mld
, WORD wMsg
, DWORD dwParam1
,
1586 DWORD dwParam2
, BOOL bFrom32
)
1588 LPWINE_MM_DRIVER lpDrv
;
1590 WINE_MM_DRIVER_PART
* part
;
1591 WINE_LLTYPE
* llType
= &llTypes
[mld
->type
];
1595 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1596 llTypes
[mld
->type
].name
, mld
->uDeviceID
, wMsg
,
1597 mld
->dwDriverInstance
, dwParam1
, dwParam2
, bFrom32
?'Y':'N');
1599 if (mld
->uDeviceID
== (UINT16
)-1) {
1600 if (!llType
->bSupportMapper
) {
1601 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1602 llTypes
[mld
->type
].name
);
1603 return MMSYSERR_BADDEVICEID
;
1607 if (mld
->uDeviceID
>= llType
->wMaxId
) {
1608 WARN("uDev(%u) requested >= max (%d)\n", mld
->uDeviceID
, llType
->wMaxId
);
1609 return MMSYSERR_BADDEVICEID
;
1611 devID
= mld
->uDeviceID
;
1614 lpDrv
= &MMDrvs
[mld
->mmdIndex
];
1615 part
= &lpDrv
->parts
[mld
->type
];
1618 /* some sanity checks */
1619 if (!(part
->nIDMin
<= devID
))
1620 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part
->nIDMin
, devID
);
1621 if (!(devID
< part
->nIDMax
))
1622 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID
, part
->nIDMax
);
1626 assert(part
->u
.fnMessage32
);
1629 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1630 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1631 ret
= part
->u
.fnMessage32(mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1632 TRACE("=> %lu\n", ret
);
1634 map
= llType
->Map16To32A(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1636 case MMDRV_MAP_NOMEM
:
1637 ret
= MMSYSERR_NOMEM
;
1639 case MMDRV_MAP_MSGERROR
:
1640 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg
);
1641 ret
= MMSYSERR_ERROR
;
1644 case MMDRV_MAP_OKMEM
:
1645 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1646 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1647 ret
= part
->u
.fnMessage32(mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
,
1648 dwParam1
, dwParam2
);
1649 TRACE("=> %lu\n", ret
);
1650 if (map
== MMDRV_MAP_OKMEM
)
1651 llType
->UnMap16To32A(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1654 case MMDRV_MAP_PASS
:
1655 FIXME("NIY: pass used ?\n");
1656 ret
= MMSYSERR_NOTSUPPORTED
;
1661 assert(part
->u
.fnMessage16
);
1664 map
= llType
->Map32ATo16(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1666 case MMDRV_MAP_NOMEM
:
1667 ret
= MMSYSERR_NOMEM
;
1669 case MMDRV_MAP_MSGERROR
:
1670 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg
);
1671 ret
= MMSYSERR_ERROR
;
1674 case MMDRV_MAP_OKMEM
:
1675 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1676 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1677 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
, mld
->uDeviceID
,
1678 wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1679 TRACE("=> %lu\n", ret
);
1680 if (map
== MMDRV_MAP_OKMEM
)
1681 llType
->UnMap32ATo16(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1684 case MMDRV_MAP_PASS
:
1685 FIXME("NIY: pass used ?\n");
1686 ret
= MMSYSERR_NOTSUPPORTED
;
1690 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1691 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1692 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
, mld
->uDeviceID
,
1693 wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1694 TRACE("=> %lu\n", ret
);
1700 /**************************************************************************
1701 * MMDRV_Alloc [internal]
1703 LPWINE_MLD
MMDRV_Alloc(UINT size
, UINT type
, LPHANDLE hndl
, DWORD
* dwFlags
,
1704 DWORD
* dwCallback
, DWORD
* dwInstance
, BOOL bFrom32
)
1708 if ((*hndl
= USER_HEAP_ALLOC(size
)) == 0)
1711 mld
= (LPWINE_MLD
) USER_HEAP_LIN_ADDR(*hndl
);
1712 if (!mld
) return NULL
;
1714 if ((UINT
)*hndl
< MMDRV_GetNum(type
) || HIWORD(*hndl
) != 0) {
1715 /* FIXME: those conditions must be fulfilled so that:
1716 * - we can distinguish between device IDs and handles
1717 * - we can use handles as 16 or 32 bit entities
1719 ERR("Shouldn't happen. Bad allocation scheme\n");
1722 mld
->bFrom32
= bFrom32
;
1723 mld
->dwFlags
= HIWORD(*dwFlags
);
1724 mld
->dwCallback
= *dwCallback
;
1725 mld
->dwClientInstance
= *dwInstance
;
1727 *dwFlags
= LOWORD(*dwFlags
) | CALLBACK_FUNCTION
;
1728 *dwCallback
= (DWORD
)llTypes
[type
].Callback
;
1729 *dwInstance
= (DWORD
)mld
; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
1734 /**************************************************************************
1735 * MMDRV_Free [internal]
1737 void MMDRV_Free(HANDLE hndl
, LPWINE_MLD mld
)
1739 USER_HEAP_FREE(hndl
);
1742 /**************************************************************************
1743 * MMDRV_Open [internal]
1745 DWORD
MMDRV_Open(LPWINE_MLD mld
, UINT wMsg
, DWORD dwParam1
, DWORD dwFlags
)
1747 DWORD dwRet
= MMSYSERR_BADDEVICEID
;
1749 WINE_LLTYPE
* llType
= &llTypes
[mld
->type
];
1751 mld
->dwDriverInstance
= (DWORD
)&dwInstance
;
1753 if (mld
->uDeviceID
== (UINT
)-1) {
1754 TRACE("MAPPER mode requested !\n");
1755 /* check if mapper is supported by type */
1756 if (llType
->bSupportMapper
) {
1757 if (llType
->nMapper
== -1) {
1758 /* no driver for mapper has been loaded, try a dumb implementation */
1759 TRACE("No mapper loaded, doing it by hand\n");
1760 for (mld
->uDeviceID
= 0; mld
->uDeviceID
< llType
->wMaxId
; mld
->uDeviceID
++) {
1761 if ((dwRet
= MMDRV_Open(mld
, wMsg
, dwParam1
, dwFlags
)) == MMSYSERR_NOERROR
) {
1762 /* to share this function epilog */
1763 dwInstance
= mld
->dwDriverInstance
;
1768 mld
->uDeviceID
= (UINT16
)-1;
1769 mld
->mmdIndex
= llType
->lpMlds
[-1].mmdIndex
;
1770 TRACE("Setting mmdIndex to %u\n", mld
->mmdIndex
);
1771 dwRet
= MMDRV_Message(mld
, wMsg
, dwParam1
, dwFlags
, TRUE
);
1775 if (mld
->uDeviceID
< llType
->wMaxId
) {
1776 mld
->mmdIndex
= llType
->lpMlds
[mld
->uDeviceID
].mmdIndex
;
1777 TRACE("Setting mmdIndex to %u\n", mld
->mmdIndex
);
1778 dwRet
= MMDRV_Message(mld
, wMsg
, dwParam1
, dwFlags
, TRUE
);
1781 if (dwRet
== MMSYSERR_NOERROR
)
1782 mld
->dwDriverInstance
= dwInstance
;
1786 /**************************************************************************
1787 * MMDRV_Close [internal]
1789 DWORD
MMDRV_Close(LPWINE_MLD mld
, UINT wMsg
)
1791 return MMDRV_Message(mld
, wMsg
, 0L, 0L, TRUE
);
1794 /**************************************************************************
1795 * MMDRV_GetByID [internal]
1797 LPWINE_MLD
MMDRV_GetByID(UINT uDevID
, UINT type
)
1799 if (uDevID
< llTypes
[type
].wMaxId
)
1800 return &llTypes
[type
].lpMlds
[uDevID
];
1801 if ((uDevID
== (UINT16
)-1 || uDevID
== (UINT
)-1) && llTypes
[type
].nMapper
!= -1)
1802 return &llTypes
[type
].lpMlds
[-1];
1806 /**************************************************************************
1807 * MMDRV_Get [internal]
1809 LPWINE_MLD
MMDRV_Get(HANDLE hndl
, UINT type
, BOOL bCanBeID
)
1811 LPWINE_MLD mld
= NULL
;
1813 assert(type
< MMDRV_MAX
);
1815 if ((UINT
)hndl
>= llTypes
[type
].wMaxId
) {
1816 mld
= (LPWINE_MLD
)USER_HEAP_LIN_ADDR(hndl
);
1818 if (!IsBadWritePtr(mld
, sizeof(*mld
)) && mld
->type
!= type
) mld
= NULL
;
1820 if (mld
== NULL
&& bCanBeID
) {
1821 mld
= MMDRV_GetByID((UINT
)hndl
, type
);
1826 /**************************************************************************
1827 * MMDRV_GetRelated [internal]
1829 LPWINE_MLD
MMDRV_GetRelated(HANDLE hndl
, UINT srcType
,
1830 BOOL bSrcCanBeID
, UINT dstType
)
1834 if ((mld
= MMDRV_Get(hndl
, srcType
, bSrcCanBeID
)) != NULL
) {
1835 WINE_MM_DRIVER_PART
* part
= &MMDrvs
[mld
->mmdIndex
].parts
[dstType
];
1836 if (part
->nIDMin
< part
->nIDMax
)
1837 return MMDRV_GetByID(part
->nIDMin
, dstType
);
1842 /**************************************************************************
1843 * MMDRV_PhysicalFeatures [internal]
1845 UINT
MMDRV_PhysicalFeatures(LPWINE_MLD mld
, UINT uMsg
, DWORD dwParam1
,
1848 WINE_MM_DRIVER
* lpDrv
= &MMDrvs
[mld
->mmdIndex
];
1850 TRACE("(%p, %04x, %08lx, %08lx)\n", mld
, uMsg
, dwParam1
, dwParam2
);
1852 /* all those function calls are undocumented */
1854 case 0x801: /* DRV_QUERYDRVENTRY */
1855 strncpy((LPSTR
)dwParam1
, lpDrv
->name
, LOWORD(dwParam2
));
1857 case 0x802: /* DRV_QUERYDEVNODE */
1858 *(LPDWORD
)dwParam1
= 0L; /* should be DevNode */
1860 case 0x803: /* DRV_QUERYNAME */
1861 WARN("NIY 0x803\n");
1863 case 0x804: /* DRV_QUERYDRIVERIDS */
1864 WARN("NIY call VxD\n");
1865 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
1866 * dwParam1 is buffer and dwParam2 is sizeof buffer
1867 * I don't know where the result is stored though
1870 case 0x805: /* DRV_QUERYMAPPABLE */
1871 return (lpDrv
->bIsMapper
) ? 2 : 0;
1873 WARN("Unknown call %04x\n", uMsg
);
1874 return MMSYSERR_INVALPARAM
;
1879 /**************************************************************************
1880 * MMDRV_InitPerType [internal]
1882 static BOOL
MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv
, UINT num
,
1883 UINT type
, UINT wMsg
)
1885 WINE_MM_DRIVER_PART
* part
= &lpDrv
->parts
[type
];
1890 part
->nIDMin
= part
->nIDMax
= 0;
1892 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
1893 /* the DRVM_ENABLE is only required when the PnP node is non zero */
1895 if (lpDrv
->bIs32
&& part
->u
.fnMessage32
) {
1896 ret
= part
->u
.fnMessage32(0, DRVM_INIT
, 0L, 0L, 0L);
1897 TRACE("DRVM_INIT => %08lx\n", ret
);
1899 ret
= part
->u
.fnMessage32(0, DRVM_ENABLE
, 0L, 0L, 0L);
1900 TRACE("DRVM_ENABLE => %08lx\n", ret
);
1902 count
= part
->u
.fnMessage32(0, wMsg
, 0L, 0L, 0L);
1905 if (!lpDrv
->bIs32
&& part
->u
.fnMessage16
) {
1906 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
1907 0, DRVM_INIT
, 0L, 0L, 0L);
1908 TRACE("DRVM_INIT => %08lx\n", ret
);
1910 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
1911 0, DRVM_ENABLE
, 0L, 0L, 0L);
1912 TRACE("DRVM_ENABLE => %08lx\n", ret
);
1914 count
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
1915 0, wMsg
, 0L, 0L, 0L);
1918 TRACE("Got %u dev for (%s:%s)\n", count
, lpDrv
->name
, llTypes
[type
].name
);
1922 /* got some drivers */
1923 if (lpDrv
->bIsMapper
) {
1924 if (llTypes
[type
].nMapper
!= -1)
1925 ERR("Two mappers for type %s (%d, %s)\n",
1926 llTypes
[type
].name
, llTypes
[type
].nMapper
, lpDrv
->name
);
1928 ERR("Strange: mapper with %d > 1 devices\n", count
);
1929 llTypes
[type
].nMapper
= num
;
1931 part
->nIDMin
= llTypes
[type
].wMaxId
;
1932 llTypes
[type
].wMaxId
+= count
;
1933 part
->nIDMax
= llTypes
[type
].wMaxId
;
1935 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
1936 part
->nIDMin
, part
->nIDMax
, llTypes
[type
].wMaxId
,
1937 lpDrv
->name
, llTypes
[type
].name
);
1938 /* realloc translation table */
1939 llTypes
[type
].lpMlds
= (LPWINE_MLD
)
1940 HeapReAlloc(SystemHeap
, 0, (llTypes
[type
].lpMlds
) ? llTypes
[type
].lpMlds
- 1 : NULL
,
1941 sizeof(WINE_MLD
) * (llTypes
[type
].wMaxId
+ 1)) + 1;
1942 /* re-build the translation table */
1943 if (llTypes
[type
].nMapper
!= -1) {
1944 TRACE("%s:Trans[%d] -> %s\n", llTypes
[type
].name
, -1, MMDrvs
[llTypes
[type
].nMapper
].name
);
1945 llTypes
[type
].lpMlds
[-1].uDeviceID
= (UINT16
)-1;
1946 llTypes
[type
].lpMlds
[-1].type
= type
;
1947 llTypes
[type
].lpMlds
[-1].mmdIndex
= llTypes
[type
].nMapper
;
1948 llTypes
[type
].lpMlds
[-1].dwDriverInstance
= 0;
1950 for (i
= k
= 0; i
<= num
; i
++) {
1951 while (MMDrvs
[i
].parts
[type
].nIDMin
<= k
&& k
< MMDrvs
[i
].parts
[type
].nIDMax
) {
1952 TRACE("%s:Trans[%d] -> %s\n", llTypes
[type
].name
, k
, MMDrvs
[i
].name
);
1953 llTypes
[type
].lpMlds
[k
].uDeviceID
= k
;
1954 llTypes
[type
].lpMlds
[k
].type
= type
;
1955 llTypes
[type
].lpMlds
[k
].mmdIndex
= i
;
1956 llTypes
[type
].lpMlds
[k
].dwDriverInstance
= 0;
1963 /**************************************************************************
1964 * MMDRV_Install [internal]
1966 static BOOL
MMDRV_Install(LPCSTR name
, int num
, BOOL bIsMapper
)
1971 LPWINE_MM_DRIVER lpDrv
= &MMDrvs
[num
];
1973 TRACE("('%s');\n", name
);
1975 memset(lpDrv
, 0, sizeof(*lpDrv
));
1977 /* First load driver */
1978 if ((lpDrv
->hDrvr
= OpenDriverA(name
, 0, 0)) == 0) {
1979 WARN("Couldn't open driver '%s'\n", name
);
1983 /* Then look for xxxMessage functions */
1984 #define AA(_w,_x,_y,_z) \
1985 func = (WINEMM_msgFunc##_y) _z (hModule, #_x); \
1987 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
1988 TRACE("Got %d bit func '%s'\n", _y, #_x); }
1990 if ((DRIVER_GetType(lpDrv
->hDrvr
) & WINE_DI_TYPE_MASK
) == WINE_DI_TYPE_32
) {
1991 WINEMM_msgFunc32 func
;
1993 lpDrv
->bIs32
= TRUE
;
1994 if ((hModule
= GetDriverModuleHandle(lpDrv
->hDrvr
))) {
1995 #define A(_x,_y) AA(_x,_y,32,GetProcAddress)
1996 A(MMDRV_AUX
, auxMessage
);
1997 A(MMDRV_MIXER
, mixMessage
);
1998 A(MMDRV_MIDIIN
, midMessage
);
1999 A(MMDRV_MIDIOUT
, modMessage
);
2000 A(MMDRV_WAVEIN
, widMessage
);
2001 A(MMDRV_WAVEOUT
, wodMessage
);
2005 WINEMM_msgFunc16 func
;
2008 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2009 * The beginning of the module description indicates the driver supports
2010 * waveform, auxiliary, and mixer devices. Use one of the following
2011 * device-type names, followed by a colon (:) to indicate the type of
2012 * device your driver supports. If the driver supports more than one
2013 * type of device, separate each device-type name with a comma (,).
2015 * wave for waveform audio devices
2016 * wavemapper for wave mappers
2017 * midi for MIDI audio devices
2018 * midimapper for midi mappers
2019 * aux for auxiliary audio devices
2020 * mixer for mixer devices
2023 lpDrv
->bIs32
= FALSE
;
2024 if ((hModule
= GetDriverModuleHandle16(lpDrv
->hDrvr
))) {
2025 #define A(_x,_y) AA(_x,_y,16,WIN32_GetProcAddress16)
2026 A(MMDRV_AUX
, auxMessage
);
2027 A(MMDRV_MIXER
, mixMessage
);
2028 A(MMDRV_MIDIIN
, midMessage
);
2029 A(MMDRV_MIDIOUT
, modMessage
);
2030 A(MMDRV_WAVEIN
, widMessage
);
2031 A(MMDRV_WAVEOUT
, wodMessage
);
2037 if (TRACE_ON(mmsys
)) {
2038 if ((lpDrv
->bIs32
) ? MMDRV_GetDescription32(name
, buffer
, sizeof(buffer
)) :
2039 MMDRV_GetDescription16(name
, buffer
, sizeof(buffer
)))
2040 TRACE("%s => %s\n", name
, buffer
);
2042 TRACE("%s => No description\n", name
);
2046 CloseDriver(lpDrv
->hDrvr
, 0, 0);
2047 WARN("No message functions found\n");
2051 /* FIXME: being a mapper or not should be known by another way */
2052 /* it's known for NE drvs (the description is of the form '*mapper: *'
2053 * I don't have any clue for PE drvs
2054 * on Win 9x, the value is gotten from the key mappable under
2055 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\MediaResources\
2057 lpDrv
->bIsMapper
= bIsMapper
;
2058 lpDrv
->name
= HEAP_strdupA(GetProcessHeap(), 0, name
);
2060 /* Finish init and get the count of the devices */
2061 MMDRV_InitPerType(lpDrv
, num
, MMDRV_AUX
, AUXDM_GETNUMDEVS
);
2062 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIXER
, MXDM_GETNUMDEVS
);
2063 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIDIIN
, MIDM_GETNUMDEVS
);
2064 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIDIOUT
, MODM_GETNUMDEVS
);
2065 MMDRV_InitPerType(lpDrv
, num
, MMDRV_WAVEIN
, WIDM_GETNUMDEVS
);
2066 MMDRV_InitPerType(lpDrv
, num
, MMDRV_WAVEOUT
, WODM_GETNUMDEVS
);
2067 /* FIXME: if all those func calls return FALSE, then the driver must be unloaded */
2071 /**************************************************************************
2072 * MMDRV_Init [internal]
2074 BOOL
MMDRV_Init(void)
2078 /* FIXME: this should be moved to init files;
2079 * - either .winerc/wine.conf
2080 * - or made of registry keys
2081 * this is a temporary hack, shall be removed anytime now
2083 /* first load hardware drivers */
2084 if (MMDRV_Install("wineoss.drv", num
, FALSE
)) num
++;
2086 /* finish with mappers */
2087 if (MMDRV_Install("msacm.drv", num
, TRUE
)) num
++;
2088 if (MMDRV_Install("midimap.drv", num
, TRUE
)) num
++;
2091 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2092 * if not just increase size of MMDrvs */
2093 assert(num
<= sizeof(MMDrvs
)/sizeof(MMDrvs
[0]));