1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * MMSYTEM low level drivers handling functions
6 * Copyright 1999 Eric Pouech
11 #include "wine/winbase16.h"
15 #include "debugtools.h"
17 DEFAULT_DEBUG_CHANNEL(mmsys
);
19 typedef DWORD
CALLBACK (*WINEMM_msgFunc16
)(UINT16
, WORD
, DWORD
, DWORD
, DWORD
);
20 typedef DWORD
CALLBACK (*WINEMM_msgFunc32
)(UINT
, UINT
, DWORD
, DWORD
, DWORD
);
22 /* for each loaded driver and each known type of driver, this structure contains
23 * the information needed to access it
25 typedef struct tagWINE_MM_DRIVER_PART
{
26 int nIDMin
; /* lower bound of global indexes for this type */
27 int nIDMax
; /* hhigher bound of global indexes for this type */
29 WINEMM_msgFunc32 fnMessage32
; /* pointer to fonction */
30 WINEMM_msgFunc16 fnMessage16
;
32 } WINE_MM_DRIVER_PART
;
34 /* each low-level .drv will be associated with an instance of this structure */
35 typedef struct tagWINE_MM_DRIVER
{
37 LPSTR name
; /* name of the driver */
38 BOOL bIs32
: 1, /* TRUE if 32 bit driver, FALSE for 16 */
39 bIsMapper
: 1; /* TRUE if mapper */
40 WINE_MM_DRIVER_PART parts
[MMDRV_MAX
];/* Information for all known types */
41 } WINE_MM_DRIVER
, *LPWINE_MM_DRIVER
;
44 MMDRV_MAP_NOMEM
, /* ko, memory problem */
45 MMDRV_MAP_MSGERROR
, /* ko, unknown message */
46 MMDRV_MAP_OK
, /* ok, no memory allocated. to be sent to the proc. */
47 MMDRV_MAP_OKMEM
, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
48 MMDRV_MAP_PASS
/* not handled (no memory allocated) to be sent to the driver */
51 typedef MMDRV_MapType (*MMDRV_MAPFUNC
)(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
);
53 /* each known type of driver has an instance of this structure */
54 typedef struct tagWINE_LLTYPE
{
55 /* those attributes depend on the specification of the type */
56 LPSTR name
; /* name (for debugging) */
57 BOOL bSupportMapper
; /* if type is allowed to support mapper */
58 MMDRV_MAPFUNC Map16To32A
; /* those are function pointers to handle */
59 MMDRV_MAPFUNC UnMap16To32A
; /* the parameter conversion (16 vs 32 bit) */
60 MMDRV_MAPFUNC Map32ATo16
; /* when hi-func (in mmsystem or winmm) and */
61 MMDRV_MAPFUNC UnMap32ATo16
; /* low-func (in .drv) do not match */
62 LPDRVCALLBACK Callback
; /* handles callback for a specified type */
63 /* those attributes reflect the loaded/current situation for the type */
64 UINT wMaxId
; /* number of loaded devices (sum across all loaded drivers */
65 LPWINE_MLD lpMlds
; /* "static" mlds to access the part though device IDs */
66 int nMapper
; /* index to mapper */
69 static WINE_MM_DRIVER MMDrvs
[3];
70 static LPWINE_MLD MM_MLDrvs
[40];
71 #define MAX_MM_MLDRVS (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
73 /* ### start build ### */
74 extern WORD CALLBACK
MMDRV_CallTo16_word_wwlll(FARPROC16
,WORD
,WORD
,LONG
,LONG
,LONG
);
75 /* ### stop build ### */
77 /**************************************************************************
78 * MMDRV_GetDescription16 [internal]
80 static BOOL
MMDRV_GetDescription16(const char* fname
, char* buf
, int buflen
)
88 if ((hFile
= OpenFile(fname
, &ofs
, OF_READ
| OF_SHARE_DENY_WRITE
)) == HFILE_ERROR
) {
89 ERR("Can't open file %s (builtin driver ?)\n", fname
);
93 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
95 if (_lread(hFile
, &w
, 2) != 2) E(("Can't read sig\n"));
96 if (w
!= ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w
));
97 if (_llseek(hFile
, 0x3C, SEEK_SET
) < 0) E(("Can't seek to ext header offset\n"));
98 if (_lread(hFile
, &dw
, 4) != 4) E(("Can't read ext header offset\n"));
99 if (_llseek(hFile
, dw
+ 0x2C, SEEK_SET
) < 0) E(("Can't seek to ext header.nr table %lu\n", dw
+0x2C));
100 if (_lread(hFile
, &dw
, 4) != 4) E(("Can't read nr table offset\n"));
101 if (_llseek(hFile
, dw
, SEEK_SET
) < 0) E(("Can't seek to nr table %lu\n", dw
));
102 if (_lread(hFile
, buf
, 1) != 1) E(("Can't read descr length\n"));
103 buflen
= min((BYTE
)buf
[0], buflen
- 1);
104 if (_lread(hFile
, buf
, buflen
) != buflen
) E(("Can't read descr (%d)\n", buflen
));
107 TRACE("Got '%s' [%d]\n", buf
, buflen
);
113 /**************************************************************************
114 * MMDRV_GetDescription32 [internal]
116 static BOOL
MMDRV_GetDescription32(const char* fname
, char* buf
, int buflen
)
125 FARPROC pGetFileVersionInfoSizeA
;
126 FARPROC pGetFileVersionInfoA
;
127 FARPROC pVerQueryValueA
;
130 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
132 if (OpenFile(fname
, &ofs
, OF_EXIST
)==HFILE_ERROR
) E(("Can't find file %s\n", fname
));
134 if (!(hmodule
= LoadLibraryA( "version.dll" ))) goto theEnd
;
135 if (!(pGetFileVersionInfoSizeA
= GetProcAddress( hmodule
, "GetFileVersionInfoSizeA" )))
137 if (!(pGetFileVersionInfoA
= GetProcAddress( hmodule
, "GetFileVersionInfoA" )))
139 if (!(pVerQueryValueA
= GetProcAddress( hmodule
, "pVerQueryValueA" )))
142 if (!(dw
= pGetFileVersionInfoSizeA(ofs
.szPathName
, &h
))) E(("Can't get FVIS\n"));
143 if (!(ptr
= HeapAlloc(GetProcessHeap(), 0, dw
))) E(("OOM\n"));
144 if (!pGetFileVersionInfoA(ofs
.szPathName
, h
, dw
, ptr
)) E(("Can't get FVI\n"));
146 #define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
147 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
163 if (!pVerQueryValueA(ptr
, "\\StringFileInfo\\040904B0\\ProductName", &val
, &u
)) E(("Can't get product name\n"));
164 lstrcpynA(buf
, val
, buflen
);
169 HeapFree(GetProcessHeap(), 0, ptr
);
170 if (hmodule
) FreeLibrary( hmodule
);
174 /**************************************************************************
175 * MMDRV_Callback [internal]
177 static void MMDRV_Callback(LPWINE_MLD mld
, HDRVR hDev
, UINT uMsg
, DWORD dwParam1
, DWORD dwParam2
)
179 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
180 mld
->dwCallback
, hDev
, uMsg
, mld
->dwClientInstance
, dwParam1
, dwParam2
);
182 if (!mld
->bFrom32
&& (mld
->dwFlags
& DCB_TYPEMASK
) == DCB_FUNCTION
) {
183 /* 16 bit func, call it */
184 TRACE("Function (16 bit) !\n");
185 MMDRV_CallTo16_word_wwlll((FARPROC16
)mld
->dwCallback
, hDev
, uMsg
,
186 mld
->dwClientInstance
, dwParam1
, dwParam2
);
188 DriverCallback(mld
->dwCallback
, mld
->dwFlags
, hDev
, uMsg
,
189 mld
->dwClientInstance
, dwParam1
, dwParam2
);
193 /* =================================
194 * A U X M A P P E R S
195 * ================================= */
197 /**************************************************************************
198 * MMDRV_Aux_Map16To32A [internal]
200 static MMDRV_MapType
MMDRV_Aux_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
202 return MMDRV_MAP_MSGERROR
;
205 /**************************************************************************
206 * MMDRV_Aux_UnMap16To32A [internal]
208 static MMDRV_MapType
MMDRV_Aux_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
210 return MMDRV_MAP_MSGERROR
;
213 /**************************************************************************
214 * MMDRV_Aux_Map32ATo16 [internal]
216 static MMDRV_MapType
MMDRV_Aux_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
218 return MMDRV_MAP_MSGERROR
;
221 /**************************************************************************
222 * MMDRV_Aux_UnMap32ATo16 [internal]
224 static MMDRV_MapType
MMDRV_Aux_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
227 case AUXDM_GETDEVCAPS
:
228 lpCaps
->wMid
= ac16
.wMid
;
229 lpCaps
->wPid
= ac16
.wPid
;
230 lpCaps
->vDriverVersion
= ac16
.vDriverVersion
;
231 strcpy(lpCaps
->szPname
, ac16
.szPname
);
232 lpCaps
->wTechnology
= ac16
.wTechnology
;
233 lpCaps
->dwSupport
= ac16
.dwSupport
;
235 return MMDRV_MAP_MSGERROR
;
238 /**************************************************************************
239 * MMDRV_Aux_Callback [internal]
241 static void CALLBACK
MMDRV_Aux_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
243 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
246 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
249 /* =================================
250 * M I X E R M A P P E R S
251 * ================================= */
253 /**************************************************************************
254 * xMMDRV_Mixer_Map16To32A [internal]
256 static MMDRV_MapType
MMDRV_Mixer_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
258 return MMDRV_MAP_MSGERROR
;
261 /**************************************************************************
262 * MMDRV_Mixer_UnMap16To32A [internal]
264 static MMDRV_MapType
MMDRV_Mixer_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
268 UINT ret
= mixerGetDevCapsA(devid
, &micA
, sizeof(micA
));
270 if (ret
== MMSYSERR_NOERROR
) {
271 mixcaps
->wMid
= micA
.wMid
;
272 mixcaps
->wPid
= micA
.wPid
;
273 mixcaps
->vDriverVersion
= micA
.vDriverVersion
;
274 strcpy(mixcaps
->szPname
, micA
.szPname
);
275 mixcaps
->fdwSupport
= micA
.fdwSupport
;
276 mixcaps
->cDestinations
= micA
.cDestinations
;
280 return MMDRV_MAP_MSGERROR
;
283 /**************************************************************************
284 * MMDRV_Mixer_Map32ATo16 [internal]
286 static MMDRV_MapType
MMDRV_Mixer_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
288 return MMDRV_MAP_MSGERROR
;
291 /**************************************************************************
292 * MMDRV_Mixer_UnMap32ATo16 [internal]
294 static MMDRV_MapType
MMDRV_Mixer_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
296 return MMDRV_MAP_MSGERROR
;
299 /**************************************************************************
300 * MMDRV_Mixer_Callback [internal]
302 static void CALLBACK
MMDRV_Mixer_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
304 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
307 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
310 /* =================================
311 * M I D I I N M A P P E R S
312 * ================================= */
314 /**************************************************************************
315 * MMDRV_MidiIn_Map16To32A [internal]
317 static MMDRV_MapType
MMDRV_MidiIn_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
319 return MMDRV_MAP_MSGERROR
;
322 /**************************************************************************
323 * MMDRV_MidiIn_UnMap16To32A [internal]
325 static MMDRV_MapType
MMDRV_MidiIn_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
327 return MMDRV_MAP_MSGERROR
;
330 /**************************************************************************
331 * MMDRV_MidiIn_Map32ATo16 [internal]
333 static MMDRV_MapType
MMDRV_MidiIn_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
335 return MMDRV_MAP_MSGERROR
;
338 /**************************************************************************
339 * MMDRV_MidiIn_UnMap32ATo16 [internal]
341 static MMDRV_MapType
MMDRV_MidiIn_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
343 return MMDRV_MAP_MSGERROR
;
346 /**************************************************************************
347 * MMDRV_MidiIn_Callback [internal]
349 static void CALLBACK
MMDRV_MidiIn_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
351 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
356 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
361 /* dwParam1 & dwParam2 are are data, nothing to do */
365 /* dwParam1 points to a MidiHdr, work to be done !!! */
366 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
367 /* initial map is: 32 => 16 */
368 LPMIDIHDR mh16
= MapSL(dwParam1
);
369 LPMIDIHDR mh32
= *(LPMIDIHDR
*)((LPSTR
)mh16
- sizeof(LPMIDIHDR
));
371 dwParam1
= (DWORD
)mh32
;
372 mh32
->dwFlags
= mh16
->dwFlags
;
373 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
374 if (mh32
->reserved
>= sizeof(MIDIHDR
))
375 mh32
->dwOffset
= mh16
->dwOffset
;
376 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
377 /* initial map is: 16 => 32 */
378 LPMIDIHDR mh32
= (LPMIDIHDR
)(dwParam1
);
379 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
380 LPMIDIHDR mh16
= MapSL(segmh16
);
382 dwParam1
= (DWORD
)segmh16
;
383 mh16
->dwFlags
= mh32
->dwFlags
;
384 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
385 if (mh16
->reserved
>= sizeof(MIDIHDR
))
386 mh16
->dwOffset
= mh32
->dwOffset
;
388 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
390 /* case MOM_POSITIONCB: */
392 ERR("Unknown msg %u\n", uMsg
);
395 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
398 /* =================================
399 * M I D I O U T M A P P E R S
400 * ================================= */
402 /**************************************************************************
403 * MMDRV_MidiOut_Map16To32A [internal]
405 static MMDRV_MapType
MMDRV_MidiOut_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
407 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
410 case MODM_GETNUMDEVS
:
420 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
423 case MODM_GETDEVCAPS
:
425 LPMIDIOUTCAPSA moc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16
) + sizeof(MIDIOUTCAPSA
));
426 LPMIDIOUTCAPS16 moc16
= MapSL(*lpParam1
);
429 *(LPMIDIOUTCAPS16
*)moc32
= moc16
;
430 moc32
= (LPMIDIOUTCAPSA
)((LPSTR
)moc32
+ sizeof(LPMIDIOUTCAPS16
));
431 *lpParam1
= (DWORD
)moc32
;
432 *lpParam2
= sizeof(MIDIOUTCAPSA
);
434 ret
= MMDRV_MAP_OKMEM
;
436 ret
= MMDRV_MAP_NOMEM
;
442 LPMIDIHDR mh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
));
443 LPMIDIHDR mh16
= MapSL(*lpParam1
);
446 *(LPMIDIHDR
*)mh32
= (LPMIDIHDR
)*lpParam1
;
447 mh32
= (LPMIDIHDR
)((LPSTR
)mh32
+ sizeof(LPMIDIHDR
));
448 mh32
->lpData
= MapSL((SEGPTR
)mh16
->lpData
);
449 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
450 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
451 mh32
->dwUser
= mh16
->dwUser
;
452 mh32
->dwFlags
= mh16
->dwFlags
;
453 /* FIXME: nothing on mh32->lpNext */
454 /* could link the mh32->lpNext at this level for memory house keeping */
455 mh32
->dwOffset
= (*lpParam2
>= sizeof(MIDIHDR
)) ? ((LPMIDIHDR
)mh16
)->dwOffset
: 0;
456 mh16
->lpNext
= mh32
; /* for reuse in unprepare and write */
457 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
458 mh16
->reserved
= *lpParam2
;
459 *lpParam1
= (DWORD
)mh32
;
460 *lpParam2
= sizeof(MIDIHDR
);
462 ret
= MMDRV_MAP_OKMEM
;
464 ret
= MMDRV_MAP_NOMEM
;
471 LPMIDIHDR mh16
= MapSL(*lpParam1
);
472 LPMIDIHDR mh32
= (LPMIDIHDR
)mh16
->lpNext
;
474 *lpParam1
= (DWORD
)mh32
;
475 *lpParam2
= sizeof(MIDIHDR
);
476 /* dwBufferLength can be reduced between prepare & write */
477 if (mh32
->dwBufferLength
< mh16
->dwBufferLength
) {
478 ERR("Size of buffer has been increased (%ld, %ld)\n",
479 mh32
->dwBufferLength
, mh16
->dwBufferLength
);
480 return MMDRV_MAP_MSGERROR
;
482 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
483 ret
= MMDRV_MAP_OKMEM
;
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_UnMap16To32A [internal]
499 static MMDRV_MapType
MMDRV_MidiOut_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
501 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
504 case MODM_GETNUMDEVS
:
514 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
517 case MODM_GETDEVCAPS
:
519 LPMIDIOUTCAPSA moc32
= (LPMIDIOUTCAPSA
)(*lpParam1
);
520 LPMIDIOUTCAPS16 moc16
= *(LPMIDIOUTCAPS16
*)((LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
522 moc16
->wMid
= moc32
->wMid
;
523 moc16
->wPid
= moc32
->wPid
;
524 moc16
->vDriverVersion
= moc32
->vDriverVersion
;
525 strcpy(moc16
->szPname
, moc32
->szPname
);
526 moc16
->wTechnology
= moc32
->wTechnology
;
527 moc16
->wVoices
= moc32
->wVoices
;
528 moc16
->wNotes
= moc32
->wNotes
;
529 moc16
->wChannelMask
= moc32
->wChannelMask
;
530 moc16
->dwSupport
= moc32
->dwSupport
;
531 HeapFree(GetProcessHeap(), 0, (LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
539 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
540 LPMIDIHDR mh16
= MapSL(*(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
)));
542 assert(mh16
->lpNext
== mh32
);
543 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
544 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
545 mh16
->dwUser
= mh32
->dwUser
;
546 mh16
->dwFlags
= mh32
->dwFlags
;
547 if (mh16
->reserved
>= sizeof(MIDIHDR
))
548 mh16
->dwOffset
= mh32
->dwOffset
;
550 if (wMsg
== MODM_UNPREPARE
) {
551 HeapFree(GetProcessHeap(), 0, (LPSTR
)mh32
- sizeof(LPMIDIHDR
));
558 case MODM_CACHEPATCHES
:
559 case MODM_CACHEDRUMPATCHES
:
561 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
567 /**************************************************************************
568 * MMDRV_MidiOut_Map32ATo16 [internal]
570 static MMDRV_MapType
MMDRV_MidiOut_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
572 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
576 case MODM_GETNUMDEVS
:
582 case MODM_GETDEVCAPS
:
584 LPMIDIOUTCAPSA moc32
= (LPMIDIOUTCAPSA
)*lpParam1
;
585 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMIDIOUTCAPSA
) + sizeof(MIDIOUTCAPS16
));
588 *(LPMIDIOUTCAPSA
*)ptr
= moc32
;
589 ret
= MMDRV_MAP_OKMEM
;
591 ret
= MMDRV_MAP_NOMEM
;
593 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIOUTCAPSA
);
594 *lpParam2
= sizeof(MIDIOUTCAPS16
);
599 LPMIDIHDR mh32
= (LPMIDIHDR
)*lpParam1
;
601 LPVOID ptr
= SEGPTR_ALLOC(sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
) + mh32
->dwBufferLength
);
604 *(LPMIDIHDR
*)ptr
= mh32
;
605 mh16
= (LPMIDIHDR
)((LPSTR
)ptr
+ sizeof(LPMIDIHDR
));
606 mh16
->lpData
= (LPSTR
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
);
607 /* data will be copied on WODM_WRITE */
608 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
609 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
610 mh16
->dwUser
= mh32
->dwUser
;
611 mh16
->dwFlags
= mh32
->dwFlags
;
612 /* FIXME: nothing on mh32->lpNext */
613 /* could link the mh32->lpNext at this level for memory house keeping */
614 mh16
->dwOffset
= (*lpParam2
>= sizeof(MIDIHDR
)) ? mh32
->dwOffset
: 0;
616 mh32
->lpNext
= (LPMIDIHDR
)mh16
; /* for reuse in unprepare and write */
617 mh32
->reserved
= *lpParam2
;
619 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
620 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
), (DWORD
)mh16
->lpData
,
621 mh32
->dwBufferLength
, (DWORD
)mh32
->lpData
);
622 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
);
623 *lpParam2
= sizeof(MIDIHDR
);
625 ret
= MMDRV_MAP_OKMEM
;
627 ret
= MMDRV_MAP_NOMEM
;
634 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
635 LPMIDIHDR mh16
= (LPMIDIHDR
)mh32
->lpNext
;
636 LPSTR ptr
= (LPSTR
)mh16
- sizeof(LPMIDIHDR
);
638 assert(*(LPMIDIHDR
*)ptr
== mh32
);
640 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
641 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
), (DWORD
)mh16
->lpData
,
642 mh32
->dwBufferLength
, (DWORD
)mh32
->lpData
);
644 if (wMsg
== MODM_LONGDATA
)
645 memcpy((LPSTR
)mh16
+ sizeof(MIDIHDR
), mh32
->lpData
, mh32
->dwBufferLength
);
647 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
);
648 *lpParam2
= sizeof(MIDIHDR
);
649 /* dwBufferLength can be reduced between prepare & write */
650 if (mh16
->dwBufferLength
< mh32
->dwBufferLength
) {
651 ERR("Size of buffer has been increased (%ld, %ld)\n",
652 mh16
->dwBufferLength
, mh32
->dwBufferLength
);
653 return MMDRV_MAP_MSGERROR
;
655 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
656 ret
= MMDRV_MAP_OKMEM
;
661 LPMIDIOPENDESC mod32
= (LPMIDIOPENDESC
)*lpParam1
;
663 LPMIDIOPENDESC16 mod16
;
665 /* allocated data are mapped as follows:
666 LPMIDIOPENDESC ptr to orig lParam1
667 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
668 DWORD dwUser passed to driver
669 MIDIOPENDESC16 mod16: openDesc passed to driver
672 ptr
= SEGPTR_ALLOC(sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
) + sizeof(MIDIOPENDESC16
) +
673 mod32
->cIds
? (mod32
->cIds
- 1) * sizeof(MIDIOPENSTRMID
) : 0);
676 *(LPMIDIOPENDESC
*)ptr
= mod32
;
677 *(LPDWORD
)(ptr
+ sizeof(LPMIDIOPENDESC
)) = *lpdwUser
;
678 mod16
= (LPMIDIOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
));
680 mod16
->hMidi
= mod32
->hMidi
;
681 mod16
->dwCallback
= mod32
->dwCallback
;
682 mod16
->dwInstance
= mod32
->dwInstance
;
683 mod16
->dnDevNode
= mod32
->dnDevNode
;
684 mod16
->cIds
= mod32
->cIds
;
685 memcpy(&mod16
->rgIds
, &mod32
->rgIds
, mod32
->cIds
* sizeof(MIDIOPENSTRMID
));
687 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
);
688 *lpdwUser
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIOPENDESC
) + sizeof(DWORD
);
690 ret
= MMDRV_MAP_OKMEM
;
692 ret
= MMDRV_MAP_NOMEM
;
697 case MODM_CACHEPATCHES
:
698 case MODM_CACHEDRUMPATCHES
:
700 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
706 /**************************************************************************
707 * MMDRV_MidiOut_UnMap32ATo16 [internal]
709 static MMDRV_MapType
MMDRV_MidiOut_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
711 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
715 case MODM_GETNUMDEVS
:
721 case MODM_GETDEVCAPS
:
723 LPMIDIOUTCAPS16 moc16
= MapSL(*lpParam1
);
724 LPSTR ptr
= (LPSTR
)moc16
- sizeof(LPMIDIOUTCAPSA
);
725 LPMIDIOUTCAPSA moc32
= *(LPMIDIOUTCAPSA
*)ptr
;
727 moc32
->wMid
= moc16
->wMid
;
728 moc32
->wPid
= moc16
->wPid
;
729 moc32
->vDriverVersion
= moc16
->vDriverVersion
;
730 strcpy(moc32
->szPname
, moc16
->szPname
);
731 moc32
->wTechnology
= moc16
->wTechnology
;
732 moc32
->wVoices
= moc16
->wVoices
;
733 moc32
->wNotes
= moc16
->wNotes
;
734 moc32
->wChannelMask
= moc16
->wChannelMask
;
735 moc32
->dwSupport
= moc16
->dwSupport
;
737 if (!SEGPTR_FREE(ptr
))
738 FIXME("bad free line=%d\n", __LINE__
);
746 LPMIDIHDR mh16
= MapSL(*lpParam1
);
747 LPSTR ptr
= (LPSTR
)mh16
- sizeof(LPMIDIHDR
);
748 LPMIDIHDR mh32
= *(LPMIDIHDR
*)ptr
;
750 assert(mh32
->lpNext
== (LPMIDIHDR
)mh16
);
751 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
752 mh32
->dwUser
= mh16
->dwUser
;
753 mh32
->dwFlags
= mh16
->dwFlags
;
755 if (wMsg
== MODM_UNPREPARE
) {
756 if (!SEGPTR_FREE(ptr
))
757 FIXME("bad free line=%d\n", __LINE__
);
765 LPMIDIOPENDESC16 mod16
= MapSL(*lpParam1
);
766 LPSTR ptr
= (LPSTR
)mod16
- sizeof(LPMIDIOPENDESC
) - 2*sizeof(DWORD
);
768 **(DWORD
**)(ptr
+ sizeof(LPMIDIOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPMIDIOPENDESC
) + sizeof(DWORD
));
770 if (!SEGPTR_FREE(ptr
))
771 FIXME("bad free line=%d\n", __LINE__
);
777 case MODM_CACHEPATCHES
:
778 case MODM_CACHEDRUMPATCHES
:
780 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
786 /**************************************************************************
787 * MMDRV_MidiOut_Callback [internal]
789 static void CALLBACK
MMDRV_MidiOut_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
791 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
796 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
799 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
800 /* initial map is: 32 => 16 */
801 LPMIDIHDR mh16
= MapSL(dwParam1
);
802 LPMIDIHDR mh32
= *(LPMIDIHDR
*)((LPSTR
)mh16
- sizeof(LPMIDIHDR
));
804 dwParam1
= (DWORD
)mh32
;
805 mh32
->dwFlags
= mh16
->dwFlags
;
806 mh32
->dwOffset
= mh16
->dwOffset
;
807 if (mh32
->reserved
>= sizeof(MIDIHDR
))
808 mh32
->dwOffset
= mh16
->dwOffset
;
809 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
810 /* initial map is: 16 => 32 */
811 LPMIDIHDR mh32
= (LPMIDIHDR
)(dwParam1
);
812 SEGPTR segmh16
= *(SEGPTR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
813 LPMIDIHDR mh16
= MapSL(segmh16
);
815 dwParam1
= (DWORD
)segmh16
;
816 mh16
->dwFlags
= mh32
->dwFlags
;
817 if (mh16
->reserved
>= sizeof(MIDIHDR
))
818 mh16
->dwOffset
= mh32
->dwOffset
;
820 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
822 /* case MOM_POSITIONCB: */
824 ERR("Unknown msg %u\n", uMsg
);
827 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
830 /* =================================
831 * W A V E I N M A P P E R S
832 * ================================= */
834 /**************************************************************************
835 * MMDRV_WaveIn_Map16To32A [internal]
837 static MMDRV_MapType
MMDRV_WaveIn_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
839 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
842 case WIDM_GETNUMDEVS
:
850 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
852 case WIDM_GETDEVCAPS
:
854 LPWAVEINCAPSA wic32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16
) + sizeof(WAVEINCAPSA
));
855 LPWAVEINCAPS16 wic16
= MapSL(*lpParam1
);
858 *(LPWAVEINCAPS16
*)wic32
= wic16
;
859 wic32
= (LPWAVEINCAPSA
)((LPSTR
)wic32
+ sizeof(LPWAVEINCAPS16
));
860 *lpParam1
= (DWORD
)wic32
;
861 *lpParam2
= sizeof(WAVEINCAPSA
);
863 ret
= MMDRV_MAP_OKMEM
;
865 ret
= MMDRV_MAP_NOMEM
;
871 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
872 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
875 *(LPMMTIME16
*)mmt32
= mmt16
;
876 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
878 mmt32
->wType
= mmt16
->wType
;
879 *lpParam1
= (DWORD
)mmt32
;
880 *lpParam2
= sizeof(MMTIME
);
882 ret
= MMDRV_MAP_OKMEM
;
884 ret
= MMDRV_MAP_NOMEM
;
890 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
891 LPWAVEHDR wh16
= MapSL(*lpParam1
);
894 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
895 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
896 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
897 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
898 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
899 wh32
->dwUser
= wh16
->dwUser
;
900 wh32
->dwFlags
= wh16
->dwFlags
;
901 wh32
->dwLoops
= wh16
->dwLoops
;
902 /* FIXME: nothing on wh32->lpNext */
903 /* could link the wh32->lpNext at this level for memory house keeping */
904 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
905 *lpParam1
= (DWORD
)wh32
;
906 *lpParam2
= sizeof(WAVEHDR
);
908 ret
= MMDRV_MAP_OKMEM
;
910 ret
= MMDRV_MAP_NOMEM
;
917 LPWAVEHDR wh16
= MapSL(*lpParam1
);
918 LPWAVEHDR wh32
= (LPWAVEHDR
)wh16
->lpNext
;
920 *lpParam1
= (DWORD
)wh32
;
921 *lpParam2
= sizeof(WAVEHDR
);
922 /* dwBufferLength can be reduced between prepare & write */
923 if (wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
924 ERR("Size of buffer has been increased (%ld, %ld)\n",
925 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
926 return MMDRV_MAP_MSGERROR
;
928 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
929 ret
= MMDRV_MAP_OKMEM
;
932 case WIDM_MAPPER_STATUS
:
933 /* just a single DWORD */
934 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
938 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
944 /**************************************************************************
945 * MMDRV_WaveIn_UnMap16To32A [internal]
947 static MMDRV_MapType
MMDRV_WaveIn_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
949 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
952 case WIDM_GETNUMDEVS
:
956 case WIDM_MAPPER_STATUS
:
961 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
963 case WIDM_GETDEVCAPS
:
965 LPWAVEINCAPSA wic32
= (LPWAVEINCAPSA
)(*lpParam1
);
966 LPWAVEINCAPS16 wic16
= *(LPWAVEINCAPS16
*)((LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
968 wic16
->wMid
= wic32
->wMid
;
969 wic16
->wPid
= wic32
->wPid
;
970 wic16
->vDriverVersion
= wic32
->vDriverVersion
;
971 strcpy(wic16
->szPname
, wic32
->szPname
);
972 wic16
->dwFormats
= wic32
->dwFormats
;
973 wic16
->wChannels
= wic32
->wChannels
;
974 HeapFree(GetProcessHeap(), 0, (LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
980 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
981 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
983 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
984 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
992 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
993 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
995 assert(wh16
->lpNext
== wh32
);
996 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
997 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
998 wh16
->dwUser
= wh32
->dwUser
;
999 wh16
->dwFlags
= wh32
->dwFlags
;
1000 wh16
->dwLoops
= wh32
->dwLoops
;
1002 if (wMsg
== WIDM_UNPREPARE
) {
1003 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1010 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1016 /**************************************************************************
1017 * MMDRV_WaveIn_Map32ATo16 [internal]
1019 static MMDRV_MapType
MMDRV_WaveIn_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1021 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1025 case WIDM_GETNUMDEVS
:
1034 LPWAVEOPENDESC wod32
= (LPWAVEOPENDESC
)*lpParam1
;
1035 int sz
= sizeof(WAVEFORMATEX
);
1037 LPWAVEOPENDESC16 wod16
;
1039 /* allocated data are mapped as follows:
1040 LPWAVEOPENDESC ptr to orig lParam1
1041 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1042 DWORD dwUser passed to driver
1043 WAVEOPENDESC16 wod16: openDesc passed to driver
1044 WAVEFORMATEX openDesc->lpFormat passed to driver
1045 xxx extra bytes to WAVEFORMATEX
1047 if (wod32
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
1048 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
, wod32
->lpFormat
->wFormatTag
);
1049 sz
+= ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
;
1052 ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
) + sz
);
1055 *(LPWAVEOPENDESC
*)ptr
= wod32
;
1056 *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *lpdwUser
;
1057 wod16
= (LPWAVEOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
));
1059 wod16
->hWave
= wod32
->hWave
;
1060 wod16
->lpFormat
= (LPWAVEFORMATEX
)((DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
));
1061 memcpy(wod16
+ 1, wod32
->lpFormat
, sz
);
1063 wod16
->dwCallback
= wod32
->dwCallback
;
1064 wod16
->dwInstance
= wod32
->dwInstance
;
1065 wod16
->uMappedDeviceID
= wod32
->uMappedDeviceID
;
1066 wod16
->dnDevNode
= wod32
->dnDevNode
;
1068 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
);
1069 *lpdwUser
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
);
1071 ret
= MMDRV_MAP_OKMEM
;
1073 ret
= MMDRV_MAP_NOMEM
;
1079 LPWAVEHDR wh32
= (LPWAVEHDR
)*lpParam1
;
1081 LPVOID ptr
= SEGPTR_ALLOC(sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
) + wh32
->dwBufferLength
);
1084 *(LPWAVEHDR
*)ptr
= wh32
;
1085 wh16
= (LPWAVEHDR
)((LPSTR
)ptr
+ sizeof(LPWAVEHDR
));
1086 wh16
->lpData
= (LPSTR
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
);
1087 /* data will be copied on WODM_WRITE */
1088 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1089 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1090 wh16
->dwUser
= wh32
->dwUser
;
1091 wh16
->dwFlags
= wh32
->dwFlags
;
1092 wh16
->dwLoops
= wh32
->dwLoops
;
1093 /* FIXME: nothing on wh32->lpNext */
1094 /* could link the wh32->lpNext at this level for memory house keeping */
1095 wh32
->lpNext
= wh16
; /* for reuse in unprepare and write */
1096 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1097 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1098 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1099 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1100 *lpParam2
= sizeof(WAVEHDR
);
1102 ret
= MMDRV_MAP_OKMEM
;
1104 ret
= MMDRV_MAP_NOMEM
;
1108 case WIDM_ADDBUFFER
:
1109 case WIDM_UNPREPARE
:
1111 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1112 LPWAVEHDR wh16
= wh32
->lpNext
;
1113 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1115 assert(*(LPWAVEHDR
*)ptr
== wh32
);
1117 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1118 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1119 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1121 if (wMsg
== WIDM_ADDBUFFER
)
1122 memcpy((LPSTR
)wh16
+ sizeof(WAVEHDR
), wh32
->lpData
, wh32
->dwBufferLength
);
1124 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1125 *lpParam2
= sizeof(WAVEHDR
);
1126 /* dwBufferLength can be reduced between prepare & write */
1127 if (wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
1128 ERR("Size of buffer has been increased (%ld, %ld)\n",
1129 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
1130 return MMDRV_MAP_MSGERROR
;
1132 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1133 ret
= MMDRV_MAP_OKMEM
;
1136 case WIDM_GETDEVCAPS
:
1138 LPWAVEINCAPSA wic32
= (LPWAVEINCAPSA
)*lpParam1
;
1139 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPWAVEINCAPSA
) + sizeof(WAVEINCAPS16
));
1142 *(LPWAVEINCAPSA
*)ptr
= wic32
;
1143 ret
= MMDRV_MAP_OKMEM
;
1145 ret
= MMDRV_MAP_NOMEM
;
1147 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEINCAPSA
);
1148 *lpParam2
= sizeof(WAVEINCAPS16
);
1153 LPMMTIME mmt32
= (LPMMTIME
)*lpParam1
;
1154 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMMTIME
) + sizeof(MMTIME16
));
1155 LPMMTIME16 mmt16
= (LPMMTIME16
)(ptr
+ sizeof(LPMMTIME
));
1158 *(LPMMTIME
*)ptr
= mmt32
;
1159 mmt16
->wType
= mmt32
->wType
;
1160 ret
= MMDRV_MAP_OKMEM
;
1162 ret
= MMDRV_MAP_NOMEM
;
1164 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMMTIME
);
1165 *lpParam2
= sizeof(MMTIME16
);
1168 case DRVM_MAPPER_STATUS
:
1170 LPDWORD p32
= (LPDWORD
)*lpParam2
;
1175 switch (*lpParam1
) {
1176 case WAVEIN_MAPPER_STATUS_DEVICE
: sz
= sizeof(DWORD
); break;
1177 case WAVEIN_MAPPER_STATUS_MAPPED
: sz
= sizeof(DWORD
); break;
1178 case WAVEIN_MAPPER_STATUS_FORMAT
: sz
= sizeof(WAVEFORMATEX
); break;
1180 ERR("Unknown value: %lu\n", *lpParam1
);
1181 return MMDRV_MAP_MSGERROR
;
1183 ptr
= SEGPTR_ALLOC(sizeof(LPDWORD
) + sz
);
1184 p16
= (LPDWORD
)(ptr
+ sizeof(LPDWORD
));
1187 *(LPDWORD
*)ptr
= p32
;
1188 ret
= MMDRV_MAP_OKMEM
;
1190 ret
= MMDRV_MAP_NOMEM
;
1192 *lpParam2
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPDWORD
);
1196 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1202 /**************************************************************************
1203 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1205 static MMDRV_MapType
MMDRV_WaveIn_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1207 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1211 case WIDM_GETNUMDEVS
:
1220 LPWAVEOPENDESC16 wod16
= MapSL(*lpParam1
);
1221 LPSTR ptr
= (LPSTR
)wod16
- sizeof(LPWAVEOPENDESC
) - 2*sizeof(DWORD
);
1222 LPWAVEOPENDESC wod32
= *(LPWAVEOPENDESC
*)ptr
;
1224 wod32
->uMappedDeviceID
= wod16
->uMappedDeviceID
;
1225 **(DWORD
**)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
));
1227 if (!SEGPTR_FREE(ptr
))
1228 FIXME("bad free line=%d\n", __LINE__
);
1234 case WIDM_ADDBUFFER
:
1236 case WIDM_UNPREPARE
:
1238 LPWAVEHDR wh16
= MapSL(*lpParam1
);
1239 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1240 LPWAVEHDR wh32
= *(LPWAVEHDR
*)ptr
;
1242 assert(wh32
->lpNext
== wh16
);
1243 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1244 wh32
->dwUser
= wh16
->dwUser
;
1245 wh32
->dwFlags
= wh16
->dwFlags
;
1246 wh32
->dwLoops
= wh16
->dwLoops
;
1248 if (wMsg
== WIDM_UNPREPARE
) {
1249 if (!SEGPTR_FREE(ptr
))
1250 FIXME("bad free line=%d\n", __LINE__
);
1256 case WIDM_GETDEVCAPS
:
1258 LPWAVEINCAPS16 wic16
= MapSL(*lpParam1
);
1259 LPSTR ptr
= (LPSTR
)wic16
- sizeof(LPWAVEINCAPSA
);
1260 LPWAVEINCAPSA wic32
= *(LPWAVEINCAPSA
*)ptr
;
1262 wic32
->wMid
= wic16
->wMid
;
1263 wic32
->wPid
= wic16
->wPid
;
1264 wic32
->vDriverVersion
= wic16
->vDriverVersion
;
1265 strcpy(wic32
->szPname
, wic16
->szPname
);
1266 wic32
->dwFormats
= wic16
->dwFormats
;
1267 wic32
->wChannels
= wic16
->wChannels
;
1268 if (!SEGPTR_FREE(ptr
))
1269 FIXME("bad free line=%d\n", __LINE__
);
1275 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
1276 LPSTR ptr
= (LPSTR
)mmt16
- sizeof(LPMMTIME
);
1277 LPMMTIME mmt32
= *(LPMMTIME
*)ptr
;
1279 MMSYSTEM_MMTIME16to32(mmt32
, mmt16
);
1281 if (!SEGPTR_FREE(ptr
))
1282 FIXME("bad free line=%d\n", __LINE__
);
1287 case DRVM_MAPPER_STATUS
:
1289 LPDWORD p16
= MapSL(*lpParam2
);
1290 LPSTR ptr
= (LPSTR
)p16
- sizeof(LPDWORD
);
1291 LPDWORD p32
= *(LPDWORD
*)ptr
;
1294 switch (*lpParam1
) {
1295 case WAVEIN_MAPPER_STATUS_DEVICE
: sz
= sizeof(DWORD
); break;
1296 case WAVEIN_MAPPER_STATUS_MAPPED
: sz
= sizeof(DWORD
); break;
1297 case WAVEIN_MAPPER_STATUS_FORMAT
: sz
= sizeof(WAVEFORMATEX
); break;
1299 ERR("Unknown value: %lu\n", *lpParam1
);
1300 return MMDRV_MAP_MSGERROR
;
1303 memcpy(p32
, p16
, sz
);
1304 if (!SEGPTR_FREE(ptr
))
1305 FIXME("bad free line=%d\n", __LINE__
);
1311 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1317 /**************************************************************************
1318 * MMDRV_WaveIn_Callback [internal]
1320 static void CALLBACK
MMDRV_WaveIn_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
1322 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
1327 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1330 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
1331 /* initial map is: 32 => 16 */
1332 LPWAVEHDR wh16
= MapSL(dwParam1
);
1333 LPWAVEHDR wh32
= *(LPWAVEHDR
*)((LPSTR
)wh16
- sizeof(LPWAVEHDR
));
1335 dwParam1
= (DWORD
)wh32
;
1336 wh32
->dwFlags
= wh16
->dwFlags
;
1337 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1338 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
1339 /* initial map is: 16 => 32 */
1340 LPWAVEHDR wh32
= (LPWAVEHDR
)(dwParam1
);
1341 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1342 LPWAVEHDR wh16
= MapSL(segwh16
);
1344 dwParam1
= (DWORD
)segwh16
;
1345 wh16
->dwFlags
= wh32
->dwFlags
;
1346 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1348 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1351 ERR("Unknown msg %u\n", uMsg
);
1354 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
1357 /* =================================
1358 * W A V E O U T M A P P E R S
1359 * ================================= */
1361 /**************************************************************************
1362 * MMDRV_WaveOut_Map16To32A [internal]
1364 static MMDRV_MapType
MMDRV_WaveOut_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1366 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1370 case WODM_BREAKLOOP
:
1372 case WODM_GETNUMDEVS
:
1377 case WODM_SETPLAYBACKRATE
:
1378 case WODM_SETVOLUME
:
1383 case WODM_GETPLAYBACKRATE
:
1384 case WODM_GETVOLUME
:
1386 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1389 case WODM_GETDEVCAPS
:
1391 LPWAVEOUTCAPSA woc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16
) + sizeof(WAVEOUTCAPSA
));
1392 LPWAVEOUTCAPS16 woc16
= MapSL(*lpParam1
);
1395 *(LPWAVEOUTCAPS16
*)woc32
= woc16
;
1396 woc32
= (LPWAVEOUTCAPSA
)((LPSTR
)woc32
+ sizeof(LPWAVEOUTCAPS16
));
1397 *lpParam1
= (DWORD
)woc32
;
1398 *lpParam2
= sizeof(WAVEOUTCAPSA
);
1400 ret
= MMDRV_MAP_OKMEM
;
1402 ret
= MMDRV_MAP_NOMEM
;
1408 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
1409 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
1412 *(LPMMTIME16
*)mmt32
= mmt16
;
1413 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
1415 mmt32
->wType
= mmt16
->wType
;
1416 *lpParam1
= (DWORD
)mmt32
;
1417 *lpParam2
= sizeof(MMTIME
);
1419 ret
= MMDRV_MAP_OKMEM
;
1421 ret
= MMDRV_MAP_NOMEM
;
1427 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
1428 LPWAVEHDR wh16
= MapSL(*lpParam1
);
1431 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
1432 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
1433 wh32
->lpData
= MapSL((SEGPTR
)wh16
->lpData
);
1434 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1435 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1436 wh32
->dwUser
= wh16
->dwUser
;
1437 wh32
->dwFlags
= wh16
->dwFlags
;
1438 wh32
->dwLoops
= wh16
->dwLoops
;
1439 /* FIXME: nothing on wh32->lpNext */
1440 /* could link the wh32->lpNext at this level for memory house keeping */
1441 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
1442 *lpParam1
= (DWORD
)wh32
;
1443 *lpParam2
= sizeof(WAVEHDR
);
1445 ret
= MMDRV_MAP_OKMEM
;
1447 ret
= MMDRV_MAP_NOMEM
;
1451 case WODM_UNPREPARE
:
1454 LPWAVEHDR wh16
= MapSL(*lpParam1
);
1455 LPWAVEHDR wh32
= (LPWAVEHDR
)wh16
->lpNext
;
1457 *lpParam1
= (DWORD
)wh32
;
1458 *lpParam2
= sizeof(WAVEHDR
);
1459 /* dwBufferLength can be reduced between prepare & write */
1460 if (wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
1461 ERR("Size of buffer has been increased (%ld, %ld)\n",
1462 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
1463 return MMDRV_MAP_MSGERROR
;
1465 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1466 ret
= MMDRV_MAP_OKMEM
;
1469 case WODM_MAPPER_STATUS
:
1470 *lpParam2
= (DWORD
)MapSL(*lpParam2
);
1474 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1480 /**************************************************************************
1481 * MMDRV_WaveOut_UnMap16To32A [internal]
1483 static MMDRV_MapType
MMDRV_WaveOut_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1485 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1489 case WODM_BREAKLOOP
:
1491 case WODM_GETNUMDEVS
:
1496 case WODM_SETPLAYBACKRATE
:
1497 case WODM_SETVOLUME
:
1498 case WODM_MAPPER_STATUS
:
1503 case WODM_GETPLAYBACKRATE
:
1504 case WODM_GETVOLUME
:
1506 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1509 case WODM_GETDEVCAPS
:
1511 LPWAVEOUTCAPSA woc32
= (LPWAVEOUTCAPSA
)(*lpParam1
);
1512 LPWAVEOUTCAPS16 woc16
= *(LPWAVEOUTCAPS16
*)((LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
1514 woc16
->wMid
= woc32
->wMid
;
1515 woc16
->wPid
= woc32
->wPid
;
1516 woc16
->vDriverVersion
= woc32
->vDriverVersion
;
1517 strcpy(woc16
->szPname
, woc32
->szPname
);
1518 woc16
->dwFormats
= woc32
->dwFormats
;
1519 woc16
->wChannels
= woc32
->wChannels
;
1520 woc16
->dwSupport
= woc32
->dwSupport
;
1521 HeapFree(GetProcessHeap(), 0, (LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
1527 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
1528 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1530 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
1531 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1536 case WODM_UNPREPARE
:
1539 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1540 LPWAVEHDR wh16
= MapSL(*(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
1542 assert(wh16
->lpNext
== wh32
);
1543 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1544 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1545 wh16
->dwUser
= wh32
->dwUser
;
1546 wh16
->dwFlags
= wh32
->dwFlags
;
1547 wh16
->dwLoops
= wh32
->dwLoops
;
1549 if (wMsg
== WODM_UNPREPARE
) {
1550 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1557 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1563 /**************************************************************************
1564 * MMDRV_WaveOut_Map32ATo16 [internal]
1566 static MMDRV_MapType
MMDRV_WaveOut_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1572 case WODM_BREAKLOOP
:
1574 case WODM_GETNUMDEVS
:
1579 case WODM_SETPLAYBACKRATE
:
1580 case WODM_SETVOLUME
:
1584 case WODM_GETDEVCAPS
:
1586 LPWAVEOUTCAPSA woc32
= (LPWAVEOUTCAPSA
)*lpParam1
;
1587 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOUTCAPSA
) + sizeof(WAVEOUTCAPS16
));
1590 *(LPWAVEOUTCAPSA
*)ptr
= woc32
;
1591 ret
= MMDRV_MAP_OKMEM
;
1593 ret
= MMDRV_MAP_NOMEM
;
1595 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOUTCAPSA
);
1596 *lpParam2
= sizeof(WAVEOUTCAPS16
);
1600 FIXME("NIY: no conversion yet\n");
1601 ret
= MMDRV_MAP_MSGERROR
;
1603 case WODM_GETPLAYBACKRATE
:
1604 FIXME("NIY: no conversion yet\n");
1605 ret
= MMDRV_MAP_MSGERROR
;
1609 LPMMTIME mmt32
= (LPMMTIME
)*lpParam1
;
1610 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMMTIME
) + sizeof(MMTIME16
));
1611 LPMMTIME16 mmt16
= (LPMMTIME16
)(ptr
+ sizeof(LPMMTIME
));
1614 *(LPMMTIME
*)ptr
= mmt32
;
1615 mmt16
->wType
= mmt32
->wType
;
1616 ret
= MMDRV_MAP_OKMEM
;
1618 ret
= MMDRV_MAP_NOMEM
;
1620 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMMTIME
);
1621 *lpParam2
= sizeof(MMTIME16
);
1624 case WODM_GETVOLUME
:
1625 FIXME("NIY: no conversion yet\n");
1626 ret
= MMDRV_MAP_MSGERROR
;
1630 LPWAVEOPENDESC wod32
= (LPWAVEOPENDESC
)*lpParam1
;
1631 int sz
= sizeof(WAVEFORMATEX
);
1633 LPWAVEOPENDESC16 wod16
;
1635 /* allocated data are mapped as follows:
1636 LPWAVEOPENDESC ptr to orig lParam1
1637 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1638 DWORD dwUser passed to driver
1639 WAVEOPENDESC16 wod16: openDesc passed to driver
1640 WAVEFORMATEX openDesc->lpFormat passed to driver
1641 xxx extra bytes to WAVEFORMATEX
1643 if (wod32
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
1644 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
, wod32
->lpFormat
->wFormatTag
);
1645 sz
+= ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
;
1648 ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
) + sz
);
1651 *(LPWAVEOPENDESC
*)ptr
= wod32
;
1652 *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *lpdwUser
;
1653 wod16
= (LPWAVEOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
));
1655 wod16
->hWave
= wod32
->hWave
;
1656 wod16
->lpFormat
= (LPWAVEFORMATEX
)((DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
));
1657 memcpy(wod16
+ 1, wod32
->lpFormat
, sz
);
1659 wod16
->dwCallback
= wod32
->dwCallback
;
1660 wod16
->dwInstance
= wod32
->dwInstance
;
1661 wod16
->uMappedDeviceID
= wod32
->uMappedDeviceID
;
1662 wod16
->dnDevNode
= wod32
->dnDevNode
;
1664 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
);
1665 *lpdwUser
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
);
1667 ret
= MMDRV_MAP_OKMEM
;
1669 ret
= MMDRV_MAP_NOMEM
;
1675 LPWAVEHDR wh32
= (LPWAVEHDR
)*lpParam1
;
1677 LPVOID ptr
= SEGPTR_ALLOC(sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
) + wh32
->dwBufferLength
);
1680 *(LPWAVEHDR
*)ptr
= wh32
;
1681 wh16
= (LPWAVEHDR
)((LPSTR
)ptr
+ sizeof(LPWAVEHDR
));
1682 wh16
->lpData
= (LPSTR
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
);
1683 /* data will be copied on WODM_WRITE */
1684 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1685 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1686 wh16
->dwUser
= wh32
->dwUser
;
1687 wh16
->dwFlags
= wh32
->dwFlags
;
1688 wh16
->dwLoops
= wh32
->dwLoops
;
1689 /* FIXME: nothing on wh32->lpNext */
1690 /* could link the wh32->lpNext at this level for memory house keeping */
1691 wh32
->lpNext
= wh16
; /* for reuse in unprepare and write */
1692 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1693 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1694 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1695 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1696 *lpParam2
= sizeof(WAVEHDR
);
1698 ret
= MMDRV_MAP_OKMEM
;
1700 ret
= MMDRV_MAP_NOMEM
;
1704 case WODM_UNPREPARE
:
1707 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1708 LPWAVEHDR wh16
= wh32
->lpNext
;
1709 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1711 assert(*(LPWAVEHDR
*)ptr
== wh32
);
1713 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1714 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1715 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1717 if (wMsg
== WODM_WRITE
)
1718 memcpy((LPSTR
)wh16
+ sizeof(WAVEHDR
), wh32
->lpData
, wh32
->dwBufferLength
);
1720 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1721 *lpParam2
= sizeof(WAVEHDR
);
1722 /* dwBufferLength can be reduced between prepare & write */
1723 if (wh16
->dwBufferLength
< wh32
->dwBufferLength
) {
1724 ERR("Size of buffer has been increased (%ld, %ld)\n",
1725 wh16
->dwBufferLength
, wh32
->dwBufferLength
);
1726 return MMDRV_MAP_MSGERROR
;
1728 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1729 ret
= MMDRV_MAP_OKMEM
;
1732 case DRVM_MAPPER_STATUS
:
1734 LPDWORD p32
= (LPDWORD
)*lpParam2
;
1739 switch (*lpParam1
) {
1740 case WAVEOUT_MAPPER_STATUS_DEVICE
: sz
= sizeof(DWORD
); break;
1741 case WAVEOUT_MAPPER_STATUS_MAPPED
: sz
= sizeof(DWORD
); break;
1742 case WAVEOUT_MAPPER_STATUS_FORMAT
: sz
= sizeof(WAVEFORMATEX
); break;
1744 ERR("Unknown value: %lu\n", *lpParam1
);
1745 return MMDRV_MAP_MSGERROR
;
1747 ptr
= SEGPTR_ALLOC(sizeof(LPDWORD
) + sz
);
1748 p16
= (LPDWORD
)(ptr
+ sizeof(LPDWORD
));
1751 *(LPDWORD
*)ptr
= p32
;
1752 memcpy(p16
, p32
, sz
);
1753 ret
= MMDRV_MAP_OKMEM
;
1755 ret
= MMDRV_MAP_NOMEM
;
1757 *lpParam2
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPDWORD
);
1761 FIXME("NIY: no conversion yet\n");
1762 ret
= MMDRV_MAP_MSGERROR
;
1768 /**************************************************************************
1769 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1771 static MMDRV_MapType
MMDRV_WaveOut_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1777 case WODM_BREAKLOOP
:
1779 case WODM_GETNUMDEVS
:
1784 case WODM_SETPLAYBACKRATE
:
1785 case WODM_SETVOLUME
:
1789 case WODM_GETDEVCAPS
:
1791 LPWAVEOUTCAPS16 woc16
= MapSL(*lpParam1
);
1792 LPSTR ptr
= (LPSTR
)woc16
- sizeof(LPWAVEOUTCAPSA
);
1793 LPWAVEOUTCAPSA woc32
= *(LPWAVEOUTCAPSA
*)ptr
;
1795 woc32
->wMid
= woc16
->wMid
;
1796 woc32
->wPid
= woc16
->wPid
;
1797 woc32
->vDriverVersion
= woc16
->vDriverVersion
;
1798 strcpy(woc32
->szPname
, woc16
->szPname
);
1799 woc32
->dwFormats
= woc16
->dwFormats
;
1800 woc32
->wChannels
= woc16
->wChannels
;
1801 woc32
->dwSupport
= woc16
->dwSupport
;
1802 if (!SEGPTR_FREE(ptr
))
1803 FIXME("bad free line=%d\n", __LINE__
);
1808 FIXME("NIY: no conversion yet\n");
1809 ret
= MMDRV_MAP_MSGERROR
;
1811 case WODM_GETPLAYBACKRATE
:
1812 FIXME("NIY: no conversion yet\n");
1813 ret
= MMDRV_MAP_MSGERROR
;
1817 LPMMTIME16 mmt16
= MapSL(*lpParam1
);
1818 LPSTR ptr
= (LPSTR
)mmt16
- sizeof(LPMMTIME
);
1819 LPMMTIME mmt32
= *(LPMMTIME
*)ptr
;
1821 MMSYSTEM_MMTIME16to32(mmt32
, mmt16
);
1823 if (!SEGPTR_FREE(ptr
))
1824 FIXME("bad free line=%d\n", __LINE__
);
1831 LPWAVEOPENDESC16 wod16
= MapSL(*lpParam1
);
1832 LPSTR ptr
= (LPSTR
)wod16
- sizeof(LPWAVEOPENDESC
) - 2*sizeof(DWORD
);
1833 LPWAVEOPENDESC wod32
= *(LPWAVEOPENDESC
*)ptr
;
1835 wod32
->uMappedDeviceID
= wod16
->uMappedDeviceID
;
1836 **(DWORD
**)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
));
1838 if (!SEGPTR_FREE(ptr
))
1839 FIXME("bad free line=%d\n", __LINE__
);
1845 case WODM_UNPREPARE
:
1848 LPWAVEHDR wh16
= MapSL(*lpParam1
);
1849 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1850 LPWAVEHDR wh32
= *(LPWAVEHDR
*)ptr
;
1852 assert(wh32
->lpNext
== wh16
);
1853 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1854 wh32
->dwUser
= wh16
->dwUser
;
1855 wh32
->dwFlags
= wh16
->dwFlags
;
1856 wh32
->dwLoops
= wh16
->dwLoops
;
1858 if (wMsg
== WODM_UNPREPARE
) {
1859 if (!SEGPTR_FREE(ptr
))
1860 FIXME("bad free line=%d\n", __LINE__
);
1866 case WODM_GETVOLUME
:
1867 FIXME("NIY: no conversion yet\n");
1868 ret
= MMDRV_MAP_MSGERROR
;
1870 case DRVM_MAPPER_STATUS
:
1872 LPDWORD p16
= MapSL(*lpParam2
);
1873 LPSTR ptr
= (LPSTR
)p16
- sizeof(LPDWORD
);
1874 LPDWORD p32
= *(LPDWORD
*)ptr
;
1877 switch (*lpParam1
) {
1878 case WAVEOUT_MAPPER_STATUS_DEVICE
: sz
= sizeof(DWORD
); break;
1879 case WAVEOUT_MAPPER_STATUS_MAPPED
: sz
= sizeof(DWORD
); break;
1880 case WAVEOUT_MAPPER_STATUS_FORMAT
: sz
= sizeof(WAVEFORMATEX
); break;
1882 ERR("Unknown value: %lu\n", *lpParam1
);
1883 return MMDRV_MAP_MSGERROR
;
1886 memcpy(p32
, p16
, sz
);
1887 if (!SEGPTR_FREE(ptr
))
1888 FIXME("bad free line=%d\n", __LINE__
);
1894 FIXME("NIY: no conversion yet\n");
1895 ret
= MMDRV_MAP_MSGERROR
;
1901 /**************************************************************************
1902 * MMDRV_WaveOut_Callback [internal]
1904 static void CALLBACK
MMDRV_WaveOut_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
1906 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
1911 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1914 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
1915 /* initial map is: 32 => 16 */
1916 LPWAVEHDR wh16
= MapSL(dwParam1
);
1917 LPWAVEHDR wh32
= *(LPWAVEHDR
*)((LPSTR
)wh16
- sizeof(LPWAVEHDR
));
1919 dwParam1
= (DWORD
)wh32
;
1920 wh32
->dwFlags
= wh16
->dwFlags
;
1921 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
1922 /* initial map is: 16 => 32 */
1923 LPWAVEHDR wh32
= (LPWAVEHDR
)(dwParam1
);
1924 SEGPTR segwh16
= *(SEGPTR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1925 LPWAVEHDR wh16
= MapSL(segwh16
);
1927 dwParam1
= (DWORD
)segwh16
;
1928 wh16
->dwFlags
= wh32
->dwFlags
;
1930 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1933 ERR("Unknown msg %u\n", uMsg
);
1936 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
1939 #define A(_x,_y) {#_y, _x, \
1940 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1941 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1942 MMDRV_##_y##_Callback, 0, NULL, -1}
1944 /* Note: the indices of this array must match the definitions
1945 * of the MMDRV_???? manifest constants
1947 static WINE_LLTYPE llTypes
[MMDRV_MAX
] = {
1957 /**************************************************************************
1958 * MMDRV_GetNum [internal]
1960 UINT
MMDRV_GetNum(UINT type
)
1962 assert(type
< MMDRV_MAX
);
1963 return llTypes
[type
].wMaxId
;
1966 /**************************************************************************
1967 * WINE_Message [internal]
1969 DWORD
MMDRV_Message(LPWINE_MLD mld
, WORD wMsg
, DWORD dwParam1
,
1970 DWORD dwParam2
, BOOL bFrom32
)
1972 LPWINE_MM_DRIVER lpDrv
;
1974 WINE_MM_DRIVER_PART
* part
;
1975 WINE_LLTYPE
* llType
= &llTypes
[mld
->type
];
1979 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1980 llTypes
[mld
->type
].name
, mld
->uDeviceID
, wMsg
,
1981 mld
->dwDriverInstance
, dwParam1
, dwParam2
, bFrom32
?'Y':'N');
1983 if (mld
->uDeviceID
== (UINT16
)-1) {
1984 if (!llType
->bSupportMapper
) {
1985 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1986 llTypes
[mld
->type
].name
);
1987 return MMSYSERR_BADDEVICEID
;
1991 if (mld
->uDeviceID
>= llType
->wMaxId
) {
1992 WARN("uDev(%u) requested >= max (%d)\n", mld
->uDeviceID
, llType
->wMaxId
);
1993 return MMSYSERR_BADDEVICEID
;
1995 devID
= mld
->uDeviceID
;
1998 lpDrv
= &MMDrvs
[mld
->mmdIndex
];
1999 part
= &lpDrv
->parts
[mld
->type
];
2002 /* some sanity checks */
2003 if (!(part
->nIDMin
<= devID
))
2004 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part
->nIDMin
, devID
);
2005 if (!(devID
< part
->nIDMax
))
2006 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID
, part
->nIDMax
);
2010 assert(part
->u
.fnMessage32
);
2013 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2014 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2015 ret
= part
->u
.fnMessage32(mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2016 TRACE("=> %lu\n", ret
);
2018 map
= llType
->Map16To32A(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
2020 case MMDRV_MAP_NOMEM
:
2021 ret
= MMSYSERR_NOMEM
;
2023 case MMDRV_MAP_MSGERROR
:
2024 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg
);
2025 ret
= MMSYSERR_ERROR
;
2028 case MMDRV_MAP_OKMEM
:
2029 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2030 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2031 ret
= part
->u
.fnMessage32(mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
,
2032 dwParam1
, dwParam2
);
2033 TRACE("=> %lu\n", ret
);
2034 if (map
== MMDRV_MAP_OKMEM
)
2035 llType
->UnMap16To32A(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
2038 case MMDRV_MAP_PASS
:
2039 FIXME("NIY: pass used ?\n");
2040 ret
= MMSYSERR_NOTSUPPORTED
;
2045 assert(part
->u
.fnMessage16
);
2048 map
= llType
->Map32ATo16(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
2050 case MMDRV_MAP_NOMEM
:
2051 ret
= MMSYSERR_NOMEM
;
2053 case MMDRV_MAP_MSGERROR
:
2054 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg
);
2055 ret
= MMSYSERR_ERROR
;
2058 case MMDRV_MAP_OKMEM
:
2059 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2060 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2061 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
, mld
->uDeviceID
,
2062 wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2063 TRACE("=> %lu\n", ret
);
2064 if (map
== MMDRV_MAP_OKMEM
)
2065 llType
->UnMap32ATo16(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
2068 case MMDRV_MAP_PASS
:
2069 FIXME("NIY: pass used ?\n");
2070 ret
= MMSYSERR_NOTSUPPORTED
;
2074 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
2075 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2076 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
, mld
->uDeviceID
,
2077 wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
2078 TRACE("=> %lu\n", ret
);
2084 /**************************************************************************
2085 * MMDRV_Alloc [internal]
2087 LPWINE_MLD
MMDRV_Alloc(UINT size
, UINT type
, LPHANDLE hndl
, DWORD
* dwFlags
,
2088 DWORD
* dwCallback
, DWORD
* dwInstance
, BOOL bFrom32
)
2092 mld
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
2093 if (!mld
) return NULL
;
2095 /* find an empty slot in MM_MLDrvs table */
2096 for (*hndl
= 0; *hndl
< MAX_MM_MLDRVS
; (*hndl
)++) {
2097 if (!MM_MLDrvs
[*hndl
]) break;
2099 if (*hndl
== MAX_MM_MLDRVS
) {
2100 /* the MM_MLDrvs table could be made growable in the future if needed */
2101 ERR("Too many open drivers\n");
2104 MM_MLDrvs
[*hndl
] = mld
;
2108 if ((UINT
)*hndl
< MMDRV_GetNum(type
) || HIWORD(*hndl
) != 0) {
2109 /* FIXME: those conditions must be fulfilled so that:
2110 * - we can distinguish between device IDs and handles
2111 * - we can use handles as 16 or 32 bit entities
2113 ERR("Shouldn't happen. Bad allocation scheme\n");
2116 mld
->bFrom32
= bFrom32
;
2117 mld
->dwFlags
= HIWORD(*dwFlags
);
2118 mld
->dwCallback
= *dwCallback
;
2119 mld
->dwClientInstance
= *dwInstance
;
2121 *dwFlags
= LOWORD(*dwFlags
) | CALLBACK_FUNCTION
;
2122 *dwCallback
= (DWORD
)llTypes
[type
].Callback
;
2123 *dwInstance
= (DWORD
)mld
; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2128 /**************************************************************************
2129 * MMDRV_Free [internal]
2131 void MMDRV_Free(HANDLE hndl
, LPWINE_MLD mld
)
2133 if (hndl
& 0x8000) {
2134 unsigned idx
= hndl
& ~0x8000;
2135 if (idx
< sizeof(MM_MLDrvs
) / sizeof(MM_MLDrvs
[0])) {
2136 MM_MLDrvs
[idx
] = NULL
;
2137 HeapFree(GetProcessHeap(), 0, mld
);
2141 ERR("Bad Handle %08x at %p (not freed)\n", hndl
, mld
);
2144 /**************************************************************************
2145 * MMDRV_Open [internal]
2147 DWORD
MMDRV_Open(LPWINE_MLD mld
, UINT wMsg
, DWORD dwParam1
, DWORD dwFlags
)
2149 DWORD dwRet
= MMSYSERR_BADDEVICEID
;
2151 WINE_LLTYPE
* llType
= &llTypes
[mld
->type
];
2153 mld
->dwDriverInstance
= (DWORD
)&dwInstance
;
2155 if (mld
->uDeviceID
== (UINT
)-1 || mld
->uDeviceID
== (UINT16
)-1) {
2156 TRACE("MAPPER mode requested !\n");
2157 /* check if mapper is supported by type */
2158 if (llType
->bSupportMapper
) {
2159 if (llType
->nMapper
== -1) {
2160 /* no driver for mapper has been loaded, try a dumb implementation */
2161 TRACE("No mapper loaded, doing it by hand\n");
2162 for (mld
->uDeviceID
= 0; mld
->uDeviceID
< llType
->wMaxId
; mld
->uDeviceID
++) {
2163 if ((dwRet
= MMDRV_Open(mld
, wMsg
, dwParam1
, dwFlags
)) == MMSYSERR_NOERROR
) {
2164 /* to share this function epilog */
2165 dwInstance
= mld
->dwDriverInstance
;
2170 mld
->uDeviceID
= (UINT16
)-1;
2171 mld
->mmdIndex
= llType
->lpMlds
[-1].mmdIndex
;
2172 TRACE("Setting mmdIndex to %u\n", mld
->mmdIndex
);
2173 dwRet
= MMDRV_Message(mld
, wMsg
, dwParam1
, dwFlags
, TRUE
);
2177 if (mld
->uDeviceID
< llType
->wMaxId
) {
2178 mld
->mmdIndex
= llType
->lpMlds
[mld
->uDeviceID
].mmdIndex
;
2179 TRACE("Setting mmdIndex to %u\n", mld
->mmdIndex
);
2180 dwRet
= MMDRV_Message(mld
, wMsg
, dwParam1
, dwFlags
, TRUE
);
2183 if (dwRet
== MMSYSERR_NOERROR
)
2184 mld
->dwDriverInstance
= dwInstance
;
2188 /**************************************************************************
2189 * MMDRV_Close [internal]
2191 DWORD
MMDRV_Close(LPWINE_MLD mld
, UINT wMsg
)
2193 return MMDRV_Message(mld
, wMsg
, 0L, 0L, TRUE
);
2196 /**************************************************************************
2197 * MMDRV_GetByID [internal]
2199 LPWINE_MLD
MMDRV_GetByID(UINT uDevID
, UINT type
)
2201 if (uDevID
< llTypes
[type
].wMaxId
)
2202 return &llTypes
[type
].lpMlds
[uDevID
];
2203 if ((uDevID
== (UINT16
)-1 || uDevID
== (UINT
)-1) && llTypes
[type
].nMapper
!= -1)
2204 return &llTypes
[type
].lpMlds
[-1];
2208 /**************************************************************************
2209 * MMDRV_Get [internal]
2211 LPWINE_MLD
MMDRV_Get(HANDLE hndl
, UINT type
, BOOL bCanBeID
)
2213 LPWINE_MLD mld
= NULL
;
2215 assert(type
< MMDRV_MAX
);
2217 if ((UINT
)hndl
>= llTypes
[type
].wMaxId
) {
2218 if (hndl
& 0x8000) {
2220 if (hndl
< sizeof(MM_MLDrvs
) / sizeof(MM_MLDrvs
[0])) {
2221 mld
= MM_MLDrvs
[hndl
];
2222 if (!mld
|| !HeapValidate(GetProcessHeap(), 0, mld
) || mld
->type
!= type
)
2227 if (mld
== NULL
&& bCanBeID
) {
2228 mld
= MMDRV_GetByID((UINT
)hndl
, type
);
2233 /**************************************************************************
2234 * MMDRV_GetRelated [internal]
2236 LPWINE_MLD
MMDRV_GetRelated(HANDLE hndl
, UINT srcType
,
2237 BOOL bSrcCanBeID
, UINT dstType
)
2241 if ((mld
= MMDRV_Get(hndl
, srcType
, bSrcCanBeID
)) != NULL
) {
2242 WINE_MM_DRIVER_PART
* part
= &MMDrvs
[mld
->mmdIndex
].parts
[dstType
];
2243 if (part
->nIDMin
< part
->nIDMax
)
2244 return MMDRV_GetByID(part
->nIDMin
, dstType
);
2249 /**************************************************************************
2250 * MMDRV_PhysicalFeatures [internal]
2252 UINT
MMDRV_PhysicalFeatures(LPWINE_MLD mld
, UINT uMsg
, DWORD dwParam1
,
2255 WINE_MM_DRIVER
* lpDrv
= &MMDrvs
[mld
->mmdIndex
];
2257 TRACE("(%p, %04x, %08lx, %08lx)\n", mld
, uMsg
, dwParam1
, dwParam2
);
2259 /* all those function calls are undocumented */
2261 case 0x801: /* DRV_QUERYDRVENTRY */
2262 lstrcpynA((LPSTR
)dwParam1
, lpDrv
->name
, LOWORD(dwParam2
));
2264 case 0x802: /* DRV_QUERYDEVNODE */
2265 *(LPDWORD
)dwParam1
= 0L; /* should be DevNode */
2267 case 0x803: /* DRV_QUERYNAME */
2268 WARN("NIY 0x803\n");
2270 case 0x804: /* DRV_QUERYDRIVERIDS */
2271 WARN("NIY call VxD\n");
2272 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2273 * dwParam1 is buffer and dwParam2 is sizeof buffer
2274 * I don't know where the result is stored though
2277 case 0x805: /* DRV_QUERYMAPPABLE */
2278 return (lpDrv
->bIsMapper
) ? 2 : 0;
2280 case 0x810: /* Wine-specific: Retrieve DirectSound interface */
2281 return MMDRV_Message(mld
, uMsg
, dwParam1
, dwParam2
, TRUE
);
2284 WARN("Unknown call %04x\n", uMsg
);
2285 return MMSYSERR_INVALPARAM
;
2290 /**************************************************************************
2291 * MMDRV_InitPerType [internal]
2293 static BOOL
MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv
, UINT num
,
2294 UINT type
, UINT wMsg
)
2296 WINE_MM_DRIVER_PART
* part
= &lpDrv
->parts
[type
];
2301 part
->nIDMin
= part
->nIDMax
= 0;
2303 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2304 /* the DRVM_ENABLE is only required when the PnP node is non zero */
2306 if (lpDrv
->bIs32
&& part
->u
.fnMessage32
) {
2307 ret
= part
->u
.fnMessage32(0, DRVM_INIT
, 0L, 0L, 0L);
2308 TRACE("DRVM_INIT => %08lx\n", ret
);
2310 ret
= part
->u
.fnMessage32(0, DRVM_ENABLE
, 0L, 0L, 0L);
2311 TRACE("DRVM_ENABLE => %08lx\n", ret
);
2313 count
= part
->u
.fnMessage32(0, wMsg
, 0L, 0L, 0L);
2314 } else if (!lpDrv
->bIs32
&& part
->u
.fnMessage16
) {
2315 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2316 0, DRVM_INIT
, 0L, 0L, 0L);
2317 TRACE("DRVM_INIT => %08lx\n", ret
);
2319 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2320 0, DRVM_ENABLE
, 0L, 0L, 0L);
2321 TRACE("DRVM_ENABLE => %08lx\n", ret
);
2323 count
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2324 0, wMsg
, 0L, 0L, 0L);
2329 TRACE("Got %u dev for (%s:%s)\n", count
, lpDrv
->name
, llTypes
[type
].name
);
2331 /* got some drivers */
2332 if (lpDrv
->bIsMapper
) {
2333 /* it seems native mappers return 0 devices :-( */
2334 if (llTypes
[type
].nMapper
!= -1)
2335 ERR("Two mappers for type %s (%d, %s)\n",
2336 llTypes
[type
].name
, llTypes
[type
].nMapper
, lpDrv
->name
);
2338 ERR("Strange: mapper with %d > 1 devices\n", count
);
2339 llTypes
[type
].nMapper
= num
;
2343 part
->nIDMin
= llTypes
[type
].wMaxId
;
2344 llTypes
[type
].wMaxId
+= count
;
2345 part
->nIDMax
= llTypes
[type
].wMaxId
;
2347 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2348 part
->nIDMin
, part
->nIDMax
, llTypes
[type
].wMaxId
,
2349 lpDrv
->name
, llTypes
[type
].name
);
2350 /* realloc translation table */
2351 llTypes
[type
].lpMlds
= (LPWINE_MLD
)
2352 HeapReAlloc(GetProcessHeap(), 0, (llTypes
[type
].lpMlds
) ? llTypes
[type
].lpMlds
- 1 : NULL
,
2353 sizeof(WINE_MLD
) * (llTypes
[type
].wMaxId
+ 1)) + 1;
2354 /* re-build the translation table */
2355 if (llTypes
[type
].nMapper
!= -1) {
2356 TRACE("%s:Trans[%d] -> %s\n", llTypes
[type
].name
, -1, MMDrvs
[llTypes
[type
].nMapper
].name
);
2357 llTypes
[type
].lpMlds
[-1].uDeviceID
= (UINT16
)-1;
2358 llTypes
[type
].lpMlds
[-1].type
= type
;
2359 llTypes
[type
].lpMlds
[-1].mmdIndex
= llTypes
[type
].nMapper
;
2360 llTypes
[type
].lpMlds
[-1].dwDriverInstance
= 0;
2362 for (i
= k
= 0; i
<= num
; i
++) {
2363 while (MMDrvs
[i
].parts
[type
].nIDMin
<= k
&& k
< MMDrvs
[i
].parts
[type
].nIDMax
) {
2364 TRACE("%s:Trans[%d] -> %s\n", llTypes
[type
].name
, k
, MMDrvs
[i
].name
);
2365 llTypes
[type
].lpMlds
[k
].uDeviceID
= k
;
2366 llTypes
[type
].lpMlds
[k
].type
= type
;
2367 llTypes
[type
].lpMlds
[k
].mmdIndex
= i
;
2368 llTypes
[type
].lpMlds
[k
].dwDriverInstance
= 0;
2375 /**************************************************************************
2376 * MMDRV_Install [internal]
2378 static BOOL
MMDRV_Install(LPCSTR name
, int num
, BOOL bIsMapper
)
2382 LPWINE_MM_DRIVER lpDrv
= &MMDrvs
[num
];
2385 TRACE("('%s');\n", name
);
2387 memset(lpDrv
, 0, sizeof(*lpDrv
));
2389 if (!(lpDrv
->hDriver
= OpenDriverA(name
, 0, 0))) {
2390 WARN("Couldn't open driver '%s'\n", name
);
2394 d
= DRIVER_FindFromHDrvr(lpDrv
->hDriver
);
2395 lpDrv
->bIs32
= (d
->dwFlags
& WINE_GDF_16BIT
) ? FALSE
: TRUE
;
2397 /* Then look for xxxMessage functions */
2398 #define AA(_h,_w,_x,_y,_z) \
2399 func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
2401 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2402 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2405 WINEMM_msgFunc32 func
;
2407 if (d
->d
.d32
.hModule
) {
2408 #define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
2409 A(MMDRV_AUX
, auxMessage
);
2410 A(MMDRV_MIXER
, mixMessage
);
2411 A(MMDRV_MIDIIN
, midMessage
);
2412 A(MMDRV_MIDIOUT
, modMessage
);
2413 A(MMDRV_WAVEIN
, widMessage
);
2414 A(MMDRV_WAVEOUT
, wodMessage
);
2418 WINEMM_msgFunc16 func
;
2421 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2422 * The beginning of the module description indicates the driver supports
2423 * waveform, auxiliary, and mixer devices. Use one of the following
2424 * device-type names, followed by a colon (:) to indicate the type of
2425 * device your driver supports. If the driver supports more than one
2426 * type of device, separate each device-type name with a comma (,).
2428 * wave for waveform audio devices
2429 * wavemapper for wave mappers
2430 * midi for MIDI audio devices
2431 * midimapper for midi mappers
2432 * aux for auxiliary audio devices
2433 * mixer for mixer devices
2436 if (d
->d
.d16
.hDriver16
) {
2437 HMODULE16 hMod16
= GetDriverModuleHandle16(d
->d
.d16
.hDriver16
);
2439 #define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16)
2440 A(MMDRV_AUX
, auxMessage
);
2441 A(MMDRV_MIXER
, mixMessage
);
2442 A(MMDRV_MIDIIN
, midMessage
);
2443 A(MMDRV_MIDIOUT
, modMessage
);
2444 A(MMDRV_WAVEIN
, widMessage
);
2445 A(MMDRV_WAVEOUT
, wodMessage
);
2451 if (TRACE_ON(mmsys
)) {
2452 if ((lpDrv
->bIs32
) ? MMDRV_GetDescription32(name
, buffer
, sizeof(buffer
)) :
2453 MMDRV_GetDescription16(name
, buffer
, sizeof(buffer
)))
2454 TRACE("%s => %s\n", name
, buffer
);
2456 TRACE("%s => No description\n", name
);
2460 CloseDriver(lpDrv
->hDriver
, 0, 0);
2461 WARN("No message functions found\n");
2465 /* FIXME: being a mapper or not should be known by another way */
2466 /* it's known for NE drvs (the description is of the form '*mapper: *'
2467 * I don't have any clue for PE drvs
2468 * on Win 9x, the value is gotten from the key mappable under
2469 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\MediaResources\
2471 lpDrv
->bIsMapper
= bIsMapper
;
2472 lpDrv
->name
= HEAP_strdupA(GetProcessHeap(), 0, name
);
2474 /* Finish init and get the count of the devices */
2475 MMDRV_InitPerType(lpDrv
, num
, MMDRV_AUX
, AUXDM_GETNUMDEVS
);
2476 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIXER
, MXDM_GETNUMDEVS
);
2477 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIDIIN
, MIDM_GETNUMDEVS
);
2478 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIDIOUT
, MODM_GETNUMDEVS
);
2479 MMDRV_InitPerType(lpDrv
, num
, MMDRV_WAVEIN
, WIDM_GETNUMDEVS
);
2480 MMDRV_InitPerType(lpDrv
, num
, MMDRV_WAVEOUT
, WODM_GETNUMDEVS
);
2481 /* FIXME: if all those func calls return FALSE, then the driver must be unloaded */
2485 /**************************************************************************
2486 * MMDRV_Init [internal]
2488 BOOL
MMDRV_Init(void)
2492 /* FIXME: this should be moved to init files;
2493 * - either .winerc/wine.conf
2494 * - or made of registry keys
2495 * this is a temporary hack, shall be removed anytime now
2497 /* first load hardware drivers */
2498 if (MMDRV_Install("wineoss.drv", num
, FALSE
)) num
++;
2500 /* finish with mappers */
2501 if (MMDRV_Install("msacm.drv", num
, TRUE
)) num
++;
2502 if (MMDRV_Install("midimap.drv", num
, TRUE
)) num
++;
2504 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2505 * if not just increase size of MMDrvs */
2506 assert(num
<= sizeof(MMDrvs
)/sizeof(MMDrvs
[0]));