1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * MMSYTEM low level drivers handling functions
6 * Copyright 1999 Eric Pouech
12 #include "user.h" /* should be removed asap; used in MMDRV_(Get|Alloc|Free) */
13 #include "selectors.h"
18 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(mmsys
)
22 typedef DWORD
CALLBACK (*WINEMM_msgFunc16
)(UINT16
, WORD
, DWORD
, DWORD
, DWORD
);
23 typedef DWORD
CALLBACK (*WINEMM_msgFunc32
)(UINT
, UINT
, DWORD
, DWORD
, DWORD
);
25 /* for each loaded driver and each known type of driver, this structure contains
26 * the information needed to access it
28 typedef struct tagWINE_MM_DRIVER_PART
{
29 int nIDMin
; /* lower bound of global indexes for this type */
30 int nIDMax
; /* hhigher bound of global indexes for this type */
32 WINEMM_msgFunc32 fnMessage32
; /* pointer to fonction */
33 WINEMM_msgFunc16 fnMessage16
;
35 } WINE_MM_DRIVER_PART
;
37 /* each low-level .drv will be associated with an instance of this structure */
38 typedef struct tagWINE_MM_DRIVER
{
39 HDRVR hDrvr
; /* handle of loader driver */
40 LPSTR name
; /* name of the driver */
41 BOOL bIs32
: 1, /* TRUE if 32 bit driver, FALSE for 16 */
42 bIsMapper
: 1; /* TRUE if mapper */
43 WINE_MM_DRIVER_PART parts
[MMDRV_MAX
];/* Information for all known types */
44 } WINE_MM_DRIVER
, *LPWINE_MM_DRIVER
;
47 MMDRV_MAP_NOMEM
, /* ko, memory problem */
48 MMDRV_MAP_MSGERROR
, /* ko, unknown message */
49 MMDRV_MAP_OK
, /* ok, no memory allocated. to be sent to the proc. */
50 MMDRV_MAP_OKMEM
, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
51 MMDRV_MAP_PASS
/* not handled (no memory allocated) to be sent to the driver */
54 typedef MMDRV_MapType (*MMDRV_MAPFUNC
)(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
);
56 /* each known type of driver has an instance of this structure */
57 typedef struct tagWINE_LLTYPE
{
58 /* those attributes depend on the specification of the type */
59 LPSTR name
; /* name (for debugging) */
60 BOOL bSupportMapper
; /* if type is allowed to support mapper */
61 MMDRV_MAPFUNC Map16To32A
; /* those are function pointers to handle */
62 MMDRV_MAPFUNC UnMap16To32A
; /* the parameter conversion (16 vs 32 bit) */
63 MMDRV_MAPFUNC Map32ATo16
; /* when hi-func (in mmsystem or winmm) and */
64 MMDRV_MAPFUNC UnMap32ATo16
; /* low-func (in .drv) do not match */
65 LPDRVCALLBACK Callback
; /* handles callback for a specified type */
66 /* those attributes reflect the loaded/current situation for the type */
67 UINT wMaxId
; /* number of loaded devices (sum across all loaded drivers */
68 LPWINE_MLD lpMlds
; /* "static" mlds to access the part though device IDs */
69 int nMapper
; /* index to mapper */
72 static WINE_MM_DRIVER MMDrvs
[3];
74 /* ### start build ### */
75 extern WORD CALLBACK
MMDRV_CallTo16_word_wwlll(FARPROC16
,WORD
,WORD
,LONG
,LONG
,LONG
);
76 /* ### stop build ### */
78 /**************************************************************************
79 * MMDRV_GetDescription16 [internal]
81 static BOOL
MMDRV_GetDescription16(const char* fname
, char* buf
, int buflen
)
89 if ((hFile
= OpenFile(fname
, &ofs
, OF_READ
| OF_SHARE_DENY_WRITE
)) == HFILE_ERROR
) {
90 ERR("Can't open file %s\n", fname
);
94 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
96 if (_lread(hFile
, &w
, 2) != 2) E(("Can't read sig\n"));
97 if (w
!= ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w
));
98 if (_llseek(hFile
, 0x3C, SEEK_SET
) < 0) E(("Can't seek to ext header offset\n"));
99 if (_lread(hFile
, &dw
, 4) != 4) E(("Can't read ext header offset\n"));
100 if (_llseek(hFile
, dw
+ 0x2C, SEEK_SET
) < 0) E(("Can't seek to ext header.nr table %lu\n", dw
+0x2C));
101 if (_lread(hFile
, &dw
, 4) != 4) E(("Can't read nr table offset\n"));
102 if (_llseek(hFile
, dw
, SEEK_SET
) < 0) E(("Can't seek to nr table %lu\n", dw
));
103 if (_lread(hFile
, buf
, 1) != 1) E(("Can't read descr length\n"));
104 buflen
= MIN((BYTE
)buf
[0], buflen
- 1);
105 if (_lread(hFile
, buf
, buflen
) != buflen
) E(("Can't read descr (%d)\n", buflen
));
108 TRACE("Got '%s' [%d]\n", buf
, buflen
);
114 /**************************************************************************
115 * MMDRV_GetDescription32 [internal]
117 static BOOL
MMDRV_GetDescription32(const char* fname
, char* buf
, int buflen
)
126 FARPROC pGetFileVersionInfoSizeA
;
127 FARPROC pGetFileVersionInfoA
;
128 FARPROC pVerQueryValueA
;
131 #define E(_x) do {TRACE _x;goto theEnd;} while(0)
133 if (OpenFile(fname
, &ofs
, OF_EXIST
)==HFILE_ERROR
) E(("Can't find file %s\n", fname
));
135 if (!(hmodule
= LoadLibraryA( "version.dll" ))) goto theEnd
;
136 if (!(pGetFileVersionInfoSizeA
= GetProcAddress( hmodule
, "GetFileVersionInfoSizeA" )))
138 if (!(pGetFileVersionInfoA
= GetProcAddress( hmodule
, "GetFileVersionInfoA" )))
140 if (!(pVerQueryValueA
= GetProcAddress( hmodule
, "pVerQueryValueA" )))
143 if (!(dw
= pGetFileVersionInfoSizeA(ofs
.szPathName
, &h
))) E(("Can't get FVIS\n"));
144 if (!(ptr
= HeapAlloc(GetProcessHeap(), 0, dw
))) E(("OOM\n"));
145 if (!pGetFileVersionInfoA(ofs
.szPathName
, h
, dw
, ptr
)) E(("Can't get FVI\n"));
147 #define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
148 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
164 if (!pVerQueryValueA(ptr
, "\\StringFileInfo\\040904B0\\ProductName", &val
, &u
)) E(("Can't get product name\n"));
165 lstrcpynA(buf
, val
, buflen
);
170 HeapFree(GetProcessHeap(), 0, ptr
);
171 if (hmodule
) FreeLibrary( hmodule
);
175 /**************************************************************************
176 * MMDRV_Callback [internal]
178 static void MMDRV_Callback(LPWINE_MLD mld
, HDRVR hDev
, UINT uMsg
, DWORD dwParam1
, DWORD dwParam2
)
180 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
181 mld
->dwCallback
, hDev
, uMsg
, mld
->dwClientInstance
, dwParam1
, dwParam2
);
183 if (!mld
->bFrom32
&& (mld
->dwFlags
& DCB_TYPEMASK
) == DCB_FUNCTION
) {
184 /* 16 bit func, call it */
185 TRACE("Function (16 bit) !\n");
186 MMDRV_CallTo16_word_wwlll((FARPROC16
)mld
->dwCallback
, hDev
, uMsg
,
187 mld
->dwClientInstance
, dwParam1
, dwParam2
);
189 DriverCallback(mld
->dwCallback
, mld
->dwFlags
, hDev
, uMsg
,
190 mld
->dwClientInstance
, dwParam1
, dwParam2
);
194 /* =================================
195 * A U X M A P P E R S
196 * ================================= */
198 /**************************************************************************
199 * MMDRV_Aux_Map16To32A [internal]
201 static MMDRV_MapType
MMDRV_Aux_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
203 return MMDRV_MAP_MSGERROR
;
206 /**************************************************************************
207 * MMDRV_Aux_UnMap16To32A [internal]
209 static MMDRV_MapType
MMDRV_Aux_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
211 return MMDRV_MAP_MSGERROR
;
214 /**************************************************************************
215 * MMDRV_Aux_Map32ATo16 [internal]
217 static MMDRV_MapType
MMDRV_Aux_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
219 return MMDRV_MAP_MSGERROR
;
222 /**************************************************************************
223 * MMDRV_Aux_UnMap32ATo16 [internal]
225 static MMDRV_MapType
MMDRV_Aux_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
228 case AUXDM_GETDEVCAPS
:
229 lpCaps
->wMid
= ac16
.wMid
;
230 lpCaps
->wPid
= ac16
.wPid
;
231 lpCaps
->vDriverVersion
= ac16
.vDriverVersion
;
232 strcpy(lpCaps
->szPname
, ac16
.szPname
);
233 lpCaps
->wTechnology
= ac16
.wTechnology
;
234 lpCaps
->dwSupport
= ac16
.dwSupport
;
236 return MMDRV_MAP_MSGERROR
;
239 /**************************************************************************
240 * MMDRV_Aux_Callback [internal]
242 static void CALLBACK
MMDRV_Aux_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
244 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
247 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
250 /* =================================
251 * M I X E R M A P P E R S
252 * ================================= */
254 /**************************************************************************
255 * xMMDRV_Mixer_Map16To32A [internal]
257 static MMDRV_MapType
MMDRV_Mixer_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
259 return MMDRV_MAP_MSGERROR
;
262 /**************************************************************************
263 * MMDRV_Mixer_UnMap16To32A [internal]
265 static MMDRV_MapType
MMDRV_Mixer_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
269 UINT ret
= mixerGetDevCapsA(devid
, &micA
, sizeof(micA
));
271 if (ret
== MMSYSERR_NOERROR
) {
272 mixcaps
->wMid
= micA
.wMid
;
273 mixcaps
->wPid
= micA
.wPid
;
274 mixcaps
->vDriverVersion
= micA
.vDriverVersion
;
275 strcpy(mixcaps
->szPname
, micA
.szPname
);
276 mixcaps
->fdwSupport
= micA
.fdwSupport
;
277 mixcaps
->cDestinations
= micA
.cDestinations
;
281 return MMDRV_MAP_MSGERROR
;
284 /**************************************************************************
285 * MMDRV_Mixer_Map32ATo16 [internal]
287 static MMDRV_MapType
MMDRV_Mixer_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
289 return MMDRV_MAP_MSGERROR
;
292 /**************************************************************************
293 * MMDRV_Mixer_UnMap32ATo16 [internal]
295 static MMDRV_MapType
MMDRV_Mixer_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
297 return MMDRV_MAP_MSGERROR
;
300 /**************************************************************************
301 * MMDRV_Mixer_Callback [internal]
303 static void CALLBACK
MMDRV_Mixer_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
305 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
308 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
311 /* =================================
312 * M I D I I N M A P P E R S
313 * ================================= */
315 /**************************************************************************
316 * MMDRV_MidiIn_Map16To32A [internal]
318 static MMDRV_MapType
MMDRV_MidiIn_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
320 return MMDRV_MAP_MSGERROR
;
323 /**************************************************************************
324 * MMDRV_MidiIn_UnMap16To32A [internal]
326 static MMDRV_MapType
MMDRV_MidiIn_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
328 return MMDRV_MAP_MSGERROR
;
331 /**************************************************************************
332 * MMDRV_MidiIn_Map32ATo16 [internal]
334 static MMDRV_MapType
MMDRV_MidiIn_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
336 return MMDRV_MAP_MSGERROR
;
339 /**************************************************************************
340 * MMDRV_MidiIn_UnMap32ATo16 [internal]
342 static MMDRV_MapType
MMDRV_MidiIn_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
344 return MMDRV_MAP_MSGERROR
;
347 /**************************************************************************
348 * MMDRV_MidiIn_Callback [internal]
350 static void CALLBACK
MMDRV_MidiIn_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
352 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
357 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
362 /* dwParam1 & dwParam2 are are data, nothing to do */
366 /* dwParam1 points to a MidiHdr, work to be done !!! */
367 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
368 /* initial map is: 32 => 16 */
369 LPMIDIHDR mh16
= (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
);
370 LPMIDIHDR mh32
= *(LPMIDIHDR
*)((LPSTR
)mh16
- sizeof(LPMIDIHDR
));
372 dwParam1
= (DWORD
)mh32
;
373 mh32
->dwFlags
= mh16
->dwFlags
;
374 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
375 if (mh32
->reserved
>= sizeof(MIDIHDR
))
376 mh32
->dwOffset
= mh16
->dwOffset
;
377 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
378 /* initial map is: 16 => 32 */
379 LPMIDIHDR mh32
= (LPMIDIHDR
)(dwParam1
);
380 LPMIDIHDR segmh16
= *(LPMIDIHDR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
381 LPMIDIHDR mh16
= PTR_SEG_TO_LIN(segmh16
);
383 dwParam1
= (DWORD
)segmh16
;
384 mh16
->dwFlags
= mh32
->dwFlags
;
385 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
386 if (mh16
->reserved
>= sizeof(MIDIHDR
))
387 mh16
->dwOffset
= mh32
->dwOffset
;
389 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
391 /* case MOM_POSITIONCB: */
393 ERR("Unknown msg %u\n", uMsg
);
396 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
399 /* =================================
400 * M I D I O U T M A P P E R S
401 * ================================= */
403 /**************************************************************************
404 * MMDRV_MidiOut_Map16To32A [internal]
406 static MMDRV_MapType
MMDRV_MidiOut_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
408 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
411 case MODM_GETNUMDEVS
:
421 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
424 case MODM_GETDEVCAPS
:
426 LPMIDIOUTCAPSA moc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16
) + sizeof(MIDIOUTCAPSA
));
427 LPMIDIOUTCAPS16 moc16
= PTR_SEG_TO_LIN(*lpParam1
);
430 *(LPMIDIOUTCAPS16
*)moc32
= moc16
;
431 moc32
= (LPMIDIOUTCAPSA
)((LPSTR
)moc32
+ sizeof(LPMIDIOUTCAPS16
));
432 *lpParam1
= (DWORD
)moc32
;
433 *lpParam2
= sizeof(MIDIOUTCAPSA
);
435 ret
= MMDRV_MAP_OKMEM
;
437 ret
= MMDRV_MAP_NOMEM
;
443 LPMIDIHDR mh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
));
444 LPMIDIHDR mh16
= PTR_SEG_TO_LIN(*lpParam1
);
447 *(LPMIDIHDR
*)mh32
= (LPMIDIHDR
)*lpParam1
;
448 mh32
= (LPMIDIHDR
)((LPSTR
)mh32
+ sizeof(LPMIDIHDR
));
449 mh32
->lpData
= PTR_SEG_TO_LIN(mh16
->lpData
);
450 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
451 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
452 mh32
->dwUser
= mh16
->dwUser
;
453 mh32
->dwFlags
= mh16
->dwFlags
;
454 /* FIXME: nothing on mh32->lpNext */
455 /* could link the mh32->lpNext at this level for memory house keeping */
456 mh32
->dwOffset
= (*lpParam2
>= sizeof(MIDIHDR
)) ? ((LPMIDIHDR
)mh16
)->dwOffset
: 0;
457 mh16
->lpNext
= mh32
; /* for reuse in unprepare and write */
458 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
459 mh16
->reserved
= *lpParam2
;
460 *lpParam1
= (DWORD
)mh32
;
461 *lpParam2
= sizeof(MIDIHDR
);
463 ret
= MMDRV_MAP_OKMEM
;
465 ret
= MMDRV_MAP_NOMEM
;
472 LPMIDIHDR mh16
= PTR_SEG_TO_LIN(*lpParam1
);
473 LPMIDIHDR mh32
= (LPMIDIHDR
)mh16
->lpNext
;
475 *lpParam1
= (DWORD
)mh32
;
476 *lpParam2
= sizeof(MIDIHDR
);
477 /* dwBufferLength can be reduced between prepare & write */
478 if (mh32
->dwBufferLength
< mh16
->dwBufferLength
) {
479 ERR("Size of buffer has been increased (%ld, %ld)\n",
480 mh32
->dwBufferLength
, mh16
->dwBufferLength
);
481 return MMDRV_MAP_MSGERROR
;
483 mh32
->dwBufferLength
= mh16
->dwBufferLength
;
484 ret
= MMDRV_MAP_OKMEM
;
488 case MODM_CACHEPATCHES
:
489 case MODM_CACHEDRUMPATCHES
:
491 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
497 /**************************************************************************
498 * MMDRV_MidiOut_UnMap16To32A [internal]
500 static MMDRV_MapType
MMDRV_MidiOut_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
502 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
505 case MODM_GETNUMDEVS
:
515 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
518 case MODM_GETDEVCAPS
:
520 LPMIDIOUTCAPSA moc32
= (LPMIDIOUTCAPSA
)(*lpParam1
);
521 LPMIDIOUTCAPS16 moc16
= *(LPMIDIOUTCAPS16
*)((LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
523 moc16
->wMid
= moc32
->wMid
;
524 moc16
->wPid
= moc32
->wPid
;
525 moc16
->vDriverVersion
= moc32
->vDriverVersion
;
526 strcpy(moc16
->szPname
, moc32
->szPname
);
527 moc16
->wTechnology
= moc32
->wTechnology
;
528 moc16
->wVoices
= moc32
->wVoices
;
529 moc16
->wNotes
= moc32
->wNotes
;
530 moc16
->wChannelMask
= moc32
->wChannelMask
;
531 moc16
->dwSupport
= moc32
->dwSupport
;
532 HeapFree(GetProcessHeap(), 0, (LPSTR
)moc32
- sizeof(LPMIDIOUTCAPS16
));
540 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
541 LPMIDIHDR mh16
= PTR_SEG_TO_LIN(*(LPMIDIHDR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
)));
543 assert(mh16
->lpNext
== mh32
);
544 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
545 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
546 mh16
->dwUser
= mh32
->dwUser
;
547 mh16
->dwFlags
= mh32
->dwFlags
;
548 if (mh16
->reserved
>= sizeof(MIDIHDR
))
549 mh16
->dwOffset
= mh32
->dwOffset
;
551 if (wMsg
== MODM_UNPREPARE
) {
552 HeapFree(GetProcessHeap(), 0, (LPSTR
)mh32
- sizeof(LPMIDIHDR
));
559 case MODM_CACHEPATCHES
:
560 case MODM_CACHEDRUMPATCHES
:
562 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
568 /**************************************************************************
569 * MMDRV_MidiOut_Map32ATo16 [internal]
571 static MMDRV_MapType
MMDRV_MidiOut_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
573 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
577 case MODM_GETNUMDEVS
:
583 case MODM_GETDEVCAPS
:
585 LPMIDIOUTCAPSA moc32
= (LPMIDIOUTCAPSA
)*lpParam1
;
586 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMIDIOUTCAPSA
) + sizeof(MIDIOUTCAPS16
));
589 *(LPMIDIOUTCAPSA
*)ptr
= moc32
;
590 ret
= MMDRV_MAP_OKMEM
;
592 ret
= MMDRV_MAP_NOMEM
;
594 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIOUTCAPSA
);
595 *lpParam2
= sizeof(MIDIOUTCAPS16
);
600 LPMIDIHDR mh32
= (LPMIDIHDR
)*lpParam1
;
602 LPVOID ptr
= SEGPTR_ALLOC(sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
) + mh32
->dwBufferLength
);
605 *(LPMIDIHDR
*)ptr
= mh32
;
606 mh16
= (LPMIDIHDR
)((LPSTR
)ptr
+ sizeof(LPMIDIHDR
));
607 mh16
->lpData
= (LPSTR
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
) + sizeof(MIDIHDR
);
608 /* data will be copied on WODM_WRITE */
609 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
610 mh16
->dwBytesRecorded
= mh32
->dwBytesRecorded
;
611 mh16
->dwUser
= mh32
->dwUser
;
612 mh16
->dwFlags
= mh32
->dwFlags
;
613 /* FIXME: nothing on mh32->lpNext */
614 /* could link the mh32->lpNext at this level for memory house keeping */
615 mh16
->dwOffset
= (*lpParam2
>= sizeof(MIDIHDR
)) ? mh32
->dwOffset
: 0;
617 mh32
->lpNext
= (LPMIDIHDR
)mh16
; /* for reuse in unprepare and write */
618 mh32
->reserved
= *lpParam2
;
620 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
621 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
), (DWORD
)mh16
->lpData
,
622 mh32
->dwBufferLength
, (DWORD
)mh32
->lpData
);
623 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
);
624 *lpParam2
= sizeof(MIDIHDR
);
626 ret
= MMDRV_MAP_OKMEM
;
628 ret
= MMDRV_MAP_NOMEM
;
635 LPMIDIHDR mh32
= (LPMIDIHDR
)(*lpParam1
);
636 LPMIDIHDR mh16
= (LPMIDIHDR
)mh32
->lpNext
;
637 LPSTR ptr
= (LPSTR
)mh16
- sizeof(LPMIDIHDR
);
639 assert(*(LPMIDIHDR
*)ptr
== mh32
);
641 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
642 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
), (DWORD
)mh16
->lpData
,
643 mh32
->dwBufferLength
, (DWORD
)mh32
->lpData
);
645 if (wMsg
== MODM_LONGDATA
)
646 memcpy((LPSTR
)mh16
+ sizeof(MIDIHDR
), mh32
->lpData
, mh32
->dwBufferLength
);
648 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIHDR
);
649 *lpParam2
= sizeof(MIDIHDR
);
650 /* dwBufferLength can be reduced between prepare & write */
651 if (mh16
->dwBufferLength
< mh32
->dwBufferLength
) {
652 ERR("Size of buffer has been increased (%ld, %ld)\n",
653 mh16
->dwBufferLength
, mh32
->dwBufferLength
);
654 return MMDRV_MAP_MSGERROR
;
656 mh16
->dwBufferLength
= mh32
->dwBufferLength
;
657 ret
= MMDRV_MAP_OKMEM
;
662 LPMIDIOPENDESC mod32
= (LPMIDIOPENDESC
)*lpParam1
;
664 LPMIDIOPENDESC16 mod16
;
666 /* allocated data are mapped as follows:
667 LPMIDIOPENDESC ptr to orig lParam1
668 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
669 DWORD dwUser passed to driver
670 MIDIOPENDESC16 mod16: openDesc passed to driver
673 ptr
= SEGPTR_ALLOC(sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
) + sizeof(MIDIOPENDESC16
) +
674 mod32
->cIds
? (mod32
->cIds
- 1) * sizeof(MIDIOPENSTRMID
) : 0);
677 *(LPMIDIOPENDESC
*)ptr
= mod32
;
678 *(LPDWORD
)(ptr
+ sizeof(LPMIDIOPENDESC
)) = *lpdwUser
;
679 mod16
= (LPMIDIOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
));
681 mod16
->hMidi
= mod32
->hMidi
;
682 mod16
->dwCallback
= mod32
->dwCallback
;
683 mod16
->dwInstance
= mod32
->dwInstance
;
684 mod16
->dnDevNode
= mod32
->dnDevNode
;
685 mod16
->cIds
= mod32
->cIds
;
686 memcpy(&mod16
->rgIds
, &mod32
->rgIds
, mod32
->cIds
* sizeof(MIDIOPENSTRMID
));
688 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIOPENDESC
) + 2*sizeof(DWORD
);
689 *lpdwUser
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMIDIOPENDESC
) + sizeof(DWORD
);
691 ret
= MMDRV_MAP_OKMEM
;
693 ret
= MMDRV_MAP_NOMEM
;
698 case MODM_CACHEPATCHES
:
699 case MODM_CACHEDRUMPATCHES
:
701 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
707 /**************************************************************************
708 * MMDRV_MidiOut_UnMap32ATo16 [internal]
710 static MMDRV_MapType
MMDRV_MidiOut_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
712 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
716 case MODM_GETNUMDEVS
:
722 case MODM_GETDEVCAPS
:
724 LPMIDIOUTCAPS16 moc16
= (LPMIDIOUTCAPS16
)PTR_SEG_TO_LIN(*lpParam1
);
725 LPSTR ptr
= (LPSTR
)moc16
- sizeof(LPMIDIOUTCAPSA
);
726 LPMIDIOUTCAPSA moc32
= *(LPMIDIOUTCAPSA
*)ptr
;
728 moc32
->wMid
= moc16
->wMid
;
729 moc32
->wPid
= moc16
->wPid
;
730 moc32
->vDriverVersion
= moc16
->vDriverVersion
;
731 strcpy(moc32
->szPname
, moc16
->szPname
);
732 moc32
->wTechnology
= moc16
->wTechnology
;
733 moc32
->wVoices
= moc16
->wVoices
;
734 moc32
->wNotes
= moc16
->wNotes
;
735 moc32
->wChannelMask
= moc16
->wChannelMask
;
736 moc32
->dwSupport
= moc16
->dwSupport
;
738 if (!SEGPTR_FREE(ptr
))
739 FIXME("bad free line=%d\n", __LINE__
);
747 LPMIDIHDR mh16
= (LPMIDIHDR
)PTR_SEG_TO_LIN(*lpParam1
);
748 LPSTR ptr
= (LPSTR
)mh16
- sizeof(LPMIDIHDR
);
749 LPMIDIHDR mh32
= *(LPMIDIHDR
*)ptr
;
751 assert(mh32
->lpNext
== (LPMIDIHDR
)mh16
);
752 mh32
->dwBytesRecorded
= mh16
->dwBytesRecorded
;
753 mh32
->dwUser
= mh16
->dwUser
;
754 mh32
->dwFlags
= mh16
->dwFlags
;
756 if (wMsg
== MODM_UNPREPARE
) {
757 if (!SEGPTR_FREE(ptr
))
758 FIXME("bad free line=%d\n", __LINE__
);
766 LPMIDIOPENDESC16 mod16
= (LPMIDIOPENDESC16
)PTR_SEG_TO_LIN(*lpParam1
);
767 LPSTR ptr
= (LPSTR
)mod16
- sizeof(LPMIDIOPENDESC
) - 2*sizeof(DWORD
);
769 **(DWORD
**)(ptr
+ sizeof(LPMIDIOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPMIDIOPENDESC
) + sizeof(DWORD
));
771 if (!SEGPTR_FREE(ptr
))
772 FIXME("bad free line=%d\n", __LINE__
);
778 case MODM_CACHEPATCHES
:
779 case MODM_CACHEDRUMPATCHES
:
781 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
787 /**************************************************************************
788 * MMDRV_MidiOut_Callback [internal]
790 static void CALLBACK
MMDRV_MidiOut_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
792 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
797 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
800 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
801 /* initial map is: 32 => 16 */
802 LPMIDIHDR mh16
= (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
);
803 LPMIDIHDR mh32
= *(LPMIDIHDR
*)((LPSTR
)mh16
- sizeof(LPMIDIHDR
));
805 dwParam1
= (DWORD
)mh32
;
806 mh32
->dwFlags
= mh16
->dwFlags
;
807 mh32
->dwOffset
= mh16
->dwOffset
;
808 if (mh32
->reserved
>= sizeof(MIDIHDR
))
809 mh32
->dwOffset
= mh16
->dwOffset
;
810 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
811 /* initial map is: 16 => 32 */
812 LPMIDIHDR mh32
= (LPMIDIHDR
)(dwParam1
);
813 LPMIDIHDR segmh16
= *(LPMIDIHDR
*)((LPSTR
)mh32
- sizeof(LPMIDIHDR
));
814 LPMIDIHDR mh16
= PTR_SEG_TO_LIN(segmh16
);
816 dwParam1
= (DWORD
)segmh16
;
817 mh16
->dwFlags
= mh32
->dwFlags
;
818 if (mh16
->reserved
>= sizeof(MIDIHDR
))
819 mh16
->dwOffset
= mh32
->dwOffset
;
821 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
823 /* case MOM_POSITIONCB: */
825 ERR("Unknown msg %u\n", uMsg
);
828 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
831 /* =================================
832 * W A V E I N M A P P E R S
833 * ================================= */
835 /**************************************************************************
836 * MMDRV_WaveIn_Map16To32A [internal]
838 static MMDRV_MapType
MMDRV_WaveIn_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
840 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
843 case WIDM_GETNUMDEVS
:
851 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
853 case WIDM_GETDEVCAPS
:
855 LPWAVEINCAPSA wic32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16
) + sizeof(WAVEINCAPSA
));
856 LPWAVEINCAPS16 wic16
= PTR_SEG_TO_LIN(*lpParam1
);
859 *(LPWAVEINCAPS16
*)wic32
= wic16
;
860 wic32
= (LPWAVEINCAPSA
)((LPSTR
)wic32
+ sizeof(LPWAVEINCAPS16
));
861 *lpParam1
= (DWORD
)wic32
;
862 *lpParam2
= sizeof(WAVEINCAPSA
);
864 ret
= MMDRV_MAP_OKMEM
;
866 ret
= MMDRV_MAP_NOMEM
;
872 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
873 LPMMTIME16 mmt16
= PTR_SEG_TO_LIN(*lpParam1
);
876 *(LPMMTIME16
*)mmt32
= mmt16
;
877 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
879 mmt32
->wType
= mmt16
->wType
;
880 *lpParam1
= (DWORD
)mmt32
;
881 *lpParam2
= sizeof(MMTIME
);
883 ret
= MMDRV_MAP_OKMEM
;
885 ret
= MMDRV_MAP_NOMEM
;
891 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
892 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*lpParam1
);
895 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
896 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
897 wh32
->lpData
= PTR_SEG_TO_LIN(wh16
->lpData
);
898 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
899 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
900 wh32
->dwUser
= wh16
->dwUser
;
901 wh32
->dwFlags
= wh16
->dwFlags
;
902 wh32
->dwLoops
= wh16
->dwLoops
;
903 /* FIXME: nothing on wh32->lpNext */
904 /* could link the wh32->lpNext at this level for memory house keeping */
905 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
906 *lpParam1
= (DWORD
)wh32
;
907 *lpParam2
= sizeof(WAVEHDR
);
909 ret
= MMDRV_MAP_OKMEM
;
911 ret
= MMDRV_MAP_NOMEM
;
918 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*lpParam1
);
919 LPWAVEHDR wh32
= (LPWAVEHDR
)wh16
->lpNext
;
921 *lpParam1
= (DWORD
)wh32
;
922 *lpParam2
= sizeof(WAVEHDR
);
923 /* dwBufferLength can be reduced between prepare & write */
924 if (wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
925 ERR("Size of buffer has been increased (%ld, %ld)\n",
926 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
927 return MMDRV_MAP_MSGERROR
;
929 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
930 ret
= MMDRV_MAP_OKMEM
;
934 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
935 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
941 /**************************************************************************
942 * MMDRV_WaveIn_UnMap16To32A [internal]
944 static MMDRV_MapType
MMDRV_WaveIn_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
946 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
949 case WIDM_GETNUMDEVS
:
957 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
959 case WIDM_GETDEVCAPS
:
961 LPWAVEINCAPSA wic32
= (LPWAVEINCAPSA
)(*lpParam1
);
962 LPWAVEINCAPS16 wic16
= *(LPWAVEINCAPS16
*)((LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
964 wic16
->wMid
= wic32
->wMid
;
965 wic16
->wPid
= wic32
->wPid
;
966 wic16
->vDriverVersion
= wic32
->vDriverVersion
;
967 strcpy(wic16
->szPname
, wic32
->szPname
);
968 wic16
->dwFormats
= wic32
->dwFormats
;
969 wic16
->wChannels
= wic32
->wChannels
;
970 HeapFree(GetProcessHeap(), 0, (LPSTR
)wic32
- sizeof(LPWAVEINCAPS16
));
976 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
977 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
979 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
980 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
988 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
989 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*(LPWAVEHDR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
991 assert(wh16
->lpNext
== wh32
);
992 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
993 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
994 wh16
->dwUser
= wh32
->dwUser
;
995 wh16
->dwFlags
= wh32
->dwFlags
;
996 wh16
->dwLoops
= wh32
->dwLoops
;
998 if (wMsg
== WIDM_UNPREPARE
) {
999 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1006 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1012 /**************************************************************************
1013 * MMDRV_WaveIn_Map32ATo16 [internal]
1015 static MMDRV_MapType
MMDRV_WaveIn_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1017 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1021 case WIDM_GETNUMDEVS
:
1030 LPWAVEOPENDESC wod32
= (LPWAVEOPENDESC
)*lpParam1
;
1031 int sz
= sizeof(WAVEFORMATEX
);
1033 LPWAVEOPENDESC16 wod16
;
1035 /* allocated data are mapped as follows:
1036 LPWAVEOPENDESC ptr to orig lParam1
1037 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1038 DWORD dwUser passed to driver
1039 WAVEOPENDESC16 wod16: openDesc passed to driver
1040 WAVEFORMATEX openDesc->lpFormat passed to driver
1041 xxx extra bytes to WAVEFORMATEX
1043 if (wod32
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
1044 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
, wod32
->lpFormat
->wFormatTag
);
1045 sz
+= ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
;
1048 ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
) + sz
);
1051 *(LPWAVEOPENDESC
*)ptr
= wod32
;
1052 *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *lpdwUser
;
1053 wod16
= (LPWAVEOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
));
1055 wod16
->hWave
= wod32
->hWave
;
1056 wod16
->lpFormat
= (LPWAVEFORMATEX
)((DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
));
1057 memcpy(wod16
+ 1, wod32
->lpFormat
, sz
);
1059 wod16
->dwCallback
= wod32
->dwCallback
;
1060 wod16
->dwInstance
= wod32
->dwInstance
;
1061 wod16
->uMappedDeviceID
= wod32
->uMappedDeviceID
;
1062 wod16
->dnDevNode
= wod32
->dnDevNode
;
1064 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
);
1065 *lpdwUser
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
);
1067 ret
= MMDRV_MAP_OKMEM
;
1069 ret
= MMDRV_MAP_NOMEM
;
1075 LPWAVEHDR wh32
= (LPWAVEHDR
)*lpParam1
;
1077 LPVOID ptr
= SEGPTR_ALLOC(sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
) + wh32
->dwBufferLength
);
1080 *(LPWAVEHDR
*)ptr
= wh32
;
1081 wh16
= (LPWAVEHDR
)((LPSTR
)ptr
+ sizeof(LPWAVEHDR
));
1082 wh16
->lpData
= (LPSTR
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
);
1083 /* data will be copied on WODM_WRITE */
1084 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1085 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1086 wh16
->dwUser
= wh32
->dwUser
;
1087 wh16
->dwFlags
= wh32
->dwFlags
;
1088 wh16
->dwLoops
= wh32
->dwLoops
;
1089 /* FIXME: nothing on wh32->lpNext */
1090 /* could link the wh32->lpNext at this level for memory house keeping */
1091 wh32
->lpNext
= wh16
; /* for reuse in unprepare and write */
1092 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1093 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1094 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1095 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1096 *lpParam2
= sizeof(WAVEHDR
);
1098 ret
= MMDRV_MAP_OKMEM
;
1100 ret
= MMDRV_MAP_NOMEM
;
1104 case WIDM_ADDBUFFER
:
1105 case WIDM_UNPREPARE
:
1107 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1108 LPWAVEHDR wh16
= wh32
->lpNext
;
1109 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1111 assert(*(LPWAVEHDR
*)ptr
== wh32
);
1113 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1114 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1115 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1117 if (wMsg
== WIDM_ADDBUFFER
)
1118 memcpy((LPSTR
)wh16
+ sizeof(WAVEHDR
), wh32
->lpData
, wh32
->dwBufferLength
);
1120 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1121 *lpParam2
= sizeof(WAVEHDR
);
1122 /* dwBufferLength can be reduced between prepare & write */
1123 if (wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
1124 ERR("Size of buffer has been increased (%ld, %ld)\n",
1125 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
1126 return MMDRV_MAP_MSGERROR
;
1128 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1129 ret
= MMDRV_MAP_OKMEM
;
1132 case WIDM_GETDEVCAPS
:
1134 LPWAVEINCAPSA wic32
= (LPWAVEINCAPSA
)*lpParam1
;
1135 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPWAVEINCAPSA
) + sizeof(WAVEINCAPS16
));
1138 *(LPWAVEINCAPSA
*)ptr
= wic32
;
1139 ret
= MMDRV_MAP_OKMEM
;
1141 ret
= MMDRV_MAP_NOMEM
;
1143 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEINCAPSA
);
1144 *lpParam2
= sizeof(WAVEINCAPS16
);
1149 LPMMTIME mmt32
= (LPMMTIME
)*lpParam1
;
1150 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMMTIME
) + sizeof(MMTIME16
));
1151 LPMMTIME16 mmt16
= (LPMMTIME16
)(ptr
+ sizeof(LPMMTIME
));
1154 *(LPMMTIME
*)ptr
= mmt32
;
1155 mmt16
->wType
= mmt32
->wType
;
1156 ret
= MMDRV_MAP_OKMEM
;
1158 ret
= MMDRV_MAP_NOMEM
;
1160 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMMTIME
);
1161 *lpParam2
= sizeof(MMTIME16
);
1165 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1171 /**************************************************************************
1172 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1174 static MMDRV_MapType
MMDRV_WaveIn_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1176 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1180 case WIDM_GETNUMDEVS
:
1189 LPWAVEOPENDESC16 wod16
= (LPWAVEOPENDESC16
)PTR_SEG_TO_LIN(*lpParam1
);
1190 LPSTR ptr
= (LPSTR
)wod16
- sizeof(LPWAVEOPENDESC
) - 2*sizeof(DWORD
);
1191 LPWAVEOPENDESC wod32
= *(LPWAVEOPENDESC
*)ptr
;
1193 wod32
->uMappedDeviceID
= wod16
->uMappedDeviceID
;
1194 **(DWORD
**)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
));
1196 if (!SEGPTR_FREE(ptr
))
1197 FIXME("bad free line=%d\n", __LINE__
);
1203 case WIDM_ADDBUFFER
:
1205 case WIDM_UNPREPARE
:
1207 LPWAVEHDR wh16
= (LPWAVEHDR
)PTR_SEG_TO_LIN(*lpParam1
);
1208 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1209 LPWAVEHDR wh32
= *(LPWAVEHDR
*)ptr
;
1211 assert(wh32
->lpNext
== wh16
);
1212 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1213 wh32
->dwUser
= wh16
->dwUser
;
1214 wh32
->dwFlags
= wh16
->dwFlags
;
1215 wh32
->dwLoops
= wh16
->dwLoops
;
1217 if (wMsg
== WIDM_UNPREPARE
) {
1218 if (!SEGPTR_FREE(ptr
))
1219 FIXME("bad free line=%d\n", __LINE__
);
1225 case WIDM_GETDEVCAPS
:
1227 LPWAVEINCAPS16 wic16
= (LPWAVEINCAPS16
)PTR_SEG_TO_LIN(*lpParam1
);
1228 LPSTR ptr
= (LPSTR
)wic16
- sizeof(LPWAVEINCAPSA
);
1229 LPWAVEINCAPSA wic32
= *(LPWAVEINCAPSA
*)ptr
;
1231 wic32
->wMid
= wic16
->wMid
;
1232 wic32
->wPid
= wic16
->wPid
;
1233 wic32
->vDriverVersion
= wic16
->vDriverVersion
;
1234 strcpy(wic32
->szPname
, wic16
->szPname
);
1235 wic32
->dwFormats
= wic16
->dwFormats
;
1236 wic32
->wChannels
= wic16
->wChannels
;
1237 if (!SEGPTR_FREE(ptr
))
1238 FIXME("bad free line=%d\n", __LINE__
);
1244 LPMMTIME16 mmt16
= (LPMMTIME16
)PTR_SEG_TO_LIN(*lpParam1
);
1245 LPSTR ptr
= (LPSTR
)mmt16
- sizeof(LPMMTIME
);
1246 LPMMTIME mmt32
= *(LPMMTIME
*)ptr
;
1248 MMSYSTEM_MMTIME16to32(mmt32
, mmt16
);
1250 if (!SEGPTR_FREE(ptr
))
1251 FIXME("bad free line=%d\n", __LINE__
);
1257 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1263 /**************************************************************************
1264 * MMDRV_WaveIn_Callback [internal]
1266 static void CALLBACK
MMDRV_WaveIn_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
1268 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
1273 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1276 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
1277 /* initial map is: 32 => 16 */
1278 LPWAVEHDR wh16
= (LPWAVEHDR
)PTR_SEG_TO_LIN(dwParam1
);
1279 LPWAVEHDR wh32
= *(LPWAVEHDR
*)((LPSTR
)wh16
- sizeof(LPWAVEHDR
));
1281 dwParam1
= (DWORD
)wh32
;
1282 wh32
->dwFlags
= wh16
->dwFlags
;
1283 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1284 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
1285 /* initial map is: 16 => 32 */
1286 LPWAVEHDR wh32
= (LPWAVEHDR
)(dwParam1
);
1287 LPWAVEHDR segwh16
= *(LPWAVEHDR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1288 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(segwh16
);
1290 dwParam1
= (DWORD
)segwh16
;
1291 wh16
->dwFlags
= wh32
->dwFlags
;
1292 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1294 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1297 ERR("Unknown msg %u\n", uMsg
);
1300 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
1303 /* =================================
1304 * W A V E O U T M A P P E R S
1305 * ================================= */
1307 /**************************************************************************
1308 * MMDRV_WaveOut_Map16To32A [internal]
1310 static MMDRV_MapType
MMDRV_WaveOut_Map16To32A (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1312 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1316 case WODM_BREAKLOOP
:
1318 case WODM_GETNUMDEVS
:
1323 case WODM_SETPLAYBACKRATE
:
1324 case WODM_SETVOLUME
:
1329 case WODM_GETPLAYBACKRATE
:
1330 case WODM_GETVOLUME
:
1332 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1335 case WODM_GETDEVCAPS
:
1337 LPWAVEOUTCAPSA woc32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16
) + sizeof(WAVEOUTCAPSA
));
1338 LPWAVEOUTCAPS16 woc16
= PTR_SEG_TO_LIN(*lpParam1
);
1341 *(LPWAVEOUTCAPS16
*)woc32
= woc16
;
1342 woc32
= (LPWAVEOUTCAPSA
)((LPSTR
)woc32
+ sizeof(LPWAVEOUTCAPS16
));
1343 *lpParam1
= (DWORD
)woc32
;
1344 *lpParam2
= sizeof(WAVEOUTCAPSA
);
1346 ret
= MMDRV_MAP_OKMEM
;
1348 ret
= MMDRV_MAP_NOMEM
;
1354 LPMMTIME mmt32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16
) + sizeof(MMTIME
));
1355 LPMMTIME16 mmt16
= PTR_SEG_TO_LIN(*lpParam1
);
1358 *(LPMMTIME16
*)mmt32
= mmt16
;
1359 mmt32
= (LPMMTIME
)((LPSTR
)mmt32
+ sizeof(LPMMTIME16
));
1361 mmt32
->wType
= mmt16
->wType
;
1362 *lpParam1
= (DWORD
)mmt32
;
1363 *lpParam2
= sizeof(MMTIME
);
1365 ret
= MMDRV_MAP_OKMEM
;
1367 ret
= MMDRV_MAP_NOMEM
;
1373 LPWAVEHDR wh32
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
));
1374 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*lpParam1
);
1377 *(LPWAVEHDR
*)wh32
= (LPWAVEHDR
)*lpParam1
;
1378 wh32
= (LPWAVEHDR
)((LPSTR
)wh32
+ sizeof(LPWAVEHDR
));
1379 wh32
->lpData
= PTR_SEG_TO_LIN(wh16
->lpData
);
1380 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1381 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1382 wh32
->dwUser
= wh16
->dwUser
;
1383 wh32
->dwFlags
= wh16
->dwFlags
;
1384 wh32
->dwLoops
= wh16
->dwLoops
;
1385 /* FIXME: nothing on wh32->lpNext */
1386 /* could link the wh32->lpNext at this level for memory house keeping */
1387 wh16
->lpNext
= wh32
; /* for reuse in unprepare and write */
1388 *lpParam1
= (DWORD
)wh32
;
1389 *lpParam2
= sizeof(WAVEHDR
);
1391 ret
= MMDRV_MAP_OKMEM
;
1393 ret
= MMDRV_MAP_NOMEM
;
1397 case WODM_UNPREPARE
:
1400 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*lpParam1
);
1401 LPWAVEHDR wh32
= (LPWAVEHDR
)wh16
->lpNext
;
1403 *lpParam1
= (DWORD
)wh32
;
1404 *lpParam2
= sizeof(WAVEHDR
);
1405 /* dwBufferLength can be reduced between prepare & write */
1406 if (wh32
->dwBufferLength
< wh16
->dwBufferLength
) {
1407 ERR("Size of buffer has been increased (%ld, %ld)\n",
1408 wh32
->dwBufferLength
, wh16
->dwBufferLength
);
1409 return MMDRV_MAP_MSGERROR
;
1411 wh32
->dwBufferLength
= wh16
->dwBufferLength
;
1412 ret
= MMDRV_MAP_OKMEM
;
1416 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1422 /**************************************************************************
1423 * MMDRV_WaveOut_UnMap16To32A [internal]
1425 static MMDRV_MapType
MMDRV_WaveOut_UnMap16To32A(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1427 MMDRV_MapType ret
= MMDRV_MAP_MSGERROR
;
1431 case WODM_BREAKLOOP
:
1433 case WODM_GETNUMDEVS
:
1438 case WODM_SETPLAYBACKRATE
:
1439 case WODM_SETVOLUME
:
1444 case WODM_GETPLAYBACKRATE
:
1445 case WODM_GETVOLUME
:
1447 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1450 case WODM_GETDEVCAPS
:
1452 LPWAVEOUTCAPSA woc32
= (LPWAVEOUTCAPSA
)(*lpParam1
);
1453 LPWAVEOUTCAPS16 woc16
= *(LPWAVEOUTCAPS16
*)((LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
1455 woc16
->wMid
= woc32
->wMid
;
1456 woc16
->wPid
= woc32
->wPid
;
1457 woc16
->vDriverVersion
= woc32
->vDriverVersion
;
1458 strcpy(woc16
->szPname
, woc32
->szPname
);
1459 woc16
->dwFormats
= woc32
->dwFormats
;
1460 woc16
->wChannels
= woc32
->wChannels
;
1461 woc16
->dwSupport
= woc32
->dwSupport
;
1462 HeapFree(GetProcessHeap(), 0, (LPSTR
)woc32
- sizeof(LPWAVEOUTCAPS16
));
1468 LPMMTIME mmt32
= (LPMMTIME
)(*lpParam1
);
1469 LPMMTIME16 mmt16
= *(LPMMTIME16
*)((LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1471 MMSYSTEM_MMTIME32to16(mmt16
, mmt32
);
1472 HeapFree(GetProcessHeap(), 0, (LPSTR
)mmt32
- sizeof(LPMMTIME16
));
1477 case WODM_UNPREPARE
:
1480 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1481 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(*(LPWAVEHDR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
)));
1483 assert(wh16
->lpNext
== wh32
);
1484 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1485 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1486 wh16
->dwUser
= wh32
->dwUser
;
1487 wh16
->dwFlags
= wh32
->dwFlags
;
1488 wh16
->dwLoops
= wh32
->dwLoops
;
1490 if (wMsg
== WODM_UNPREPARE
) {
1491 HeapFree(GetProcessHeap(), 0, (LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1498 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg
, *lpParam1
, *lpParam2
);
1504 /**************************************************************************
1505 * MMDRV_WaveOut_Map32ATo16 [internal]
1507 static MMDRV_MapType
MMDRV_WaveOut_Map32ATo16 (UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1513 case WODM_BREAKLOOP
:
1515 case WODM_GETNUMDEVS
:
1520 case WODM_SETPLAYBACKRATE
:
1521 case WODM_SETVOLUME
:
1525 case WODM_GETDEVCAPS
:
1527 LPWAVEOUTCAPSA woc32
= (LPWAVEOUTCAPSA
)*lpParam1
;
1528 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOUTCAPSA
) + sizeof(WAVEOUTCAPS16
));
1531 *(LPWAVEOUTCAPSA
*)ptr
= woc32
;
1532 ret
= MMDRV_MAP_OKMEM
;
1534 ret
= MMDRV_MAP_NOMEM
;
1536 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOUTCAPSA
);
1537 *lpParam2
= sizeof(WAVEOUTCAPS16
);
1541 FIXME("NIY: no conversion yet\n");
1542 ret
= MMDRV_MAP_MSGERROR
;
1544 case WODM_GETPLAYBACKRATE
:
1545 FIXME("NIY: no conversion yet\n");
1546 ret
= MMDRV_MAP_MSGERROR
;
1550 LPMMTIME mmt32
= (LPMMTIME
)*lpParam1
;
1551 LPSTR ptr
= SEGPTR_ALLOC(sizeof(LPMMTIME
) + sizeof(MMTIME16
));
1552 LPMMTIME16 mmt16
= (LPMMTIME16
)(ptr
+ sizeof(LPMMTIME
));
1555 *(LPMMTIME
*)ptr
= mmt32
;
1556 mmt16
->wType
= mmt32
->wType
;
1557 ret
= MMDRV_MAP_OKMEM
;
1559 ret
= MMDRV_MAP_NOMEM
;
1561 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPMMTIME
);
1562 *lpParam2
= sizeof(MMTIME16
);
1565 case WODM_GETVOLUME
:
1566 FIXME("NIY: no conversion yet\n");
1567 ret
= MMDRV_MAP_MSGERROR
;
1571 LPWAVEOPENDESC wod32
= (LPWAVEOPENDESC
)*lpParam1
;
1572 int sz
= sizeof(WAVEFORMATEX
);
1574 LPWAVEOPENDESC16 wod16
;
1576 /* allocated data are mapped as follows:
1577 LPWAVEOPENDESC ptr to orig lParam1
1578 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
1579 DWORD dwUser passed to driver
1580 WAVEOPENDESC16 wod16: openDesc passed to driver
1581 WAVEFORMATEX openDesc->lpFormat passed to driver
1582 xxx extra bytes to WAVEFORMATEX
1584 if (wod32
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
1585 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
, wod32
->lpFormat
->wFormatTag
);
1586 sz
+= ((LPWAVEFORMATEX
)wod32
->lpFormat
)->cbSize
;
1589 ptr
= SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
) + sz
);
1592 *(LPWAVEOPENDESC
*)ptr
= wod32
;
1593 *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *lpdwUser
;
1594 wod16
= (LPWAVEOPENDESC16
)((LPSTR
)ptr
+ sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
));
1596 wod16
->hWave
= wod32
->hWave
;
1597 wod16
->lpFormat
= (LPWAVEFORMATEX
)((DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
) + sizeof(WAVEOPENDESC16
));
1598 memcpy(wod16
+ 1, wod32
->lpFormat
, sz
);
1600 wod16
->dwCallback
= wod32
->dwCallback
;
1601 wod16
->dwInstance
= wod32
->dwInstance
;
1602 wod16
->uMappedDeviceID
= wod32
->uMappedDeviceID
;
1603 wod16
->dnDevNode
= wod32
->dnDevNode
;
1605 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + 2*sizeof(DWORD
);
1606 *lpdwUser
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
);
1608 ret
= MMDRV_MAP_OKMEM
;
1610 ret
= MMDRV_MAP_NOMEM
;
1616 LPWAVEHDR wh32
= (LPWAVEHDR
)*lpParam1
;
1618 LPVOID ptr
= SEGPTR_ALLOC(sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
) + wh32
->dwBufferLength
);
1621 *(LPWAVEHDR
*)ptr
= wh32
;
1622 wh16
= (LPWAVEHDR
)((LPSTR
)ptr
+ sizeof(LPWAVEHDR
));
1623 wh16
->lpData
= (LPSTR
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
) + sizeof(WAVEHDR
);
1624 /* data will be copied on WODM_WRITE */
1625 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1626 wh16
->dwBytesRecorded
= wh32
->dwBytesRecorded
;
1627 wh16
->dwUser
= wh32
->dwUser
;
1628 wh16
->dwFlags
= wh32
->dwFlags
;
1629 wh16
->dwLoops
= wh32
->dwLoops
;
1630 /* FIXME: nothing on wh32->lpNext */
1631 /* could link the wh32->lpNext at this level for memory house keeping */
1632 wh32
->lpNext
= wh16
; /* for reuse in unprepare and write */
1633 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1634 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1635 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1636 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1637 *lpParam2
= sizeof(WAVEHDR
);
1639 ret
= MMDRV_MAP_OKMEM
;
1641 ret
= MMDRV_MAP_NOMEM
;
1645 case WODM_UNPREPARE
:
1648 LPWAVEHDR wh32
= (LPWAVEHDR
)(*lpParam1
);
1649 LPWAVEHDR wh16
= wh32
->lpNext
;
1650 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1652 assert(*(LPWAVEHDR
*)ptr
== wh32
);
1654 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1655 (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
), (DWORD
)wh16
->lpData
,
1656 wh32
->dwBufferLength
, (DWORD
)wh32
->lpData
);
1658 if (wMsg
== WODM_WRITE
)
1659 memcpy((LPSTR
)wh16
+ sizeof(WAVEHDR
), wh32
->lpData
, wh32
->dwBufferLength
);
1661 *lpParam1
= (DWORD
)SEGPTR_GET(ptr
) + sizeof(LPWAVEHDR
);
1662 *lpParam2
= sizeof(WAVEHDR
);
1663 /* dwBufferLength can be reduced between prepare & write */
1664 if (wh16
->dwBufferLength
< wh32
->dwBufferLength
) {
1665 ERR("Size of buffer has been increased (%ld, %ld)\n",
1666 wh16
->dwBufferLength
, wh32
->dwBufferLength
);
1667 return MMDRV_MAP_MSGERROR
;
1669 wh16
->dwBufferLength
= wh32
->dwBufferLength
;
1670 ret
= MMDRV_MAP_OKMEM
;
1674 FIXME("NIY: no conversion yet\n");
1675 ret
= MMDRV_MAP_MSGERROR
;
1681 /**************************************************************************
1682 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1684 static MMDRV_MapType
MMDRV_WaveOut_UnMap32ATo16(UINT wMsg
, LPDWORD lpdwUser
, LPDWORD lpParam1
, LPDWORD lpParam2
)
1690 case WODM_BREAKLOOP
:
1692 case WODM_GETNUMDEVS
:
1697 case WODM_SETPLAYBACKRATE
:
1698 case WODM_SETVOLUME
:
1702 case WODM_GETDEVCAPS
:
1704 LPWAVEOUTCAPS16 woc16
= (LPWAVEOUTCAPS16
)PTR_SEG_TO_LIN(*lpParam1
);
1705 LPSTR ptr
= (LPSTR
)woc16
- sizeof(LPWAVEOUTCAPSA
);
1706 LPWAVEOUTCAPSA woc32
= *(LPWAVEOUTCAPSA
*)ptr
;
1708 woc32
->wMid
= woc16
->wMid
;
1709 woc32
->wPid
= woc16
->wPid
;
1710 woc32
->vDriverVersion
= woc16
->vDriverVersion
;
1711 strcpy(woc32
->szPname
, woc16
->szPname
);
1712 woc32
->dwFormats
= woc16
->dwFormats
;
1713 woc32
->wChannels
= woc16
->wChannels
;
1714 woc32
->dwSupport
= woc16
->dwSupport
;
1715 if (!SEGPTR_FREE(ptr
))
1716 FIXME("bad free line=%d\n", __LINE__
);
1721 FIXME("NIY: no conversion yet\n");
1722 ret
= MMDRV_MAP_MSGERROR
;
1724 case WODM_GETPLAYBACKRATE
:
1725 FIXME("NIY: no conversion yet\n");
1726 ret
= MMDRV_MAP_MSGERROR
;
1730 LPMMTIME16 mmt16
= (LPMMTIME16
)PTR_SEG_TO_LIN(*lpParam1
);
1731 LPSTR ptr
= (LPSTR
)mmt16
- sizeof(LPMMTIME
);
1732 LPMMTIME mmt32
= *(LPMMTIME
*)ptr
;
1734 MMSYSTEM_MMTIME16to32(mmt32
, mmt16
);
1736 if (!SEGPTR_FREE(ptr
))
1737 FIXME("bad free line=%d\n", __LINE__
);
1744 LPWAVEOPENDESC16 wod16
= (LPWAVEOPENDESC16
)PTR_SEG_TO_LIN(*lpParam1
);
1745 LPSTR ptr
= (LPSTR
)wod16
- sizeof(LPWAVEOPENDESC
) - 2*sizeof(DWORD
);
1746 LPWAVEOPENDESC wod32
= *(LPWAVEOPENDESC
*)ptr
;
1748 wod32
->uMappedDeviceID
= wod16
->uMappedDeviceID
;
1749 **(DWORD
**)(ptr
+ sizeof(LPWAVEOPENDESC
)) = *(LPDWORD
)(ptr
+ sizeof(LPWAVEOPENDESC
) + sizeof(DWORD
));
1751 if (!SEGPTR_FREE(ptr
))
1752 FIXME("bad free line=%d\n", __LINE__
);
1758 case WODM_UNPREPARE
:
1761 LPWAVEHDR wh16
= (LPWAVEHDR
)PTR_SEG_TO_LIN(*lpParam1
);
1762 LPSTR ptr
= (LPSTR
)wh16
- sizeof(LPWAVEHDR
);
1763 LPWAVEHDR wh32
= *(LPWAVEHDR
*)ptr
;
1765 assert(wh32
->lpNext
== wh16
);
1766 wh32
->dwBytesRecorded
= wh16
->dwBytesRecorded
;
1767 wh32
->dwUser
= wh16
->dwUser
;
1768 wh32
->dwFlags
= wh16
->dwFlags
;
1769 wh32
->dwLoops
= wh16
->dwLoops
;
1771 if (wMsg
== WODM_UNPREPARE
) {
1772 if (!SEGPTR_FREE(ptr
))
1773 FIXME("bad free line=%d\n", __LINE__
);
1779 case WODM_GETVOLUME
:
1780 FIXME("NIY: no conversion yet\n");
1781 ret
= MMDRV_MAP_MSGERROR
;
1784 FIXME("NIY: no conversion yet\n");
1785 ret
= MMDRV_MAP_MSGERROR
;
1791 /**************************************************************************
1792 * MMDRV_WaveOut_Callback [internal]
1794 static void CALLBACK
MMDRV_WaveOut_Callback(HDRVR hDev
, UINT uMsg
, DWORD dwInstance
, DWORD dwParam1
, DWORD dwParam2
)
1796 LPWINE_MLD mld
= (LPWINE_MLD
)dwInstance
;
1801 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1804 if (mld
->bFrom32
&& !MMDrvs
[mld
->mmdIndex
].bIs32
) {
1805 /* initial map is: 32 => 16 */
1806 LPWAVEHDR wh16
= (LPWAVEHDR
)PTR_SEG_TO_LIN(dwParam1
);
1807 LPWAVEHDR wh32
= *(LPWAVEHDR
*)((LPSTR
)wh16
- sizeof(LPWAVEHDR
));
1809 dwParam1
= (DWORD
)wh32
;
1810 wh32
->dwFlags
= wh16
->dwFlags
;
1811 } else if (!mld
->bFrom32
&& MMDrvs
[mld
->mmdIndex
].bIs32
) {
1812 /* initial map is: 16 => 32 */
1813 LPWAVEHDR wh32
= (LPWAVEHDR
)(dwParam1
);
1814 LPWAVEHDR segwh16
= *(LPWAVEHDR
*)((LPSTR
)wh32
- sizeof(LPWAVEHDR
));
1815 LPWAVEHDR wh16
= PTR_SEG_TO_LIN(segwh16
);
1817 dwParam1
= (DWORD
)segwh16
;
1818 wh16
->dwFlags
= wh32
->dwFlags
;
1820 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1823 ERR("Unknown msg %u\n", uMsg
);
1826 MMDRV_Callback(mld
, hDev
, uMsg
, dwParam1
, dwParam2
);
1829 #define A(_x,_y) {#_y, _x, \
1830 MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1831 MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1832 MMDRV_##_y##_Callback, 0, NULL, -1}
1834 /* Note: the indices of this array must match the definitions
1835 * of the MMDRV_???? manifest constants
1837 static WINE_LLTYPE llTypes
[MMDRV_MAX
] = {
1847 /**************************************************************************
1848 * MMDRV_GetNum [internal]
1850 UINT
MMDRV_GetNum(UINT type
)
1852 assert(type
< MMDRV_MAX
);
1853 return llTypes
[type
].wMaxId
;
1856 /**************************************************************************
1857 * WINE_Message [internal]
1859 DWORD
MMDRV_Message(LPWINE_MLD mld
, WORD wMsg
, DWORD dwParam1
,
1860 DWORD dwParam2
, BOOL bFrom32
)
1862 LPWINE_MM_DRIVER lpDrv
;
1864 WINE_MM_DRIVER_PART
* part
;
1865 WINE_LLTYPE
* llType
= &llTypes
[mld
->type
];
1869 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1870 llTypes
[mld
->type
].name
, mld
->uDeviceID
, wMsg
,
1871 mld
->dwDriverInstance
, dwParam1
, dwParam2
, bFrom32
?'Y':'N');
1873 if (mld
->uDeviceID
== (UINT16
)-1) {
1874 if (!llType
->bSupportMapper
) {
1875 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1876 llTypes
[mld
->type
].name
);
1877 return MMSYSERR_BADDEVICEID
;
1881 if (mld
->uDeviceID
>= llType
->wMaxId
) {
1882 WARN("uDev(%u) requested >= max (%d)\n", mld
->uDeviceID
, llType
->wMaxId
);
1883 return MMSYSERR_BADDEVICEID
;
1885 devID
= mld
->uDeviceID
;
1888 lpDrv
= &MMDrvs
[mld
->mmdIndex
];
1889 part
= &lpDrv
->parts
[mld
->type
];
1892 /* some sanity checks */
1893 if (!(part
->nIDMin
<= devID
))
1894 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part
->nIDMin
, devID
);
1895 if (!(devID
< part
->nIDMax
))
1896 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID
, part
->nIDMax
);
1900 assert(part
->u
.fnMessage32
);
1903 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1904 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1905 ret
= part
->u
.fnMessage32(mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1906 TRACE("=> %lu\n", ret
);
1908 map
= llType
->Map16To32A(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1910 case MMDRV_MAP_NOMEM
:
1911 ret
= MMSYSERR_NOMEM
;
1913 case MMDRV_MAP_MSGERROR
:
1914 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg
);
1915 ret
= MMSYSERR_ERROR
;
1918 case MMDRV_MAP_OKMEM
:
1919 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1920 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1921 ret
= part
->u
.fnMessage32(mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
,
1922 dwParam1
, dwParam2
);
1923 TRACE("=> %lu\n", ret
);
1924 if (map
== MMDRV_MAP_OKMEM
)
1925 llType
->UnMap16To32A(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1928 case MMDRV_MAP_PASS
:
1929 FIXME("NIY: pass used ?\n");
1930 ret
= MMSYSERR_NOTSUPPORTED
;
1935 assert(part
->u
.fnMessage16
);
1938 map
= llType
->Map32ATo16(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1940 case MMDRV_MAP_NOMEM
:
1941 ret
= MMSYSERR_NOMEM
;
1943 case MMDRV_MAP_MSGERROR
:
1944 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg
);
1945 ret
= MMSYSERR_ERROR
;
1948 case MMDRV_MAP_OKMEM
:
1949 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1950 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1951 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
, mld
->uDeviceID
,
1952 wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1953 TRACE("=> %lu\n", ret
);
1954 if (map
== MMDRV_MAP_OKMEM
)
1955 llType
->UnMap32ATo16(wMsg
, &mld
->dwDriverInstance
, &dwParam1
, &dwParam2
);
1958 case MMDRV_MAP_PASS
:
1959 FIXME("NIY: pass used ?\n");
1960 ret
= MMSYSERR_NOTSUPPORTED
;
1964 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1965 mld
->uDeviceID
, wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1966 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
, mld
->uDeviceID
,
1967 wMsg
, mld
->dwDriverInstance
, dwParam1
, dwParam2
);
1968 TRACE("=> %lu\n", ret
);
1974 /**************************************************************************
1975 * MMDRV_Alloc [internal]
1977 LPWINE_MLD
MMDRV_Alloc(UINT size
, UINT type
, LPHANDLE hndl
, DWORD
* dwFlags
,
1978 DWORD
* dwCallback
, DWORD
* dwInstance
, BOOL bFrom32
)
1982 if ((*hndl
= USER_HEAP_ALLOC(size
)) == 0)
1985 mld
= (LPWINE_MLD
) USER_HEAP_LIN_ADDR(*hndl
);
1986 if (!mld
) return NULL
;
1988 if ((UINT
)*hndl
< MMDRV_GetNum(type
) || HIWORD(*hndl
) != 0) {
1989 /* FIXME: those conditions must be fulfilled so that:
1990 * - we can distinguish between device IDs and handles
1991 * - we can use handles as 16 or 32 bit entities
1993 ERR("Shouldn't happen. Bad allocation scheme\n");
1996 mld
->bFrom32
= bFrom32
;
1997 mld
->dwFlags
= HIWORD(*dwFlags
);
1998 mld
->dwCallback
= *dwCallback
;
1999 mld
->dwClientInstance
= *dwInstance
;
2001 *dwFlags
= LOWORD(*dwFlags
) | CALLBACK_FUNCTION
;
2002 *dwCallback
= (DWORD
)llTypes
[type
].Callback
;
2003 *dwInstance
= (DWORD
)mld
; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2008 /**************************************************************************
2009 * MMDRV_Free [internal]
2011 void MMDRV_Free(HANDLE hndl
, LPWINE_MLD mld
)
2013 USER_HEAP_FREE(hndl
);
2016 /**************************************************************************
2017 * MMDRV_Open [internal]
2019 DWORD
MMDRV_Open(LPWINE_MLD mld
, UINT wMsg
, DWORD dwParam1
, DWORD dwFlags
)
2021 DWORD dwRet
= MMSYSERR_BADDEVICEID
;
2023 WINE_LLTYPE
* llType
= &llTypes
[mld
->type
];
2025 mld
->dwDriverInstance
= (DWORD
)&dwInstance
;
2027 if (mld
->uDeviceID
== (UINT
)-1 || mld
->uDeviceID
== (UINT16
)-1) {
2028 TRACE("MAPPER mode requested !\n");
2029 /* check if mapper is supported by type */
2030 if (llType
->bSupportMapper
) {
2031 if (llType
->nMapper
== -1) {
2032 /* no driver for mapper has been loaded, try a dumb implementation */
2033 TRACE("No mapper loaded, doing it by hand\n");
2034 for (mld
->uDeviceID
= 0; mld
->uDeviceID
< llType
->wMaxId
; mld
->uDeviceID
++) {
2035 if ((dwRet
= MMDRV_Open(mld
, wMsg
, dwParam1
, dwFlags
)) == MMSYSERR_NOERROR
) {
2036 /* to share this function epilog */
2037 dwInstance
= mld
->dwDriverInstance
;
2042 mld
->uDeviceID
= (UINT16
)-1;
2043 mld
->mmdIndex
= llType
->lpMlds
[-1].mmdIndex
;
2044 TRACE("Setting mmdIndex to %u\n", mld
->mmdIndex
);
2045 dwRet
= MMDRV_Message(mld
, wMsg
, dwParam1
, dwFlags
, TRUE
);
2049 if (mld
->uDeviceID
< llType
->wMaxId
) {
2050 mld
->mmdIndex
= llType
->lpMlds
[mld
->uDeviceID
].mmdIndex
;
2051 TRACE("Setting mmdIndex to %u\n", mld
->mmdIndex
);
2052 dwRet
= MMDRV_Message(mld
, wMsg
, dwParam1
, dwFlags
, TRUE
);
2055 if (dwRet
== MMSYSERR_NOERROR
)
2056 mld
->dwDriverInstance
= dwInstance
;
2060 /**************************************************************************
2061 * MMDRV_Close [internal]
2063 DWORD
MMDRV_Close(LPWINE_MLD mld
, UINT wMsg
)
2065 return MMDRV_Message(mld
, wMsg
, 0L, 0L, TRUE
);
2068 /**************************************************************************
2069 * MMDRV_GetByID [internal]
2071 LPWINE_MLD
MMDRV_GetByID(UINT uDevID
, UINT type
)
2073 if (uDevID
< llTypes
[type
].wMaxId
)
2074 return &llTypes
[type
].lpMlds
[uDevID
];
2075 if ((uDevID
== (UINT16
)-1 || uDevID
== (UINT
)-1) && llTypes
[type
].nMapper
!= -1)
2076 return &llTypes
[type
].lpMlds
[-1];
2080 /**************************************************************************
2081 * MMDRV_Get [internal]
2083 LPWINE_MLD
MMDRV_Get(HANDLE hndl
, UINT type
, BOOL bCanBeID
)
2085 LPWINE_MLD mld
= NULL
;
2087 assert(type
< MMDRV_MAX
);
2089 if ((UINT
)hndl
>= llTypes
[type
].wMaxId
) {
2090 mld
= (LPWINE_MLD
)USER_HEAP_LIN_ADDR(hndl
);
2092 if (!IsBadWritePtr(mld
, sizeof(*mld
)) && mld
->type
!= type
) mld
= NULL
;
2094 if (mld
== NULL
&& bCanBeID
) {
2095 mld
= MMDRV_GetByID((UINT
)hndl
, type
);
2100 /**************************************************************************
2101 * MMDRV_GetRelated [internal]
2103 LPWINE_MLD
MMDRV_GetRelated(HANDLE hndl
, UINT srcType
,
2104 BOOL bSrcCanBeID
, UINT dstType
)
2108 if ((mld
= MMDRV_Get(hndl
, srcType
, bSrcCanBeID
)) != NULL
) {
2109 WINE_MM_DRIVER_PART
* part
= &MMDrvs
[mld
->mmdIndex
].parts
[dstType
];
2110 if (part
->nIDMin
< part
->nIDMax
)
2111 return MMDRV_GetByID(part
->nIDMin
, dstType
);
2116 /**************************************************************************
2117 * MMDRV_PhysicalFeatures [internal]
2119 UINT
MMDRV_PhysicalFeatures(LPWINE_MLD mld
, UINT uMsg
, DWORD dwParam1
,
2122 WINE_MM_DRIVER
* lpDrv
= &MMDrvs
[mld
->mmdIndex
];
2124 TRACE("(%p, %04x, %08lx, %08lx)\n", mld
, uMsg
, dwParam1
, dwParam2
);
2126 /* all those function calls are undocumented */
2128 case 0x801: /* DRV_QUERYDRVENTRY */
2129 lstrcpynA((LPSTR
)dwParam1
, lpDrv
->name
, LOWORD(dwParam2
));
2131 case 0x802: /* DRV_QUERYDEVNODE */
2132 *(LPDWORD
)dwParam1
= 0L; /* should be DevNode */
2134 case 0x803: /* DRV_QUERYNAME */
2135 WARN("NIY 0x803\n");
2137 case 0x804: /* DRV_QUERYDRIVERIDS */
2138 WARN("NIY call VxD\n");
2139 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2140 * dwParam1 is buffer and dwParam2 is sizeof buffer
2141 * I don't know where the result is stored though
2144 case 0x805: /* DRV_QUERYMAPPABLE */
2145 return (lpDrv
->bIsMapper
) ? 2 : 0;
2147 WARN("Unknown call %04x\n", uMsg
);
2148 return MMSYSERR_INVALPARAM
;
2153 /**************************************************************************
2154 * MMDRV_InitPerType [internal]
2156 static BOOL
MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv
, UINT num
,
2157 UINT type
, UINT wMsg
)
2159 WINE_MM_DRIVER_PART
* part
= &lpDrv
->parts
[type
];
2164 part
->nIDMin
= part
->nIDMax
= 0;
2166 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2167 /* the DRVM_ENABLE is only required when the PnP node is non zero */
2169 if (lpDrv
->bIs32
&& part
->u
.fnMessage32
) {
2170 ret
= part
->u
.fnMessage32(0, DRVM_INIT
, 0L, 0L, 0L);
2171 TRACE("DRVM_INIT => %08lx\n", ret
);
2173 ret
= part
->u
.fnMessage32(0, DRVM_ENABLE
, 0L, 0L, 0L);
2174 TRACE("DRVM_ENABLE => %08lx\n", ret
);
2176 count
= part
->u
.fnMessage32(0, wMsg
, 0L, 0L, 0L);
2179 if (!lpDrv
->bIs32
&& part
->u
.fnMessage16
) {
2180 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2181 0, DRVM_INIT
, 0L, 0L, 0L);
2182 TRACE("DRVM_INIT => %08lx\n", ret
);
2184 ret
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2185 0, DRVM_ENABLE
, 0L, 0L, 0L);
2186 TRACE("DRVM_ENABLE => %08lx\n", ret
);
2188 count
= MMDRV_CallTo16_word_wwlll((FARPROC16
)part
->u
.fnMessage16
,
2189 0, wMsg
, 0L, 0L, 0L);
2192 TRACE("Got %u dev for (%s:%s)\n", count
, lpDrv
->name
, llTypes
[type
].name
);
2196 /* got some drivers */
2197 if (lpDrv
->bIsMapper
) {
2198 if (llTypes
[type
].nMapper
!= -1)
2199 ERR("Two mappers for type %s (%d, %s)\n",
2200 llTypes
[type
].name
, llTypes
[type
].nMapper
, lpDrv
->name
);
2202 ERR("Strange: mapper with %d > 1 devices\n", count
);
2203 llTypes
[type
].nMapper
= num
;
2205 part
->nIDMin
= llTypes
[type
].wMaxId
;
2206 llTypes
[type
].wMaxId
+= count
;
2207 part
->nIDMax
= llTypes
[type
].wMaxId
;
2209 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2210 part
->nIDMin
, part
->nIDMax
, llTypes
[type
].wMaxId
,
2211 lpDrv
->name
, llTypes
[type
].name
);
2212 /* realloc translation table */
2213 llTypes
[type
].lpMlds
= (LPWINE_MLD
)
2214 HeapReAlloc(SystemHeap
, 0, (llTypes
[type
].lpMlds
) ? llTypes
[type
].lpMlds
- 1 : NULL
,
2215 sizeof(WINE_MLD
) * (llTypes
[type
].wMaxId
+ 1)) + 1;
2216 /* re-build the translation table */
2217 if (llTypes
[type
].nMapper
!= -1) {
2218 TRACE("%s:Trans[%d] -> %s\n", llTypes
[type
].name
, -1, MMDrvs
[llTypes
[type
].nMapper
].name
);
2219 llTypes
[type
].lpMlds
[-1].uDeviceID
= (UINT16
)-1;
2220 llTypes
[type
].lpMlds
[-1].type
= type
;
2221 llTypes
[type
].lpMlds
[-1].mmdIndex
= llTypes
[type
].nMapper
;
2222 llTypes
[type
].lpMlds
[-1].dwDriverInstance
= 0;
2224 for (i
= k
= 0; i
<= num
; i
++) {
2225 while (MMDrvs
[i
].parts
[type
].nIDMin
<= k
&& k
< MMDrvs
[i
].parts
[type
].nIDMax
) {
2226 TRACE("%s:Trans[%d] -> %s\n", llTypes
[type
].name
, k
, MMDrvs
[i
].name
);
2227 llTypes
[type
].lpMlds
[k
].uDeviceID
= k
;
2228 llTypes
[type
].lpMlds
[k
].type
= type
;
2229 llTypes
[type
].lpMlds
[k
].mmdIndex
= i
;
2230 llTypes
[type
].lpMlds
[k
].dwDriverInstance
= 0;
2237 /**************************************************************************
2238 * MMDRV_Install [internal]
2240 static BOOL
MMDRV_Install(LPCSTR name
, int num
, BOOL bIsMapper
)
2245 LPWINE_MM_DRIVER lpDrv
= &MMDrvs
[num
];
2247 TRACE("('%s');\n", name
);
2249 memset(lpDrv
, 0, sizeof(*lpDrv
));
2251 /* First load driver */
2252 if ((lpDrv
->hDrvr
= OpenDriverA(name
, 0, 0)) == 0) {
2253 WARN("Couldn't open driver '%s'\n", name
);
2257 /* Then look for xxxMessage functions */
2258 #define AA(_w,_x,_y,_z) \
2259 func = (WINEMM_msgFunc##_y) _z (hModule, #_x); \
2261 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2262 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2264 if ((GetDriverFlags(lpDrv
->hDrvr
) & (WINE_GDF_EXIST
|WINE_GDF_16BIT
)) == WINE_GDF_EXIST
) {
2265 WINEMM_msgFunc32 func
;
2267 lpDrv
->bIs32
= TRUE
;
2268 if ((hModule
= GetDriverModuleHandle(lpDrv
->hDrvr
))) {
2269 #define A(_x,_y) AA(_x,_y,32,GetProcAddress)
2270 A(MMDRV_AUX
, auxMessage
);
2271 A(MMDRV_MIXER
, mixMessage
);
2272 A(MMDRV_MIDIIN
, midMessage
);
2273 A(MMDRV_MIDIOUT
, modMessage
);
2274 A(MMDRV_WAVEIN
, widMessage
);
2275 A(MMDRV_WAVEOUT
, wodMessage
);
2279 WINEMM_msgFunc16 func
;
2282 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2283 * The beginning of the module description indicates the driver supports
2284 * waveform, auxiliary, and mixer devices. Use one of the following
2285 * device-type names, followed by a colon (:) to indicate the type of
2286 * device your driver supports. If the driver supports more than one
2287 * type of device, separate each device-type name with a comma (,).
2289 * wave for waveform audio devices
2290 * wavemapper for wave mappers
2291 * midi for MIDI audio devices
2292 * midimapper for midi mappers
2293 * aux for auxiliary audio devices
2294 * mixer for mixer devices
2297 lpDrv
->bIs32
= FALSE
;
2298 if ((hModule
= GetDriverModuleHandle16(lpDrv
->hDrvr
))) {
2299 #define A(_x,_y) AA(_x,_y,16,WIN32_GetProcAddress16)
2300 A(MMDRV_AUX
, auxMessage
);
2301 A(MMDRV_MIXER
, mixMessage
);
2302 A(MMDRV_MIDIIN
, midMessage
);
2303 A(MMDRV_MIDIOUT
, modMessage
);
2304 A(MMDRV_WAVEIN
, widMessage
);
2305 A(MMDRV_WAVEOUT
, wodMessage
);
2311 if (TRACE_ON(mmsys
)) {
2312 if ((lpDrv
->bIs32
) ? MMDRV_GetDescription32(name
, buffer
, sizeof(buffer
)) :
2313 MMDRV_GetDescription16(name
, buffer
, sizeof(buffer
)))
2314 TRACE("%s => %s\n", name
, buffer
);
2316 TRACE("%s => No description\n", name
);
2320 CloseDriver(lpDrv
->hDrvr
, 0, 0);
2321 WARN("No message functions found\n");
2325 /* FIXME: being a mapper or not should be known by another way */
2326 /* it's known for NE drvs (the description is of the form '*mapper: *'
2327 * I don't have any clue for PE drvs
2328 * on Win 9x, the value is gotten from the key mappable under
2329 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\MediaResources\
2331 lpDrv
->bIsMapper
= bIsMapper
;
2332 lpDrv
->name
= HEAP_strdupA(GetProcessHeap(), 0, name
);
2334 /* Finish init and get the count of the devices */
2335 MMDRV_InitPerType(lpDrv
, num
, MMDRV_AUX
, AUXDM_GETNUMDEVS
);
2336 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIXER
, MXDM_GETNUMDEVS
);
2337 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIDIIN
, MIDM_GETNUMDEVS
);
2338 MMDRV_InitPerType(lpDrv
, num
, MMDRV_MIDIOUT
, MODM_GETNUMDEVS
);
2339 MMDRV_InitPerType(lpDrv
, num
, MMDRV_WAVEIN
, WIDM_GETNUMDEVS
);
2340 MMDRV_InitPerType(lpDrv
, num
, MMDRV_WAVEOUT
, WODM_GETNUMDEVS
);
2341 /* FIXME: if all those func calls return FALSE, then the driver must be unloaded */
2345 /**************************************************************************
2346 * MMDRV_Init [internal]
2348 BOOL
MMDRV_Init(void)
2352 /* FIXME: this should be moved to init files;
2353 * - either .winerc/wine.conf
2354 * - or made of registry keys
2355 * this is a temporary hack, shall be removed anytime now
2357 /* first load hardware drivers */
2358 if (MMDRV_Install("wineoss.drv", num
, FALSE
)) num
++;
2360 /* finish with mappers */
2361 if (MMDRV_Install("msacm.drv", num
, TRUE
)) num
++;
2362 if (MMDRV_Install("midimap.drv", num
, TRUE
)) num
++;
2365 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2366 * if not just increase size of MMDrvs */
2367 assert(num
<= sizeof(MMDrvs
)/sizeof(MMDrvs
[0]));