1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * MMSYTEM low level drivers handling functions
6 * Copyright 1999 Eric Pouech
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "wine/winbase16.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mmsys
);
34 typedef DWORD (CALLBACK
*WINEMM_msgFunc16
)(UINT16
, WORD
, DWORD
, DWORD
, DWORD
);
35 typedef DWORD (CALLBACK
*WINEMM_msgFunc32
)(UINT
, UINT
, DWORD
, DWORD
, DWORD
);
37 /* for each loaded driver and each known type of driver, this structure contains
38 * the information needed to access it
40 typedef struct tagWINE_MM_DRIVER_PART
{
41 int nIDMin
; /* lower bound of global indexes for this type */
42 int nIDMax
; /* hhigher bound of global indexes for this type */
44 WINEMM_msgFunc32 fnMessage32
; /* pointer to fonction */
45 WINEMM_msgFunc16 fnMessage16
;
47 } WINE_MM_DRIVER_PART
;
49 /* each low-level .drv will be associated with an instance of this structure */
50 typedef struct tagWINE_MM_DRIVER
{
52 LPSTR drvname
; /* name of the driver */
53 BOOL bIs32
: 1, /* TRUE if 32 bit driver, FALSE for 16 */
54 bIsMapper
: 1; /* TRUE if mapper */
55 WINE_MM_DRIVER_PART parts
[MMDRV_MAX
];/* Information for all known types */
56 } WINE_MM_DRIVER
, *LPWINE_MM_DRIVER
;
59 MMDRV_MAP_NOMEM
, /* ko, memory problem */
60 MMDRV_MAP_MSGERROR
, /* ko, unknown message */
61 MMDRV_MAP_OK
, /* ok, no memory allocated. to be sent to the proc. */
62 MMDRV_MAP_OKMEM
, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
63 MMDRV_MAP_PASS
/* not handled (no memory allocated) to be sent to the driver */
66 typedef MMDRV_MapType (*MMDRV_MAPFUNC
)(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
);
68 /* each known type of driver has an instance of this structure */
69 typedef struct tagWINE_LLTYPE
{
70 /* those attributes depend on the specification of the type */
71 LPSTR typestr
; /* name (for debugging) */
72 BOOL bSupportMapper
; /* if type is allowed to support mapper */
73 MMDRV_MAPFUNC Map16To32A
; /* those are function pointers to handle */
74 MMDRV_MAPFUNC UnMap16To32A
; /* the parameter conversion (16 vs 32 bit) */
75 MMDRV_MAPFUNC Map32ATo16
; /* when hi-func (in mmsystem or winmm) and */
76 MMDRV_MAPFUNC UnMap32ATo16
; /* low-func (in .drv) do not match */
77 LPDRVCALLBACK Callback
; /* handles callback for a specified type */
78 /* those attributes reflect the loaded/current situation for the type */
79 UINT wMaxId
; /* number of loaded devices (sum across all loaded drivers */
80 LPWINE_MLD lpMlds
; /* "static" mlds to access the part though device IDs */
81 int nMapper
; /* index to mapper */
84 static int MMDrvsHi
/* = 0 */;
85 static WINE_MM_DRIVER MMDrvs
[3];
86 static LPWINE_MLD MM_MLDrvs
[40];
87 #define MAX_MM_MLDRVS (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
89 /* ### start build ### */
90 extern WORD CALLBACK
MMDRV_CallTo16_word_wwlll(FARPROC16
,WORD
,WORD
,LONG
,LONG
,LONG
);
91 /* ### stop build ### */
93 /**************************************************************************
94 * MMDRV_GetDescription16 [internal]
96 static BOOL
MMDRV_GetDescription16(const char* fname
, char* buf
, int buflen
)
104 if ((hFile
= OpenFile(fname
, &ofs
, OF_READ
| OF_SHARE_DENY_WRITE
)) == HFILE_ERROR
) {
105 ERR("Can't open file %s (builtin driver ?)\n", fname
);
109 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
111 if (_lread(hFile
, &w
, 2) != 2) E(("Can't read sig\n"));
112 if (w
!= ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w
));
113 if (_llseek(hFile
, 0x3C, SEEK_SET
) < 0) E(("Can't seek to ext header offset\n"));
114 if (_lread(hFile
, &dw
, 4) != 4) E(("Can't read ext header offset\n"));
115 if (_llseek(hFile
, dw
+ 0x2C, SEEK_SET
) < 0) E(("Can't seek to ext header.nr table %lu\n", dw
+0x2C));
116 if (_lread(hFile
, &dw
, 4) != 4) E(("Can't read nr table offset\n"));
117 if (_llseek(hFile
, dw
, SEEK_SET
) < 0) E(("Can't seek to nr table %lu\n", dw
));
118 if (_lread(hFile
, buf
, 1) != 1) E(("Can't read descr length\n"));
119 buflen
= min((int)(unsigned)(BYTE
)buf
[0], buflen
- 1);
120 if (_lread(hFile
, buf
, buflen
) != buflen
) E(("Can't read descr (%d)\n", buflen
));
123 TRACE("Got '%s' [%d]\n", buf
, buflen
);
129 /**************************************************************************
130 * MMDRV_GetDescription32 [internal]
132 static BOOL
MMDRV_GetDescription32(const char* fname
, char* buf
, int buflen
)
141 FARPROC pGetFileVersionInfoSizeA
;
142 FARPROC pGetFileVersionInfoA
;
143 FARPROC pVerQueryValueA
;
146 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
148 if (OpenFile(fname
, &ofs
, OF_EXIST
)==HFILE_ERROR
) E(("Can't find file %s\n", fname
));
150 if (!(hmodule
= LoadLibraryA( "version.dll" ))) goto theEnd
;
151 if (!(pGetFileVersionInfoSizeA
= GetProcAddress( hmodule
, "GetFileVersionInfoSizeA" )))
153 if (!(pGetFileVersionInfoA
= GetProcAddress( hmodule
, "GetFileVersionInfoA" )))
155 if (!(pVerQueryValueA
= GetProcAddress( hmodule
, "pVerQueryValueA" )))
158 if (!(dw
= pGetFileVersionInfoSizeA(ofs
.szPathName
, &h
))) E(("Can't get FVIS\n"));
159 if (!(ptr
= HeapAlloc(GetProcessHeap(), 0, dw
))) E(("OOM\n"));
160 if (!pGetFileVersionInfoA(ofs
.szPathName
, h
, dw
, ptr
)) E(("Can't get FVI\n"));
162 #define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
163 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
179 if (!pVerQueryValueA(ptr
, "\\StringFileInfo\\040904B0\\ProductName", &val
, &u
)) E(("Can't get product name\n"));
180 lstrcpynA(buf
, val
, buflen
);
185 HeapFree(GetProcessHeap(), 0, ptr
);
186 if (hmodule
) FreeLibrary( hmodule
);
190 /**************************************************************************
191 * MMDRV_Callback [internal]
193 static void MMDRV_Callback(LPWINE_MLD mld
, HDRVR hDev
, UINT uMsg
, DWORD dwParam1
, DWORD dwParam2
)
195 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
196 mld
->dwCallback
, hDev
, uMsg
, mld
->dwClientInstance
, dwParam1
, dwParam2
);
198 if (!mld
->bFrom32
&& (mld
->dwFlags
& DCB_TYPEMASK
) == DCB_FUNCTION
) {
199 /* 16 bit func, call it */
200 TRACE("Function (16 bit) !\n");
201 MMDRV_CallTo16_word_wwlll((FARPROC16
)mld
->dwCallback
, HDRVR_16(hDev
), uMsg
,
202 mld
->dwClientInstance
, dwParam1
, dwParam2
);
204 DriverCallback(mld
->dwCallback
, mld
->dwFlags
, hDev
, uMsg
,
205 mld
->dwClientInstance
, dwParam1
, dwParam2
);
209 /* =================================
210 * A U X M A P P E R S
211 * ================================= */
213 /**************************************************************************
214 * MMDRV_Aux_Map16To32A [internal]
216 static MMDRV_MapType
MMDRV_Aux_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
218 return MMDRV_MAP_MSGERROR
;
221 /**************************************************************************
222 * MMDRV_Aux_UnMap16To32A [internal]
224 static MMDRV_MapType
MMDRV_Aux_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
226 return MMDRV_MAP_MSGERROR
;
229 /**************************************************************************
230 * MMDRV_Aux_Map32ATo16 [internal]
232 static MMDRV_MapType
MMDRV_Aux_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
234 return MMDRV_MAP_MSGERROR
;
237 /**************************************************************************
238 * MMDRV_Aux_UnMap32ATo16 [internal]
240 static MMDRV_MapType
MMDRV_Aux_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
243 case AUXDM_GETDEVCAPS
:
244 lpCaps
->wMid
= ac16
.wMid
;
245 lpCaps
->wPid
= ac16
.wPid
;
246 lpCaps
->vDriverVersion
= ac16
.vDriverVersion
;
247 strcpy(lpCaps
->szPname
, ac16
.szPname
);
248 lpCaps
->wTechnology
= ac16
.wTechnology
;
249 lpCaps
->dwSupport
= ac16
.dwSupport
;
251 return MMDRV_MAP_MSGERROR
;
254 /**************************************************************************
255 * MMDRV_Aux_Callback [internal]
257 static void CALLBACK
MMDRV_Aux_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
259 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
262 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
265 /* =================================
266 * M I X E R M A P P E R S
267 * ================================= */
269 /**************************************************************************
270 * xMMDRV_Mixer_Map16To32A [internal]
272 static MMDRV_MapType
MMDRV_Mixer_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
274 return MMDRV_MAP_MSGERROR
;
277 /**************************************************************************
278 * MMDRV_Mixer_UnMap16To32A [internal]
280 static MMDRV_MapType
MMDRV_Mixer_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
284 UINT ret
= mixerGetDevCapsA(devid
, &micA
, sizeof(micA
));
286 if (ret
== MMSYSERR_NOERROR
) {
287 mixcaps
->wMid
= micA
.wMid
;
288 mixcaps
->wPid
= micA
.wPid
;
289 mixcaps
->vDriverVersion
= micA
.vDriverVersion
;
290 strcpy(mixcaps
->szPname
, micA
.szPname
);
291 mixcaps
->fdwSupport
= micA
.fdwSupport
;
292 mixcaps
->cDestinations
= micA
.cDestinations
;
296 return MMDRV_MAP_MSGERROR
;
299 /**************************************************************************
300 * MMDRV_Mixer_Map32ATo16 [internal]
302 static MMDRV_MapType
MMDRV_Mixer_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
304 return MMDRV_MAP_MSGERROR
;
307 /**************************************************************************
308 * MMDRV_Mixer_UnMap32ATo16 [internal]
310 static MMDRV_MapType
MMDRV_Mixer_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
312 return MMDRV_MAP_MSGERROR
;
315 /**************************************************************************
316 * MMDRV_Mixer_Callback [internal]
318 static void CALLBACK
MMDRV_Mixer_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
320 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
323 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
326 /* =================================
327 * M I D I I N M A P P E R S
328 * ================================= */
330 /**************************************************************************
331 * MMDRV_MidiIn_Map16To32A [internal]
333 static MMDRV_MapType
MMDRV_MidiIn_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
335 return MMDRV_MAP_MSGERROR
;
338 /**************************************************************************
339 * MMDRV_MidiIn_UnMap16To32A [internal]
341 static MMDRV_MapType
MMDRV_MidiIn_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
343 return MMDRV_MAP_MSGERROR
;
346 /**************************************************************************
347 * MMDRV_MidiIn_Map32ATo16 [internal]
349 static MMDRV_MapType
MMDRV_MidiIn_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
351 return MMDRV_MAP_MSGERROR
;
354 /**************************************************************************
355 * MMDRV_MidiIn_UnMap32ATo16 [internal]
357 static MMDRV_MapType
MMDRV_MidiIn_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
359 return MMDRV_MAP_MSGERROR
;
362 /**************************************************************************
363 * MMDRV_MidiIn_Callback [internal]
365 static void CALLBACK
MMDRV_MidiIn_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
367 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
372 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
377 /* dwParam1 & dwParam2 are are data, nothing to do */
381 /* dwParam1 points to a MidiHdr, work to be done !!! */
382 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
383 /* initial map is: 32 => 16 */
384 LPMIDIHDR mh16
= MapSL(dwParam1
);
385 LPMIDIHDR mh32
= *(LPMIDIHDR
*)((LPSTR
)mh16
- sizeof(LPMIDIHDR
));
387 dwParam1
= (DWORD
)mh32
;
388 mh32
->dwFlags
= mh16
->dwFlags
;
389 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
390 if (mh32
->reserved
>= sizeof(MIDIHDR
))
391 mh32
->dwOffset
= mh16
->dwOffset
;
392 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
393 /* initial map is: 16 => 32 */
394 LPMIDIHDR mh32
= (LPMIDIHDR
)(dwParam1
);
395 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
396 LPMIDIHDR mh16
= MapSL(segmh16
);
398 dwParam1
= (DWORD
)segmh16
;
399 mh16
->dwFlags
= mh32
->dwFlags
;
400 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
401 if (mh16
->reserved
>= sizeof(MIDIHDR
))
402 mh16
->dwOffset
= mh32
->dwOffset
;
404 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
406 /* case MOM_POSITIONCB: */
408 ERR("Unknown msg %u\n", uMsg
);
411 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
414 /* =================================
415 * M I D I O U T M A P P E R S
416 * ================================= */
418 /**************************************************************************
419 * MMDRV_MidiOut_Map16To32A [internal]
421 static MMDRV_MapType
MMDRV_MidiOut_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
423 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
426 case MODM_GETNUMDEVS
:
436 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
439 case MODM_GETDEVCAPS
:
441 LPMIDIOUTCAPSA moc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16
) + sizeof(MIDIOUTCAPSA
));
442 LPMIDIOUTCAPS16 moc16
= MapSL(*lpParam1
);
445 *(LPMIDIOUTCAPS16
*)moc32
= moc16
;
446 moc32
= (LPMIDIOUTCAPSA
)((LPSTR
)moc32
+ sizeof(LPMIDIOUTCAPS16
));
447 *lpParam1
= (DWORD
)moc32
;
448 *lpParam2
= sizeof(MIDIOUTCAPSA
);
450 ret
= MMDRV_MAP_OKMEM
;
452 ret
= MMDRV_MAP_NOMEM
;
458 LPMIDIHDR mh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
));
459 LPMIDIHDR mh16
= MapSL(*lpParam1
);
462 *(LPMIDIHDR
*)mh32
= (LPMIDIHDR
)*lpParam1
;
463 mh32
= (LPMIDIHDR
)((LPSTR
)mh32
+ sizeof(LPMIDIHDR
));
464 mh32
->lpData
= MapSL((SEGPTR
)mh16
->lpData
);
465 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
466 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
467 mh32
->dwUser
= mh16
->dwUser
;
468 mh32
->dwFlags
= mh16
->dwFlags
;
469 /* FIXME: nothing on mh32->lpNext */
470 /* could link the mh32->lpNext at this level for memory house keeping */
471 mh32
->dwOffset
= (*lpParam2
>= sizeof(MIDIHDR
)) ? ((LPMIDIHDR
)mh16
)->dwOffset
: 0;
472 mh16
->lpNext
= mh32
; /* for reuse in unprepare and write */
473 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
474 mh16
->reserved
= *lpParam2
;
475 *lpParam1
= (DWORD
)mh32
;
476 *lpParam2
= sizeof(MIDIHDR
);
478 ret
= MMDRV_MAP_OKMEM
;
480 ret
= MMDRV_MAP_NOMEM
;
487 LPMIDIHDR mh16
= MapSL(*lpParam1
);
488 LPMIDIHDR mh32
= (LPMIDIHDR
)mh16
->lpNext
;
490 *lpParam1
= (DWORD
)mh32
;
491 *lpParam2
= sizeof(MIDIHDR
);
492 /* dwBufferLength can be reduced between prepare & write */
493 if (wMsg
== MODM_LONGDATA
&& mh32
->dwBufferLength
< mh16
->dwBufferLength
) {
494 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
495 mh32
->dwBufferLength
, mh16
->dwBufferLength
);
497 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
498 ret
= MMDRV_MAP_OKMEM
;
502 case MODM_CACHEPATCHES
:
503 case MODM_CACHEDRUMPATCHES
:
505 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
511 /**************************************************************************
512 * MMDRV_MidiOut_UnMap16To32A [internal]
514 static MMDRV_MapType
MMDRV_MidiOut_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
516 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
519 case MODM_GETNUMDEVS
:
529 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
532 case MODM_GETDEVCAPS
:
534 LPMIDIOUTCAPSA moc32
= (LPMIDIOUTCAPSA
)(*lpParam1
);
535 LPMIDIOUTCAPS16 moc16
= *(LPMIDIOUTCAPS16
*)((LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
537 moc16
->wMid
= moc32
->wMid
;
538 moc16
->wPid
= moc32
->wPid
;
539 moc16
->vDriverVersion
= moc32
->vDriverVersion
;
540 strcpy(moc16
->szPname
, moc32
->szPname
);
541 moc16
->wTechnology
= moc32
->wTechnology
;
542 moc16
->wVoices
= moc32
->wVoices
;
543 moc16
->wNotes
= moc32
->wNotes
;
544 moc16
->wChannelMask
= moc32
->wChannelMask
;
545 moc16
->dwSupport
= moc32
->dwSupport
;
546 HeapFree(GetProcessHeap(), 0, (LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
554 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
555 LPMIDIHDR mh16
= MapSL(*(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
)));
557 assert(mh16
->lpNext
== mh32
);
558 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
559 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
560 mh16
->dwUser
= mh32
->dwUser
;
561 mh16
->dwFlags
= mh32
->dwFlags
;
562 if (mh16
->reserved
>= sizeof(MIDIHDR
))
563 mh16
->dwOffset
= mh32
->dwOffset
;
565 if (wMsg
== MODM_UNPREPARE
) {
566 HeapFree(GetProcessHeap(), 0, (LPSTR
)mh32
- sizeof(LPMIDIHDR
));
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_Map32ATo16 [internal]
585 static MMDRV_MapType
MMDRV_MidiOut_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
587 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
591 case MODM_GETNUMDEVS
:
597 case MODM_GETDEVCAPS
:
599 LPMIDIOUTCAPSA moc32
= (LPMIDIOUTCAPSA
)*lpParam1
;
600 LPSTR ptr
= HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA
)+sizeof(MIDIOUTCAPS16
));
603 *(LPMIDIOUTCAPSA
*)ptr
= moc32
;
604 ret
= MMDRV_MAP_OKMEM
;
606 ret
= MMDRV_MAP_NOMEM
;
608 *lpParam1
= (DWORD
)MapLS(ptr
) + sizeof(LPMIDIOUTCAPSA
);
609 *lpParam2
= sizeof(MIDIOUTCAPS16
);
614 LPMIDIHDR mh32
= (LPMIDIHDR
)*lpParam1
;
616 LPVOID ptr
= HeapAlloc( GetProcessHeap(), 0,
617 sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
) + mh32
->dwBufferLength
);
620 *(LPMIDIHDR
*)ptr
= mh32
;
621 mh16
= (LPMIDIHDR
)((LPSTR
)ptr
+ sizeof(LPMIDIHDR
));
622 *lpParam1
= MapLS(mh16
);
623 mh16
->lpData
= (LPSTR
)*lpParam1
+ sizeof(MIDIHDR
);
624 /* data will be copied on WODM_WRITE */
625 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
626 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
627 mh16
->dwUser
= mh32
->dwUser
;
628 mh16
->dwFlags
= mh32
->dwFlags
;
629 /* FIXME: nothing on mh32->lpNext */
630 /* could link the mh32->lpNext at this level for memory house keeping */
631 mh16
->dwOffset
= (*lpParam2
>= sizeof(MIDIHDR
)) ? mh32
->dwOffset
: 0;
633 mh32
->lpNext
= (LPMIDIHDR
)mh16
; /* for reuse in unprepare and write */
634 mh32
->reserved
= *lpParam2
;
636 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
637 *lpParam1
, (DWORD
)mh16
->lpData
,
638 mh32
->dwBufferLength
, (DWORD
)mh32
->lpData
);
639 *lpParam2
= sizeof(MIDIHDR
);
641 ret
= MMDRV_MAP_OKMEM
;
643 ret
= MMDRV_MAP_NOMEM
;
650 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
651 LPMIDIHDR mh16
= (LPMIDIHDR
)mh32
->lpNext
;
652 LPSTR ptr
= (LPSTR
)mh16
- sizeof(LPMIDIHDR
);
654 assert(*(LPMIDIHDR
*)ptr
== mh32
);
656 if (wMsg
== MODM_LONGDATA
)
657 memcpy((LPSTR
)mh16
+ sizeof(MIDIHDR
), mh32
->lpData
, mh32
->dwBufferLength
);
659 *lpParam1
= MapLS(mh16
);
660 *lpParam2
= sizeof(MIDIHDR
);
661 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
662 *lpParam1
, (DWORD
)mh16
->lpData
, mh32
->dwBufferLength
, (DWORD
)mh32
->lpData
);
664 /* dwBufferLength can be reduced between prepare & write */
665 if (wMsg
== MODM_LONGDATA
&& mh16
->dwBufferLength
< mh32
->dwBufferLength
) {
666 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
667 mh16
->dwBufferLength
, mh32
->dwBufferLength
);
669 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
670 ret
= MMDRV_MAP_OKMEM
;
675 LPMIDIOPENDESC mod32
= (LPMIDIOPENDESC
)*lpParam1
;
677 LPMIDIOPENDESC16 mod16
;
679 /* allocated data are mapped as follows:
680 LPMIDIOPENDESC ptr to orig lParam1
681 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
682 DWORD dwUser passed to driver
683 MIDIOPENDESC16 mod16: openDesc passed to driver
686 ptr
= HeapAlloc( GetProcessHeap(), 0,
687 sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
) + sizeof(MIDIOPENDESC16
) +
688 mod32
->cIds
? (mod32
->cIds
- 1) * sizeof(MIDIOPENSTRMID
) : 0);
691 SEGPTR segptr
= MapLS(ptr
);
692 *(LPMIDIOPENDESC
*)ptr
= mod32
;
693 *(LPDWORD
)((char*)ptr
+ sizeof(LPMIDIOPENDESC
)) = *lpdwUser
;
694 mod16
= (LPMIDIOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
));
696 mod16
->hMidi
= HMIDI_16(mod32
->hMidi
);
697 mod16
->dwCallback
= mod32
->dwCallback
;
698 mod16
->dwInstance
= mod32
->dwInstance
;
699 mod16
->dnDevNode
= mod32
->dnDevNode
;
700 mod16
->cIds
= mod32
->cIds
;
701 memcpy(&mod16
->rgIds
, &mod32
->rgIds
, mod32
->cIds
* sizeof(MIDIOPENSTRMID
));
703 *lpParam1
= (DWORD
)segptr
+ sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
);
704 *lpdwUser
= (DWORD
)segptr
+ sizeof(LPMIDIOPENDESC
) + sizeof(DWORD
);
706 ret
= MMDRV_MAP_OKMEM
;
708 ret
= MMDRV_MAP_NOMEM
;
713 case MODM_CACHEPATCHES
:
714 case MODM_CACHEDRUMPATCHES
:
716 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
722 /**************************************************************************
723 * MMDRV_MidiOut_UnMap32ATo16 [internal]
725 static MMDRV_MapType
MMDRV_MidiOut_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
727 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
731 case MODM_GETNUMDEVS
:
737 case MODM_GETDEVCAPS
:
739 LPMIDIOUTCAPS16 moc16
= MapSL(*lpParam1
);
740 LPSTR ptr
= (LPSTR
)moc16
- sizeof(LPMIDIOUTCAPSA
);
741 LPMIDIOUTCAPSA moc32
= *(LPMIDIOUTCAPSA
*)ptr
;
743 moc32
->wMid
= moc16
->wMid
;
744 moc32
->wPid
= moc16
->wPid
;
745 moc32
->vDriverVersion
= moc16
->vDriverVersion
;
746 strcpy(moc32
->szPname
, moc16
->szPname
);
747 moc32
->wTechnology
= moc16
->wTechnology
;
748 moc32
->wVoices
= moc16
->wVoices
;
749 moc32
->wNotes
= moc16
->wNotes
;
750 moc32
->wChannelMask
= moc16
->wChannelMask
;
751 moc32
->dwSupport
= moc16
->dwSupport
;
752 UnMapLS( *lpParam1
);
753 HeapFree( GetProcessHeap(), 0, ptr
);
761 LPMIDIHDR mh16
= MapSL(*lpParam1
);
762 LPSTR ptr
= (LPSTR
)mh16
- sizeof(LPMIDIHDR
);
763 LPMIDIHDR mh32
= *(LPMIDIHDR
*)ptr
;
765 assert(mh32
->lpNext
== (LPMIDIHDR
)mh16
);
766 UnMapLS( *lpParam1
);
767 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
768 mh32
->dwUser
= mh16
->dwUser
;
769 mh32
->dwFlags
= mh16
->dwFlags
;
771 if (wMsg
== MODM_UNPREPARE
) {
772 HeapFree( GetProcessHeap(), 0, ptr
);
780 LPMIDIOPENDESC16 mod16
= MapSL(*lpParam1
);
781 LPSTR ptr
= (LPSTR
)mod16
- sizeof(LPMIDIOPENDESC
) - 2*sizeof(DWORD
);
782 UnMapLS( *lpParam1
);
783 **(DWORD
**)(ptr
+ sizeof(LPMIDIOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPMIDIOPENDESC
) + sizeof(DWORD
));
785 HeapFree( GetProcessHeap(), 0, ptr
);
790 case MODM_CACHEPATCHES
:
791 case MODM_CACHEDRUMPATCHES
:
793 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
799 /**************************************************************************
800 * MMDRV_MidiOut_Callback [internal]
802 static void CALLBACK
MMDRV_MidiOut_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
804 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
809 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
812 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
813 /* initial map is: 32 => 16 */
814 LPMIDIHDR mh16
= MapSL(dwParam1
);
815 LPMIDIHDR mh32
= *(LPMIDIHDR
*)((LPSTR
)mh16
- sizeof(LPMIDIHDR
));
817 dwParam1
= (DWORD
)mh32
;
818 mh32
->dwFlags
= mh16
->dwFlags
;
819 mh32
->dwOffset
= mh16
->dwOffset
;
820 if (mh32
->reserved
>= sizeof(MIDIHDR
))
821 mh32
->dwOffset
= mh16
->dwOffset
;
822 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
823 /* initial map is: 16 => 32 */
824 LPMIDIHDR mh32
= (LPMIDIHDR
)(dwParam1
);
825 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
826 LPMIDIHDR mh16
= MapSL(segmh16
);
828 dwParam1
= (DWORD
)segmh16
;
829 mh16
->dwFlags
= mh32
->dwFlags
;
830 if (mh16
->reserved
>= sizeof(MIDIHDR
))
831 mh16
->dwOffset
= mh32
->dwOffset
;
833 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
835 /* case MOM_POSITIONCB: */
837 ERR("Unknown msg %u\n", uMsg
);
840 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
843 /* =================================
844 * W A V E I N M A P P E R S
845 * ================================= */
847 /**************************************************************************
848 * MMDRV_WaveIn_Map16To32A [internal]
850 static MMDRV_MapType
MMDRV_WaveIn_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
852 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
855 case WIDM_GETNUMDEVS
:
863 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
865 case WIDM_GETDEVCAPS
:
867 LPWAVEINCAPSA wic32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16
) + sizeof(WAVEINCAPSA
));
868 LPWAVEINCAPS16 wic16
= MapSL(*lpParam1
);
871 *(LPWAVEINCAPS16
*)wic32
= wic16
;
872 wic32
= (LPWAVEINCAPSA
)((LPSTR
)wic32
+ sizeof(LPWAVEINCAPS16
));
873 *lpParam1
= (DWORD
)wic32
;
874 *lpParam2
= sizeof(WAVEINCAPSA
);
876 ret
= MMDRV_MAP_OKMEM
;
878 ret
= MMDRV_MAP_NOMEM
;
884 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
885 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
888 *(LPMMTIME16
*)mmt32
= mmt16
;
889 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
891 mmt32
->wType
= mmt16
->wType
;
892 *lpParam1
= (DWORD
)mmt32
;
893 *lpParam2
= sizeof(MMTIME
);
895 ret
= MMDRV_MAP_OKMEM
;
897 ret
= MMDRV_MAP_NOMEM
;
903 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
904 LPWAVEHDR wh16
= MapSL(*lpParam1
);
907 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
908 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
909 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
910 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
911 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
912 wh32
->dwUser
= wh16
->dwUser
;
913 wh32
->dwFlags
= wh16
->dwFlags
;
914 wh32
->dwLoops
= wh16
->dwLoops
;
915 /* FIXME: nothing on wh32->lpNext */
916 /* could link the wh32->lpNext at this level for memory house keeping */
917 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
918 *lpParam1
= (DWORD
)wh32
;
919 *lpParam2
= sizeof(WAVEHDR
);
921 ret
= MMDRV_MAP_OKMEM
;
923 ret
= MMDRV_MAP_NOMEM
;
930 LPWAVEHDR wh16
= MapSL(*lpParam1
);
931 LPWAVEHDR wh32
= (LPWAVEHDR
)wh16
->lpNext
;
933 *lpParam1
= (DWORD
)wh32
;
934 *lpParam2
= sizeof(WAVEHDR
);
935 /* dwBufferLength can be reduced between prepare & write */
936 if (wMsg
== WIDM_ADDBUFFER
&& wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
937 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
938 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
940 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
941 ret
= MMDRV_MAP_OKMEM
;
944 case WIDM_MAPPER_STATUS
:
945 /* just a single DWORD */
946 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
950 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
956 /**************************************************************************
957 * MMDRV_WaveIn_UnMap16To32A [internal]
959 static MMDRV_MapType
MMDRV_WaveIn_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
961 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
964 case WIDM_GETNUMDEVS
:
968 case WIDM_MAPPER_STATUS
:
973 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
975 case WIDM_GETDEVCAPS
:
977 LPWAVEINCAPSA wic32
= (LPWAVEINCAPSA
)(*lpParam1
);
978 LPWAVEINCAPS16 wic16
= *(LPWAVEINCAPS16
*)((LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
980 wic16
->wMid
= wic32
->wMid
;
981 wic16
->wPid
= wic32
->wPid
;
982 wic16
->vDriverVersion
= wic32
->vDriverVersion
;
983 strcpy(wic16
->szPname
, wic32
->szPname
);
984 wic16
->dwFormats
= wic32
->dwFormats
;
985 wic16
->wChannels
= wic32
->wChannels
;
986 HeapFree(GetProcessHeap(), 0, (LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
992 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
993 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
995 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
996 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1000 case WIDM_ADDBUFFER
:
1002 case WIDM_UNPREPARE
:
1004 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1005 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
1007 assert(wh16
->lpNext
== wh32
);
1008 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1009 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1010 wh16
->dwUser
= wh32
->dwUser
;
1011 wh16
->dwFlags
= wh32
->dwFlags
;
1012 wh16
->dwLoops
= wh32
->dwLoops
;
1014 if (wMsg
== WIDM_UNPREPARE
) {
1015 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1022 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1028 /**************************************************************************
1029 * MMDRV_WaveIn_Map32ATo16 [internal]
1031 static MMDRV_MapType
MMDRV_WaveIn_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1033 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1037 case WIDM_GETNUMDEVS
:
1046 LPWAVEOPENDESC wod32
= (LPWAVEOPENDESC
)*lpParam1
;
1047 int sz
= sizeof(WAVEFORMATEX
);
1049 LPWAVEOPENDESC16 wod16
;
1051 /* allocated data are mapped as follows:
1052 LPWAVEOPENDESC ptr to orig lParam1
1053 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1054 DWORD dwUser passed to driver
1055 WAVEOPENDESC16 wod16: openDesc passed to driver
1056 WAVEFORMATEX openDesc->lpFormat passed to driver
1057 xxx extra bytes to WAVEFORMATEX
1059 if (wod32
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
1060 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
, wod32
->lpFormat
->wFormatTag
);
1061 sz
+= ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
;
1064 ptr
= HeapAlloc( GetProcessHeap(), 0,
1065 sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
) + sz
);
1068 SEGPTR seg_ptr
= MapLS( ptr
);
1069 *(LPWAVEOPENDESC
*)ptr
= wod32
;
1070 *(LPDWORD
)((char*)ptr
+ sizeof(LPWAVEOPENDESC
)) = *lpdwUser
;
1071 wod16
= (LPWAVEOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
));
1073 wod16
->hWave
= HWAVE_16(wod32
->hWave
);
1074 wod16
->lpFormat
= (LPWAVEFORMATEX
)(seg_ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
));
1075 memcpy(wod16
+ 1, wod32
->lpFormat
, sz
);
1077 wod16
->dwCallback
= wod32
->dwCallback
;
1078 wod16
->dwInstance
= wod32
->dwInstance
;
1079 wod16
->uMappedDeviceID
= wod32
->uMappedDeviceID
;
1080 wod16
->dnDevNode
= wod32
->dnDevNode
;
1082 *lpParam1
= seg_ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
);
1083 *lpdwUser
= seg_ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
);
1085 ret
= MMDRV_MAP_OKMEM
;
1087 ret
= MMDRV_MAP_NOMEM
;
1093 LPWAVEHDR wh32
= (LPWAVEHDR
)*lpParam1
;
1095 LPVOID ptr
= HeapAlloc( GetProcessHeap(), 0,
1096 sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
) + wh32
->dwBufferLength
);
1099 SEGPTR seg_ptr
= MapLS( ptr
);
1100 *(LPWAVEHDR
*)ptr
= wh32
;
1101 wh16
= (LPWAVEHDR
)((LPSTR
)ptr
+ sizeof(LPWAVEHDR
));
1102 wh16
->lpData
= (LPSTR
)seg_ptr
+ sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
);
1103 /* data will be copied on WODM_WRITE */
1104 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1105 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1106 wh16
->dwUser
= wh32
->dwUser
;
1107 wh16
->dwFlags
= wh32
->dwFlags
;
1108 wh16
->dwLoops
= wh32
->dwLoops
;
1109 /* FIXME: nothing on wh32->lpNext */
1110 /* could link the wh32->lpNext at this level for memory house keeping */
1111 wh32
->lpNext
= wh16
; /* for reuse in unprepare and write */
1112 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1113 seg_ptr
+ sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1114 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1115 *lpParam1
= seg_ptr
+ sizeof(LPWAVEHDR
);
1116 *lpParam2
= sizeof(WAVEHDR
);
1118 ret
= MMDRV_MAP_OKMEM
;
1120 ret
= MMDRV_MAP_NOMEM
;
1124 case WIDM_ADDBUFFER
:
1125 case WIDM_UNPREPARE
:
1127 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1128 LPWAVEHDR wh16
= wh32
->lpNext
;
1129 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1130 SEGPTR seg_ptr
= MapLS( ptr
);
1132 assert(*(LPWAVEHDR
*)ptr
== wh32
);
1134 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1135 seg_ptr
+ sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1136 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1138 if (wMsg
== WIDM_ADDBUFFER
)
1139 memcpy((LPSTR
)wh16
+ sizeof(WAVEHDR
), wh32
->lpData
, wh32
->dwBufferLength
);
1141 *lpParam1
= seg_ptr
+ sizeof(LPWAVEHDR
);
1142 *lpParam2
= sizeof(WAVEHDR
);
1143 /* dwBufferLength can be reduced between prepare & write */
1144 if (wMsg
== WIDM_ADDBUFFER
&& wh16
->dwBufferLength
< wh32
->dwBufferLength
) {
1145 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1146 wh16
->dwBufferLength
, wh32
->dwBufferLength
);
1148 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1149 ret
= MMDRV_MAP_OKMEM
;
1152 case WIDM_GETDEVCAPS
:
1154 LPWAVEINCAPSA wic32
= (LPWAVEINCAPSA
)*lpParam1
;
1155 LPSTR ptr
= HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA
) + sizeof(WAVEINCAPS16
));
1158 *(LPWAVEINCAPSA
*)ptr
= wic32
;
1159 ret
= MMDRV_MAP_OKMEM
;
1161 ret
= MMDRV_MAP_NOMEM
;
1163 *lpParam1
= MapLS(ptr
) + sizeof(LPWAVEINCAPSA
);
1164 *lpParam2
= sizeof(WAVEINCAPS16
);
1169 LPMMTIME mmt32
= (LPMMTIME
)*lpParam1
;
1170 LPSTR ptr
= HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME
) + sizeof(MMTIME16
));
1171 LPMMTIME16 mmt16
= (LPMMTIME16
)(ptr
+ sizeof(LPMMTIME
));
1174 *(LPMMTIME
*)ptr
= mmt32
;
1175 mmt16
->wType
= mmt32
->wType
;
1176 ret
= MMDRV_MAP_OKMEM
;
1178 ret
= MMDRV_MAP_NOMEM
;
1180 *lpParam1
= MapLS(ptr
) + sizeof(LPMMTIME
);
1181 *lpParam2
= sizeof(MMTIME16
);
1184 case DRVM_MAPPER_STATUS
:
1186 LPDWORD p32
= (LPDWORD
)*lpParam2
;
1187 *lpParam2
= MapLS(p32
);
1188 ret
= MMDRV_MAP_OKMEM
;
1192 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1198 /**************************************************************************
1199 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1201 static MMDRV_MapType
MMDRV_WaveIn_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1203 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1207 case WIDM_GETNUMDEVS
:
1216 LPWAVEOPENDESC16 wod16
= MapSL(*lpParam1
);
1217 LPSTR ptr
= (LPSTR
)wod16
- sizeof(LPWAVEOPENDESC
) - 2*sizeof(DWORD
);
1218 LPWAVEOPENDESC wod32
= *(LPWAVEOPENDESC
*)ptr
;
1220 UnMapLS( *lpParam1
);
1221 wod32
->uMappedDeviceID
= wod16
->uMappedDeviceID
;
1222 **(DWORD
**)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
));
1223 HeapFree( GetProcessHeap(), 0, ptr
);
1228 case WIDM_ADDBUFFER
:
1230 case WIDM_UNPREPARE
:
1232 LPWAVEHDR wh16
= MapSL(*lpParam1
);
1233 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1234 LPWAVEHDR wh32
= *(LPWAVEHDR
*)ptr
;
1236 assert(wh32
->lpNext
== wh16
);
1237 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1238 wh32
->dwUser
= wh16
->dwUser
;
1239 wh32
->dwFlags
= wh16
->dwFlags
;
1240 wh32
->dwLoops
= wh16
->dwLoops
;
1241 UnMapLS( *lpParam1
);
1243 if (wMsg
== WIDM_UNPREPARE
) {
1244 HeapFree( GetProcessHeap(), 0, ptr
);
1250 case WIDM_GETDEVCAPS
:
1252 LPWAVEINCAPS16 wic16
= MapSL(*lpParam1
);
1253 LPSTR ptr
= (LPSTR
)wic16
- sizeof(LPWAVEINCAPSA
);
1254 LPWAVEINCAPSA wic32
= *(LPWAVEINCAPSA
*)ptr
;
1256 wic32
->wMid
= wic16
->wMid
;
1257 wic32
->wPid
= wic16
->wPid
;
1258 wic32
->vDriverVersion
= wic16
->vDriverVersion
;
1259 strcpy(wic32
->szPname
, wic16
->szPname
);
1260 wic32
->dwFormats
= wic16
->dwFormats
;
1261 wic32
->wChannels
= wic16
->wChannels
;
1262 UnMapLS( *lpParam1
);
1263 HeapFree( GetProcessHeap(), 0, ptr
);
1269 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
1270 LPSTR ptr
= (LPSTR
)mmt16
- sizeof(LPMMTIME
);
1271 LPMMTIME mmt32
= *(LPMMTIME
*)ptr
;
1273 MMSYSTEM_MMTIME16to32(mmt32
, mmt16
);
1274 UnMapLS( *lpParam1
);
1275 HeapFree( GetProcessHeap(), 0, ptr
);
1279 case DRVM_MAPPER_STATUS
:
1281 UnMapLS( *lpParam2
);
1286 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1292 /**************************************************************************
1293 * MMDRV_WaveIn_Callback [internal]
1295 static void CALLBACK
MMDRV_WaveIn_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
1297 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
1302 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1305 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
1306 /* initial map is: 32 => 16 */
1307 LPWAVEHDR wh16
= MapSL(dwParam1
);
1308 LPWAVEHDR wh32
= *(LPWAVEHDR
*)((LPSTR
)wh16
- sizeof(LPWAVEHDR
));
1310 dwParam1
= (DWORD
)wh32
;
1311 wh32
->dwFlags
= wh16
->dwFlags
;
1312 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1313 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
1314 /* initial map is: 16 => 32 */
1315 LPWAVEHDR wh32
= (LPWAVEHDR
)(dwParam1
);
1316 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1317 LPWAVEHDR wh16
= MapSL(segwh16
);
1319 dwParam1
= (DWORD
)segwh16
;
1320 wh16
->dwFlags
= wh32
->dwFlags
;
1321 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1323 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1326 ERR("Unknown msg %u\n", uMsg
);
1329 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
1332 /* =================================
1333 * W A V E O U T M A P P E R S
1334 * ================================= */
1336 /**************************************************************************
1337 * MMDRV_WaveOut_Map16To32A [internal]
1339 static MMDRV_MapType
MMDRV_WaveOut_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1341 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1345 case WODM_BREAKLOOP
:
1347 case WODM_GETNUMDEVS
:
1352 case WODM_SETPLAYBACKRATE
:
1353 case WODM_SETVOLUME
:
1358 case WODM_GETPLAYBACKRATE
:
1359 case WODM_GETVOLUME
:
1361 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1364 case WODM_GETDEVCAPS
:
1366 LPWAVEOUTCAPSA woc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16
) + sizeof(WAVEOUTCAPSA
));
1367 LPWAVEOUTCAPS16 woc16
= MapSL(*lpParam1
);
1370 *(LPWAVEOUTCAPS16
*)woc32
= woc16
;
1371 woc32
= (LPWAVEOUTCAPSA
)((LPSTR
)woc32
+ sizeof(LPWAVEOUTCAPS16
));
1372 *lpParam1
= (DWORD
)woc32
;
1373 *lpParam2
= sizeof(WAVEOUTCAPSA
);
1375 ret
= MMDRV_MAP_OKMEM
;
1377 ret
= MMDRV_MAP_NOMEM
;
1383 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
1384 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
1387 *(LPMMTIME16
*)mmt32
= mmt16
;
1388 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
1390 mmt32
->wType
= mmt16
->wType
;
1391 *lpParam1
= (DWORD
)mmt32
;
1392 *lpParam2
= sizeof(MMTIME
);
1394 ret
= MMDRV_MAP_OKMEM
;
1396 ret
= MMDRV_MAP_NOMEM
;
1402 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
1403 LPWAVEHDR wh16
= MapSL(*lpParam1
);
1406 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
1407 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
1408 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
1409 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1410 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1411 wh32
->dwUser
= wh16
->dwUser
;
1412 wh32
->dwFlags
= wh16
->dwFlags
;
1413 wh32
->dwLoops
= wh16
->dwLoops
;
1414 /* FIXME: nothing on wh32->lpNext */
1415 /* could link the wh32->lpNext at this level for memory house keeping */
1416 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
1417 *lpParam1
= (DWORD
)wh32
;
1418 *lpParam2
= sizeof(WAVEHDR
);
1420 ret
= MMDRV_MAP_OKMEM
;
1422 ret
= MMDRV_MAP_NOMEM
;
1426 case WODM_UNPREPARE
:
1429 LPWAVEHDR wh16
= MapSL(*lpParam1
);
1430 LPWAVEHDR wh32
= (LPWAVEHDR
)wh16
->lpNext
;
1432 *lpParam1
= (DWORD
)wh32
;
1433 *lpParam2
= sizeof(WAVEHDR
);
1434 /* dwBufferLength can be reduced between prepare & write */
1435 if (wMsg
== WODM_WRITE
&& wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
1436 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1437 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
1439 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1440 ret
= MMDRV_MAP_OKMEM
;
1443 case WODM_MAPPER_STATUS
:
1444 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
1448 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1454 /**************************************************************************
1455 * MMDRV_WaveOut_UnMap16To32A [internal]
1457 static MMDRV_MapType
MMDRV_WaveOut_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1459 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1463 case WODM_BREAKLOOP
:
1465 case WODM_GETNUMDEVS
:
1470 case WODM_SETPLAYBACKRATE
:
1471 case WODM_SETVOLUME
:
1472 case WODM_MAPPER_STATUS
:
1477 case WODM_GETPLAYBACKRATE
:
1478 case WODM_GETVOLUME
:
1480 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1483 case WODM_GETDEVCAPS
:
1485 LPWAVEOUTCAPSA woc32
= (LPWAVEOUTCAPSA
)(*lpParam1
);
1486 LPWAVEOUTCAPS16 woc16
= *(LPWAVEOUTCAPS16
*)((LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
1488 woc16
->wMid
= woc32
->wMid
;
1489 woc16
->wPid
= woc32
->wPid
;
1490 woc16
->vDriverVersion
= woc32
->vDriverVersion
;
1491 strcpy(woc16
->szPname
, woc32
->szPname
);
1492 woc16
->dwFormats
= woc32
->dwFormats
;
1493 woc16
->wChannels
= woc32
->wChannels
;
1494 woc16
->dwSupport
= woc32
->dwSupport
;
1495 HeapFree(GetProcessHeap(), 0, (LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
1501 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
1502 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1504 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
1505 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1510 case WODM_UNPREPARE
:
1513 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1514 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
1516 assert(wh16
->lpNext
== wh32
);
1517 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1518 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1519 wh16
->dwUser
= wh32
->dwUser
;
1520 wh16
->dwFlags
= wh32
->dwFlags
;
1521 wh16
->dwLoops
= wh32
->dwLoops
;
1523 if (wMsg
== WODM_UNPREPARE
) {
1524 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1531 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1537 /**************************************************************************
1538 * MMDRV_WaveOut_Map32ATo16 [internal]
1540 static MMDRV_MapType
MMDRV_WaveOut_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1546 case WODM_BREAKLOOP
:
1548 case WODM_GETNUMDEVS
:
1553 case WODM_SETPLAYBACKRATE
:
1554 case WODM_SETVOLUME
:
1558 case WODM_GETDEVCAPS
:
1560 LPWAVEOUTCAPSA woc32
= (LPWAVEOUTCAPSA
)*lpParam1
;
1561 LPSTR ptr
= HeapAlloc( GetProcessHeap(), 0,
1562 sizeof(LPWAVEOUTCAPSA
) + sizeof(WAVEOUTCAPS16
));
1565 *(LPWAVEOUTCAPSA
*)ptr
= woc32
;
1566 ret
= MMDRV_MAP_OKMEM
;
1568 ret
= MMDRV_MAP_NOMEM
;
1570 *lpParam1
= MapLS(ptr
) + sizeof(LPWAVEOUTCAPSA
);
1571 *lpParam2
= sizeof(WAVEOUTCAPS16
);
1575 FIXME("NIY: no conversion yet\n");
1576 ret
= MMDRV_MAP_MSGERROR
;
1578 case WODM_GETPLAYBACKRATE
:
1579 FIXME("NIY: no conversion yet\n");
1580 ret
= MMDRV_MAP_MSGERROR
;
1584 LPMMTIME mmt32
= (LPMMTIME
)*lpParam1
;
1585 LPSTR ptr
= HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME
) + sizeof(MMTIME16
));
1586 LPMMTIME16 mmt16
= (LPMMTIME16
)(ptr
+ sizeof(LPMMTIME
));
1589 *(LPMMTIME
*)ptr
= mmt32
;
1590 mmt16
->wType
= mmt32
->wType
;
1591 ret
= MMDRV_MAP_OKMEM
;
1593 ret
= MMDRV_MAP_NOMEM
;
1595 *lpParam1
= MapLS(ptr
) + sizeof(LPMMTIME
);
1596 *lpParam2
= sizeof(MMTIME16
);
1599 case WODM_GETVOLUME
:
1600 FIXME("NIY: no conversion yet\n");
1601 ret
= MMDRV_MAP_MSGERROR
;
1605 LPWAVEOPENDESC wod32
= (LPWAVEOPENDESC
)*lpParam1
;
1606 int sz
= sizeof(WAVEFORMATEX
);
1608 LPWAVEOPENDESC16 wod16
;
1610 /* allocated data are mapped as follows:
1611 LPWAVEOPENDESC ptr to orig lParam1
1612 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1613 DWORD dwUser passed to driver
1614 WAVEOPENDESC16 wod16: openDesc passed to driver
1615 WAVEFORMATEX openDesc->lpFormat passed to driver
1616 xxx extra bytes to WAVEFORMATEX
1618 if (wod32
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
1619 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
, wod32
->lpFormat
->wFormatTag
);
1620 sz
+= ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
;
1623 ptr
= HeapAlloc( GetProcessHeap(), 0,
1624 sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
) + sz
);
1627 SEGPTR seg_ptr
= MapLS( ptr
);
1628 *(LPWAVEOPENDESC
*)ptr
= wod32
;
1629 *(LPDWORD
)((char*)ptr
+ sizeof(LPWAVEOPENDESC
)) = *lpdwUser
;
1630 wod16
= (LPWAVEOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
));
1632 wod16
->hWave
= HWAVE_16(wod32
->hWave
);
1633 wod16
->lpFormat
= (LPWAVEFORMATEX
)(seg_ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
));
1634 memcpy(wod16
+ 1, wod32
->lpFormat
, sz
);
1636 wod16
->dwCallback
= wod32
->dwCallback
;
1637 wod16
->dwInstance
= wod32
->dwInstance
;
1638 wod16
->uMappedDeviceID
= wod32
->uMappedDeviceID
;
1639 wod16
->dnDevNode
= wod32
->dnDevNode
;
1641 *lpParam1
= seg_ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
);
1642 *lpdwUser
= seg_ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
);
1644 ret
= MMDRV_MAP_OKMEM
;
1646 ret
= MMDRV_MAP_NOMEM
;
1652 LPWAVEHDR wh32
= (LPWAVEHDR
)*lpParam1
;
1654 LPVOID ptr
= HeapAlloc( GetProcessHeap(), 0,
1655 sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
) + wh32
->dwBufferLength
);
1658 SEGPTR seg_ptr
= MapLS( ptr
);
1659 *(LPWAVEHDR
*)ptr
= wh32
;
1660 wh16
= (LPWAVEHDR
)((LPSTR
)ptr
+ sizeof(LPWAVEHDR
));
1661 wh16
->lpData
= (LPSTR
)seg_ptr
+ sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
);
1662 /* data will be copied on WODM_WRITE */
1663 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1664 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1665 wh16
->dwUser
= wh32
->dwUser
;
1666 wh16
->dwFlags
= wh32
->dwFlags
;
1667 wh16
->dwLoops
= wh32
->dwLoops
;
1668 /* FIXME: nothing on wh32->lpNext */
1669 /* could link the wh32->lpNext at this level for memory house keeping */
1670 wh32
->lpNext
= wh16
; /* for reuse in unprepare and write */
1671 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1672 seg_ptr
+ sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1673 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1674 *lpParam1
= seg_ptr
+ sizeof(LPWAVEHDR
);
1675 *lpParam2
= sizeof(WAVEHDR
);
1677 ret
= MMDRV_MAP_OKMEM
;
1679 ret
= MMDRV_MAP_NOMEM
;
1683 case WODM_UNPREPARE
:
1686 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1687 LPWAVEHDR wh16
= wh32
->lpNext
;
1688 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1689 SEGPTR seg_ptr
= MapLS( ptr
);
1691 assert(*(LPWAVEHDR
*)ptr
== wh32
);
1693 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1694 seg_ptr
+ sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1695 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1697 if (wMsg
== WODM_WRITE
)
1698 memcpy((LPSTR
)wh16
+ sizeof(WAVEHDR
), wh32
->lpData
, wh32
->dwBufferLength
);
1700 *lpParam1
= seg_ptr
+ sizeof(LPWAVEHDR
);
1701 *lpParam2
= sizeof(WAVEHDR
);
1702 /* dwBufferLength can be reduced between prepare & write */
1703 if (wMsg
== WODM_WRITE
&& wh16
->dwBufferLength
< wh32
->dwBufferLength
) {
1704 ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
1705 wh16
->dwBufferLength
, wh32
->dwBufferLength
);
1707 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1708 ret
= MMDRV_MAP_OKMEM
;
1711 case DRVM_MAPPER_STATUS
:
1713 LPDWORD p32
= (LPDWORD
)*lpParam2
;
1714 *lpParam2
= MapLS(p32
);
1715 ret
= MMDRV_MAP_OKMEM
;
1719 FIXME("NIY: no conversion yet\n");
1720 ret
= MMDRV_MAP_MSGERROR
;
1726 /**************************************************************************
1727 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1729 static MMDRV_MapType
MMDRV_WaveOut_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1735 case WODM_BREAKLOOP
:
1737 case WODM_GETNUMDEVS
:
1742 case WODM_SETPLAYBACKRATE
:
1743 case WODM_SETVOLUME
:
1747 case WODM_GETDEVCAPS
:
1749 LPWAVEOUTCAPS16 woc16
= MapSL(*lpParam1
);
1750 LPSTR ptr
= (LPSTR
)woc16
- sizeof(LPWAVEOUTCAPSA
);
1751 LPWAVEOUTCAPSA woc32
= *(LPWAVEOUTCAPSA
*)ptr
;
1753 woc32
->wMid
= woc16
->wMid
;
1754 woc32
->wPid
= woc16
->wPid
;
1755 woc32
->vDriverVersion
= woc16
->vDriverVersion
;
1756 strcpy(woc32
->szPname
, woc16
->szPname
);
1757 woc32
->dwFormats
= woc16
->dwFormats
;
1758 woc32
->wChannels
= woc16
->wChannels
;
1759 woc32
->dwSupport
= woc16
->dwSupport
;
1760 UnMapLS( *lpParam1
);
1761 HeapFree( GetProcessHeap(), 0, ptr
);
1766 FIXME("NIY: no conversion yet\n");
1767 ret
= MMDRV_MAP_MSGERROR
;
1769 case WODM_GETPLAYBACKRATE
:
1770 FIXME("NIY: no conversion yet\n");
1771 ret
= MMDRV_MAP_MSGERROR
;
1775 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
1776 LPSTR ptr
= (LPSTR
)mmt16
- sizeof(LPMMTIME
);
1777 LPMMTIME mmt32
= *(LPMMTIME
*)ptr
;
1779 MMSYSTEM_MMTIME16to32(mmt32
, mmt16
);
1780 UnMapLS( *lpParam1
);
1781 HeapFree( GetProcessHeap(), 0, ptr
);
1787 LPWAVEOPENDESC16 wod16
= MapSL(*lpParam1
);
1788 LPSTR ptr
= (LPSTR
)wod16
- sizeof(LPWAVEOPENDESC
) - 2*sizeof(DWORD
);
1789 LPWAVEOPENDESC wod32
= *(LPWAVEOPENDESC
*)ptr
;
1791 wod32
->uMappedDeviceID
= wod16
->uMappedDeviceID
;
1792 **(DWORD
**)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
));
1793 UnMapLS( *lpParam1
);
1794 HeapFree( GetProcessHeap(), 0, ptr
);
1799 case WODM_UNPREPARE
:
1802 LPWAVEHDR wh16
= MapSL(*lpParam1
);
1803 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1804 LPWAVEHDR wh32
= *(LPWAVEHDR
*)ptr
;
1806 assert(wh32
->lpNext
== wh16
);
1807 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1808 wh32
->dwUser
= wh16
->dwUser
;
1809 wh32
->dwFlags
= wh16
->dwFlags
;
1810 wh32
->dwLoops
= wh16
->dwLoops
;
1812 UnMapLS( *lpParam1
);
1813 if (wMsg
== WODM_UNPREPARE
) {
1814 HeapFree( GetProcessHeap(), 0, ptr
);
1820 case WODM_GETVOLUME
:
1821 FIXME("NIY: no conversion yet\n");
1822 ret
= MMDRV_MAP_MSGERROR
;
1824 case DRVM_MAPPER_STATUS
:
1826 UnMapLS( *lpParam2
);
1831 FIXME("NIY: no conversion yet\n");
1832 ret
= MMDRV_MAP_MSGERROR
;
1838 /**************************************************************************
1839 * MMDRV_WaveOut_Callback [internal]
1841 static void CALLBACK
MMDRV_WaveOut_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
1843 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
1848 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1851 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
1852 /* initial map is: 32 => 16 */
1853 LPWAVEHDR wh16
= MapSL(dwParam1
);
1854 LPWAVEHDR wh32
= *(LPWAVEHDR
*)((LPSTR
)wh16
- sizeof(LPWAVEHDR
));
1856 dwParam1
= (DWORD
)wh32
;
1857 wh32
->dwFlags
= wh16
->dwFlags
;
1858 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
1859 /* initial map is: 16 => 32 */
1860 LPWAVEHDR wh32
= (LPWAVEHDR
)(dwParam1
);
1861 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1862 LPWAVEHDR wh16
= MapSL(segwh16
);
1864 dwParam1
= (DWORD
)segwh16
;
1865 wh16
->dwFlags
= wh32
->dwFlags
;
1867 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1870 ERR("Unknown msg %u\n", uMsg
);
1873 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
1876 #define A(_x,_y) {#_y, _x, \
1877 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1878 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1879 MMDRV_##_y##_Callback, 0, NULL, -1}
1881 /* Note: the indices of this array must match the definitions
1882 * of the MMDRV_???? manifest constants
1884 static WINE_LLTYPE llTypes
[MMDRV_MAX
] = {
1894 /**************************************************************************
1895 * MMDRV_GetNum [internal]
1897 UINT
MMDRV_GetNum(UINT type
)
1899 assert(type
< MMDRV_MAX
);
1900 return llTypes
[type
].wMaxId
;
1903 /**************************************************************************
1904 * WINE_Message [internal]
1906 DWORD
MMDRV_Message(LPWINE_MLD mld
, WORD wMsg
, DWORD dwParam1
,
1907 DWORD dwParam2
, BOOL bFrom32
)
1909 LPWINE_MM_DRIVER lpDrv
;
1911 WINE_MM_DRIVER_PART
* part
;
1912 WINE_LLTYPE
* llType
= &llTypes
[mld
->type
];
1916 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1917 llTypes
[mld
->type
].typestr
, mld
->uDeviceID
, wMsg
,
1918 mld
->dwDriverInstance
, dwParam1
, dwParam2
, bFrom32
?'Y':'N');
1920 if (mld
->uDeviceID
== (UINT16
)-1) {
1921 if (!llType
->bSupportMapper
) {
1922 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1923 llTypes
[mld
->type
].typestr
);
1924 return MMSYSERR_BADDEVICEID
;
1928 if (mld
->uDeviceID
>= llType
->wMaxId
) {
1929 WARN("uDev(%u) requested >= max (%d)\n", mld
->uDeviceID
, llType
->wMaxId
);
1930 return MMSYSERR_BADDEVICEID
;
1932 devID
= mld
->uDeviceID
;
1935 lpDrv
= &MMDrvs
[mld
->mmdIndex
];
1936 part
= &lpDrv
->parts
[mld
->type
];
1939 /* some sanity checks */
1940 if (!(part
->nIDMin
<= devID
))
1941 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part
->nIDMin
, devID
);
1942 if (!(devID
< part
->nIDMax
))
1943 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID
, part
->nIDMax
);
1947 assert(part
->u
.fnMessage32
);
1950 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1951 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1952 ret
= part
->u
.fnMessage32(mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1953 TRACE("=> %lu\n", ret
);
1955 map
= llType
->Map16To32A(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1957 case MMDRV_MAP_NOMEM
:
1958 ret
= MMSYSERR_NOMEM
;
1960 case MMDRV_MAP_MSGERROR
:
1961 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg
);
1962 ret
= MMSYSERR_ERROR
;
1965 case MMDRV_MAP_OKMEM
:
1966 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1967 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1968 ret
= part
->u
.fnMessage32(mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
,
1969 dwParam1
, dwParam2
);
1970 TRACE("=> %lu\n", ret
);
1971 if (map
== MMDRV_MAP_OKMEM
)
1972 llType
->UnMap16To32A(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1975 case MMDRV_MAP_PASS
:
1976 FIXME("NIY: pass used ?\n");
1977 ret
= MMSYSERR_NOTSUPPORTED
;
1982 assert(part
->u
.fnMessage16
);
1985 map
= llType
->Map32ATo16(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1987 case MMDRV_MAP_NOMEM
:
1988 ret
= MMSYSERR_NOMEM
;
1990 case MMDRV_MAP_MSGERROR
:
1991 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg
);
1992 ret
= MMSYSERR_ERROR
;
1995 case MMDRV_MAP_OKMEM
:
1996 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1997 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1998 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
, mld
->uDeviceID
,
1999 wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2000 TRACE("=> %lu\n", ret
);
2001 if (map
== MMDRV_MAP_OKMEM
)
2002 llType
->UnMap32ATo16(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
2005 case MMDRV_MAP_PASS
:
2006 FIXME("NIY: pass used ?\n");
2007 ret
= MMSYSERR_NOTSUPPORTED
;
2011 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2012 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2013 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
, mld
->uDeviceID
,
2014 wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2015 TRACE("=> %lu\n", ret
);
2021 /**************************************************************************
2022 * MMDRV_Alloc [internal]
2024 LPWINE_MLD
MMDRV_Alloc(UINT size
, UINT type
, LPHANDLE hndl
, DWORD
* dwFlags
,
2025 DWORD
* dwCallback
, DWORD
* dwInstance
, BOOL bFrom32
)
2029 mld
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2030 if (!mld
) return NULL
;
2032 /* find an empty slot in MM_MLDrvs table */
2033 for (*hndl
= 0; *hndl
< MAX_MM_MLDRVS
; (*hndl
)++) {
2034 if (!MM_MLDrvs
[*hndl
]) break;
2036 if (*hndl
== MAX_MM_MLDRVS
) {
2037 /* the MM_MLDrvs table could be made growable in the future if needed */
2038 ERR("Too many open drivers\n");
2041 MM_MLDrvs
[*hndl
] = mld
;
2045 if ((UINT
)*hndl
< MMDRV_GetNum(type
) || HIWORD(*hndl
) != 0) {
2046 /* FIXME: those conditions must be fulfilled so that:
2047 * - we can distinguish between device IDs and handles
2048 * - we can use handles as 16 or 32 bit entities
2050 ERR("Shouldn't happen. Bad allocation scheme\n");
2053 mld
->bFrom32
= bFrom32
;
2054 mld
->dwFlags
= HIWORD(*dwFlags
);
2055 mld
->dwCallback
= *dwCallback
;
2056 mld
->dwClientInstance
= *dwInstance
;
2058 *dwFlags
= LOWORD(*dwFlags
) | CALLBACK_FUNCTION
;
2059 *dwCallback
= (DWORD
)llTypes
[type
].Callback
;
2060 *dwInstance
= (DWORD
)mld
; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2065 /**************************************************************************
2066 * MMDRV_Free [internal]
2068 void MMDRV_Free(HANDLE hndl
, LPWINE_MLD mld
)
2070 if (hndl
& 0x8000) {
2071 unsigned idx
= hndl
& ~0x8000;
2072 if (idx
< sizeof(MM_MLDrvs
) / sizeof(MM_MLDrvs
[0])) {
2073 MM_MLDrvs
[idx
] = NULL
;
2074 HeapFree(GetProcessHeap(), 0, mld
);
2078 ERR("Bad Handle %08x at %p (not freed)\n", hndl
, mld
);
2081 /**************************************************************************
2082 * MMDRV_Open [internal]
2084 DWORD
MMDRV_Open(LPWINE_MLD mld
, UINT wMsg
, DWORD dwParam1
, DWORD dwFlags
)
2086 DWORD dwRet
= MMSYSERR_BADDEVICEID
;
2088 WINE_LLTYPE
* llType
= &llTypes
[mld
->type
];
2090 mld
->dwDriverInstance
= (DWORD
)&dwInstance
;
2092 if (mld
->uDeviceID
== (UINT
)-1 || mld
->uDeviceID
== (UINT16
)-1) {
2093 TRACE("MAPPER mode requested !\n");
2094 /* check if mapper is supported by type */
2095 if (llType
->bSupportMapper
) {
2096 if (llType
->nMapper
== -1) {
2097 /* no driver for mapper has been loaded, try a dumb implementation */
2098 TRACE("No mapper loaded, doing it by hand\n");
2099 for (mld
->uDeviceID
= 0; mld
->uDeviceID
< llType
->wMaxId
; mld
->uDeviceID
++) {
2100 if ((dwRet
= MMDRV_Open(mld
, wMsg
, dwParam1
, dwFlags
)) == MMSYSERR_NOERROR
) {
2101 /* to share this function epilog */
2102 dwInstance
= mld
->dwDriverInstance
;
2107 mld
->uDeviceID
= (UINT16
)-1;
2108 mld
->mmdIndex
= llType
->lpMlds
[-1].mmdIndex
;
2109 TRACE("Setting mmdIndex to %u\n", mld
->mmdIndex
);
2110 dwRet
= MMDRV_Message(mld
, wMsg
, dwParam1
, dwFlags
, TRUE
);
2114 if (mld
->uDeviceID
< llType
->wMaxId
) {
2115 mld
->mmdIndex
= llType
->lpMlds
[mld
->uDeviceID
].mmdIndex
;
2116 TRACE("Setting mmdIndex to %u\n", mld
->mmdIndex
);
2117 dwRet
= MMDRV_Message(mld
, wMsg
, dwParam1
, dwFlags
, TRUE
);
2120 if (dwRet
== MMSYSERR_NOERROR
)
2121 mld
->dwDriverInstance
= dwInstance
;
2125 /**************************************************************************
2126 * MMDRV_Close [internal]
2128 DWORD
MMDRV_Close(LPWINE_MLD mld
, UINT wMsg
)
2130 return MMDRV_Message(mld
, wMsg
, 0L, 0L, TRUE
);
2133 /**************************************************************************
2134 * MMDRV_GetByID [internal]
2136 LPWINE_MLD
MMDRV_GetByID(UINT uDevID
, UINT type
)
2138 if (uDevID
< llTypes
[type
].wMaxId
)
2139 return &llTypes
[type
].lpMlds
[uDevID
];
2140 if ((uDevID
== (UINT16
)-1 || uDevID
== (UINT
)-1) && llTypes
[type
].nMapper
!= -1)
2141 return &llTypes
[type
].lpMlds
[-1];
2145 /**************************************************************************
2146 * MMDRV_Get [internal]
2148 LPWINE_MLD
MMDRV_Get(HANDLE hndl
, UINT type
, BOOL bCanBeID
)
2150 LPWINE_MLD mld
= NULL
;
2152 assert(type
< MMDRV_MAX
);
2154 if ((UINT
)hndl
>= llTypes
[type
].wMaxId
&&
2155 hndl
!= (UINT16
)-1 && hndl
!= (UINT
)-1) {
2156 if (hndl
& 0x8000) {
2158 if (hndl
< sizeof(MM_MLDrvs
) / sizeof(MM_MLDrvs
[0])) {
2159 mld
= MM_MLDrvs
[hndl
];
2160 if (!mld
|| !HeapValidate(GetProcessHeap(), 0, mld
) || mld
->type
!= type
)
2166 if (mld
== NULL
&& bCanBeID
) {
2167 mld
= MMDRV_GetByID((UINT
)hndl
, type
);
2172 /**************************************************************************
2173 * MMDRV_GetRelated [internal]
2175 LPWINE_MLD
MMDRV_GetRelated(HANDLE hndl
, UINT srcType
,
2176 BOOL bSrcCanBeID
, UINT dstType
)
2180 if ((mld
= MMDRV_Get(hndl
, srcType
, bSrcCanBeID
)) != NULL
) {
2181 WINE_MM_DRIVER_PART
* part
= &MMDrvs
[mld
->mmdIndex
].parts
[dstType
];
2182 if (part
->nIDMin
< part
->nIDMax
)
2183 return MMDRV_GetByID(part
->nIDMin
, dstType
);
2188 /**************************************************************************
2189 * MMDRV_PhysicalFeatures [internal]
2191 UINT
MMDRV_PhysicalFeatures(LPWINE_MLD mld
, UINT uMsg
, DWORD dwParam1
,
2194 WINE_MM_DRIVER
* lpDrv
= &MMDrvs
[mld
->mmdIndex
];
2196 TRACE("(%p, %04x, %08lx, %08lx)\n", mld
, uMsg
, dwParam1
, dwParam2
);
2198 /* all those function calls are undocumented */
2200 case DRV_QUERYDRVENTRY
:
2201 lstrcpynA((LPSTR
)dwParam1
, lpDrv
->drvname
, LOWORD(dwParam2
));
2203 case DRV_QUERYDEVNODE
:
2204 *(LPDWORD
)dwParam1
= 0L; /* should be DevNode */
2207 WARN("NIY QueryName\n");
2209 case DRV_QUERYDRIVERIDS
:
2210 WARN("NIY call VxD\n");
2211 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2212 * dwParam1 is buffer and dwParam2 is sizeof buffer
2213 * I don't know where the result is stored though
2216 case DRV_QUERYMAPPABLE
:
2217 return (lpDrv
->bIsMapper
) ? 2 : 0;
2219 case DRV_QUERYDSOUNDIFACE
: /* Wine-specific: Retrieve DirectSound interface */
2220 return MMDRV_Message(mld
, uMsg
, dwParam1
, dwParam2
, TRUE
);
2223 WARN("Unknown call %04x\n", uMsg
);
2224 return MMSYSERR_INVALPARAM
;
2229 /**************************************************************************
2230 * MMDRV_InitPerType [internal]
2232 static BOOL
MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv
, UINT type
, UINT wMsg
)
2234 WINE_MM_DRIVER_PART
* part
= &lpDrv
->parts
[type
];
2239 part
->nIDMin
= part
->nIDMax
= 0;
2241 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2242 /* the DRVM_ENABLE is only required when the PnP node is non zero */
2244 if (lpDrv
->bIs32
&& part
->u
.fnMessage32
) {
2245 ret
= part
->u
.fnMessage32(0, DRVM_INIT
, 0L, 0L, 0L);
2246 TRACE("DRVM_INIT => %08lx\n", ret
);
2248 ret
= part
->u
.fnMessage32(0, DRVM_ENABLE
, 0L, 0L, 0L);
2249 TRACE("DRVM_ENABLE => %08lx\n", ret
);
2251 count
= part
->u
.fnMessage32(0, wMsg
, 0L, 0L, 0L);
2252 } else if (!lpDrv
->bIs32
&& part
->u
.fnMessage16
) {
2253 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2254 0, DRVM_INIT
, 0L, 0L, 0L);
2255 TRACE("DRVM_INIT => %08lx\n", ret
);
2257 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2258 0, DRVM_ENABLE
, 0L, 0L, 0L);
2259 TRACE("DRVM_ENABLE => %08lx\n", ret
);
2261 count
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2262 0, wMsg
, 0L, 0L, 0L);
2267 TRACE("Got %u dev for (%s:%s)\n", count
, lpDrv
->drvname
, llTypes
[type
].typestr
);
2269 /* got some drivers */
2270 if (lpDrv
->bIsMapper
) {
2271 /* it seems native mappers return 0 devices :-( */
2272 if (llTypes
[type
].nMapper
!= -1)
2273 ERR("Two mappers for type %s (%d, %s)\n",
2274 llTypes
[type
].typestr
, llTypes
[type
].nMapper
, lpDrv
->drvname
);
2276 ERR("Strange: mapper with %d > 1 devices\n", count
);
2277 llTypes
[type
].nMapper
= MMDrvsHi
;
2281 part
->nIDMin
= llTypes
[type
].wMaxId
;
2282 llTypes
[type
].wMaxId
+= count
;
2283 part
->nIDMax
= llTypes
[type
].wMaxId
;
2285 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2286 part
->nIDMin
, part
->nIDMax
, llTypes
[type
].wMaxId
,
2287 lpDrv
->drvname
, llTypes
[type
].typestr
);
2288 /* realloc translation table */
2289 llTypes
[type
].lpMlds
= (LPWINE_MLD
)
2290 HeapReAlloc(GetProcessHeap(), 0, (llTypes
[type
].lpMlds
) ? llTypes
[type
].lpMlds
- 1 : NULL
,
2291 sizeof(WINE_MLD
) * (llTypes
[type
].wMaxId
+ 1)) + 1;
2292 /* re-build the translation table */
2293 if (llTypes
[type
].nMapper
!= -1) {
2294 TRACE("%s:Trans[%d] -> %s\n", llTypes
[type
].typestr
, -1, MMDrvs
[llTypes
[type
].nMapper
].drvname
);
2295 llTypes
[type
].lpMlds
[-1].uDeviceID
= (UINT16
)-1;
2296 llTypes
[type
].lpMlds
[-1].type
= type
;
2297 llTypes
[type
].lpMlds
[-1].mmdIndex
= llTypes
[type
].nMapper
;
2298 llTypes
[type
].lpMlds
[-1].dwDriverInstance
= 0;
2300 for (i
= k
= 0; i
<= MMDrvsHi
; i
++) {
2301 while (MMDrvs
[i
].parts
[type
].nIDMin
<= k
&& k
< MMDrvs
[i
].parts
[type
].nIDMax
) {
2302 TRACE("%s:Trans[%d] -> %s\n", llTypes
[type
].typestr
, k
, MMDrvs
[i
].drvname
);
2303 llTypes
[type
].lpMlds
[k
].uDeviceID
= k
;
2304 llTypes
[type
].lpMlds
[k
].type
= type
;
2305 llTypes
[type
].lpMlds
[k
].mmdIndex
= i
;
2306 llTypes
[type
].lpMlds
[k
].dwDriverInstance
= 0;
2313 /**************************************************************************
2314 * MMDRV_Install [internal]
2316 static BOOL
MMDRV_Install(LPCSTR drvRegName
, LPCSTR drvFileName
, BOOL bIsMapper
)
2320 LPWINE_MM_DRIVER lpDrv
= &MMDrvs
[MMDrvsHi
];
2323 TRACE("('%s', '%s', mapper=%c);\n", drvRegName
, drvFileName
, bIsMapper
? 'Y' : 'N');
2325 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2326 * if not just increase size of MMDrvs */
2327 assert(MMDrvsHi
<= sizeof(MMDrvs
)/sizeof(MMDrvs
[0]));
2329 for (i
= 0; i
< MMDrvsHi
; i
++) {
2330 if (!strcmp(drvRegName
, MMDrvs
[i
].drvname
)) return FALSE
;
2333 memset(lpDrv
, 0, sizeof(*lpDrv
));
2335 if (!(lpDrv
->hDriver
= OpenDriverA(drvFileName
, 0, 0))) {
2336 WARN("Couldn't open driver '%s'\n", drvFileName
);
2340 d
= DRIVER_FindFromHDrvr(lpDrv
->hDriver
);
2341 lpDrv
->bIs32
= (d
->dwFlags
& WINE_GDF_16BIT
) ? FALSE
: TRUE
;
2343 /* Then look for xxxMessage functions */
2344 #define AA(_h,_w,_x,_y,_z) \
2345 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
2347 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2348 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2351 WINEMM_msgFunc32 func
;
2353 if (d
->d
.d32
.hModule
) {
2354 #define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
2355 A(MMDRV_AUX
, auxMessage
);
2356 A(MMDRV_MIXER
, mixMessage
);
2357 A(MMDRV_MIDIIN
, midMessage
);
2358 A(MMDRV_MIDIOUT
, modMessage
);
2359 A(MMDRV_WAVEIN
, widMessage
);
2360 A(MMDRV_WAVEOUT
, wodMessage
);
2364 WINEMM_msgFunc16 func
;
2367 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2368 * The beginning of the module description indicates the driver supports
2369 * waveform, auxiliary, and mixer devices. Use one of the following
2370 * device-type names, followed by a colon (:) to indicate the type of
2371 * device your driver supports. If the driver supports more than one
2372 * type of device, separate each device-type name with a comma (,).
2374 * wave for waveform audio devices
2375 * wavemapper for wave mappers
2376 * midi for MIDI audio devices
2377 * midimapper for midi mappers
2378 * aux for auxiliary audio devices
2379 * mixer for mixer devices
2382 if (d
->d
.d16
.hDriver16
) {
2383 HMODULE16 hMod16
= GetDriverModuleHandle16(d
->d
.d16
.hDriver16
);
2385 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
2386 A(MMDRV_AUX
, auxMessage
);
2387 A(MMDRV_MIXER
, mixMessage
);
2388 A(MMDRV_MIDIIN
, midMessage
);
2389 A(MMDRV_MIDIOUT
, modMessage
);
2390 A(MMDRV_WAVEIN
, widMessage
);
2391 A(MMDRV_WAVEOUT
, wodMessage
);
2397 if (TRACE_ON(mmsys
)) {
2398 if ((lpDrv
->bIs32
) ? MMDRV_GetDescription32(drvFileName
, buffer
, sizeof(buffer
)) :
2399 MMDRV_GetDescription16(drvFileName
, buffer
, sizeof(buffer
)))
2400 TRACE("%s => %s\n", drvFileName
, buffer
);
2402 TRACE("%s => No description\n", drvFileName
);
2406 CloseDriver(lpDrv
->hDriver
, 0, 0);
2407 WARN("No message functions found\n");
2411 /* FIXME: being a mapper or not should be known by another way */
2412 /* it's known for NE drvs (the description is of the form '*mapper: *'
2413 * I don't have any clue for PE drvs
2415 lpDrv
->bIsMapper
= bIsMapper
;
2416 lpDrv
->drvname
= strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(drvRegName
) + 1), drvRegName
);
2418 /* Finish init and get the count of the devices */
2419 MMDRV_InitPerType(lpDrv
, MMDRV_AUX
, AUXDM_GETNUMDEVS
);
2420 MMDRV_InitPerType(lpDrv
, MMDRV_MIXER
, MXDM_GETNUMDEVS
);
2421 MMDRV_InitPerType(lpDrv
, MMDRV_MIDIIN
, MIDM_GETNUMDEVS
);
2422 MMDRV_InitPerType(lpDrv
, MMDRV_MIDIOUT
, MODM_GETNUMDEVS
);
2423 MMDRV_InitPerType(lpDrv
, MMDRV_WAVEIN
, WIDM_GETNUMDEVS
);
2424 MMDRV_InitPerType(lpDrv
, MMDRV_WAVEOUT
, WODM_GETNUMDEVS
);
2425 /* FIXME: if all those func calls return FALSE,
2426 * then the driver must be unloaded
2434 /**************************************************************************
2435 * MMDRV_InitFromRegistry [internal]
2437 static BOOL
MMDRV_InitFromRegistry(void)
2446 if (RegCreateKeyA(HKEY_LOCAL_MACHINE
, "Software\\Wine\\Wine\\Config\\WinMM", &hKey
)) {
2447 TRACE("Cannot open WinMM config key\n");
2451 size
= sizeof(buffer
);
2452 if (!RegQueryValueExA(hKey
, "Drivers", 0, &type
, (LPVOID
)buffer
, &size
)) {
2455 p2
= strchr(p1
, ';');
2456 if (p2
) *p2
++ = '\0';
2457 ret
|= MMDRV_Install(p1
, p1
, FALSE
);
2462 /* finish with mappers */
2463 size
= sizeof(buffer
);
2464 if (!RegQueryValueExA(hKey
, "WaveMapper", 0, &type
, (LPVOID
)buffer
, &size
))
2465 ret
|= MMDRV_Install("wavemapper", buffer
, TRUE
);
2466 size
= sizeof(buffer
);
2467 if (!RegQueryValueExA(hKey
, "MidiMapper", 0, &type
, (LPVOID
)buffer
, &size
))
2468 ret
|= MMDRV_Install("midimapper", buffer
, TRUE
);
2475 /**************************************************************************
2476 * MMDRV_InitHardcoded [internal]
2478 static BOOL
MMDRV_InitHardcoded(void)
2480 ERR("You didn't setup properly the config file for the Wine multimedia modules.\n"
2481 "Will use the hard-coded setup, but this will disappear soon.\n"
2482 "Please add a WinMM section to your Wine config file.\n");
2484 /* first load hardware drivers */
2485 MMDRV_Install("wineoss.drv", "wineoss.drv", FALSE
);
2487 /* finish with mappers */
2488 MMDRV_Install("wavemapper", "msacm.drv", TRUE
);
2489 MMDRV_Install("midimapper", "midimap.drv", TRUE
);
2494 /**************************************************************************
2495 * MMDRV_Init [internal]
2497 BOOL
MMDRV_Init(void)
2499 /* FIXME: MMDRV_InitFromRegistry shall be MMDRV_Init in a near future */
2500 return MMDRV_InitFromRegistry() || MMDRV_InitHardcoded();