winmm split

Eric Pouech eric.pouech at wanadoo.fr
Sat Oct 26 14:44:05 CDT 2002


this (3rd) patch implements the low level multimedia message mapping

A+
-------------- next part --------------
--- ../winmm_m/lolvldrv.c	Sat Oct 26 15:06:40 2002
+++ lolvldrv.c	Sat Oct 26 19:22:16 2002
@@ -31,31 +31,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
 
-typedef	DWORD	(CALLBACK *WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
-typedef	DWORD	(CALLBACK *WINEMM_msgFunc32)(UINT  , UINT, DWORD, DWORD, DWORD);
-
-/* for each loaded driver and each known type of driver, this structure contains
- * the information needed to access it
- */
-typedef struct tagWINE_MM_DRIVER_PART {
-    int				nIDMin;		/* lower bound of global indexes for this type */
-    int				nIDMax;		/* hhigher bound of global indexes for this type */
-    union {
-	WINEMM_msgFunc32	fnMessage32;	/* pointer to fonction */
-	WINEMM_msgFunc16	fnMessage16;
-    } u;
-} WINE_MM_DRIVER_PART;
-
-/* each low-level .drv will be associated with an instance of this structure */
-typedef struct tagWINE_MM_DRIVER {
-    HDRVR			hDriver;
-    LPSTR			drvname;	/* name of the driver */
-    BOOL			bIs32 : 1,	/* TRUE if 32 bit driver, FALSE for 16 */
-	                        bIsMapper : 1;	/* TRUE if mapper */
-    WINE_MM_DRIVER_PART		parts[MMDRV_MAX];/* Information for all known types */
-} WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
-
-typedef	WINMM_MapType	(*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
 
 /* each known type of driver has an instance of this structure */
 typedef struct tagWINE_LLTYPE {
@@ -78,44 +54,13 @@
 static LPWINE_MLD	MM_MLDrvs[40];
 #define MAX_MM_MLDRVS	(sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
 
-/* ### start build ### */
-extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
-/* ### stop build ### */
-
-/**************************************************************************
- * 				MMDRV_GetDescription16		[internal]
+/******************************************************************
+ *		MMDRV_Is32
+ *
  */
-static	BOOL	MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
+BOOL                    MMDRV_Is32(unsigned int idx)
 {
-    OFSTRUCT   	ofs;
-    HFILE	hFile;
-    WORD 	w;
-    DWORD	dw;
-    BOOL	ret = FALSE;
-
-    if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
-	ERR("Can't open file %s (builtin driver ?)\n", fname);
-	return FALSE;
-    }
-
-#define E(_x)	do {TRACE _x;goto theEnd;} while(0)
-
-    if (_lread(hFile, &w, 2) != 2)			E(("Can't read sig\n"));
-    if (w != ('Z' * 256 + 'M')) 			E(("Bad sig %04x\n", w));
-    if (_llseek(hFile, 0x3C, SEEK_SET) < 0) 		E(("Can't seek to ext header offset\n"));
-    if (_lread(hFile, &dw, 4) != 4)			E(("Can't read ext header offset\n"));
-    if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) 	E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
-    if (_lread(hFile, &dw, 4) != 4)			E(("Can't read nr table offset\n"));
-    if (_llseek(hFile, dw, SEEK_SET) < 0) 		E(("Can't seek to nr table %lu\n", dw));
-    if (_lread(hFile, buf, 1) != 1)			E(("Can't read descr length\n"));
-    buflen = min((int)(unsigned)(BYTE)buf[0], buflen - 1);
-    if (_lread(hFile, buf, buflen) != buflen)		E(("Can't read descr (%d)\n", buflen));
-    buf[buflen] = '\0';
-    ret = TRUE;
-    TRACE("Got '%s' [%d]\n", buf, buflen);
-theEnd:
-    CloseHandle(hFile);
-    return ret;
+    return MMDrvs[idx].bIs32;
 }
 
 /**************************************************************************
@@ -177,1692 +122,6 @@
     HeapFree(GetProcessHeap(), 0, ptr);
     if (hmodule) FreeLibrary( hmodule );
     return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_Callback			[internal]
- */
-static void	MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
-{
-    TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
-	  mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
-
-    if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
-	/* 16 bit func, call it */
-	TRACE("Function (16 bit) !\n");
-	MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, HDRVR_16(hDev), uMsg,
-				  mld->dwClientInstance, dwParam1, dwParam2);
-    } else {
-	DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
-		       mld->dwClientInstance, dwParam1, dwParam2);
-    }
-}
-
-/* =================================
- *       A U X    M A P P E R S
- * ================================= */
-
-/**************************************************************************
- * 				MMDRV_Aux_Map16To32A		[internal]
- */
-static	WINMM_MapType	MMDRV_Aux_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_Aux_UnMap16To32A		[internal]
- */
-static	WINMM_MapType	MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_Aux_Map32ATo16		[internal]
- */
-static	WINMM_MapType	MMDRV_Aux_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_Aux_UnMap32ATo16		[internal]
- */
-static	WINMM_MapType	MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-#if 0
- case AUXDM_GETDEVCAPS:
-    lpCaps->wMid = ac16.wMid;
-    lpCaps->wPid = ac16.wPid;
-    lpCaps->vDriverVersion = ac16.vDriverVersion;
-    strcpy(lpCaps->szPname, ac16.szPname);
-    lpCaps->wTechnology = ac16.wTechnology;
-    lpCaps->dwSupport = ac16.dwSupport;
-#endif
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_Aux_Callback		[internal]
- */
-static void	CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
-{
-    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
-
-    FIXME("NIY\n");
-    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
-}
-
-/* =================================
- *     M I X E R  M A P P E R S
- * ================================= */
-
-/**************************************************************************
- * 				xMMDRV_Mixer_Map16To32A		[internal]
- */
-static	WINMM_MapType	MMDRV_Mixer_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_Mixer_UnMap16To32A	[internal]
- */
-static	WINMM_MapType	MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-#if 0
-    MIXERCAPSA	micA;
-    UINT	ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
-
-    if (ret == MMSYSERR_NOERROR) {
-	mixcaps->wMid           = micA.wMid;
-	mixcaps->wPid           = micA.wPid;
-	mixcaps->vDriverVersion = micA.vDriverVersion;
-	strcpy(mixcaps->szPname, micA.szPname);
-	mixcaps->fdwSupport     = micA.fdwSupport;
-	mixcaps->cDestinations  = micA.cDestinations;
-    }
-    return ret;
-#endif
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_Mixer_Map32ATo16		[internal]
- */
-static	WINMM_MapType	MMDRV_Mixer_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_Mixer_UnMap32ATo16	[internal]
- */
-static	WINMM_MapType	MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_Mixer_Callback		[internal]
- */
-static void	CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
-{
-    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
-
-    FIXME("NIY\n");
-    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
-}
-
-/* =================================
- *   M I D I  I N    M A P P E R S
- * ================================= */
-
-/**************************************************************************
- * 				MMDRV_MidiIn_Map16To32A		[internal]
- */
-static	WINMM_MapType	MMDRV_MidiIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_MidiIn_UnMap16To32A	[internal]
- */
-static	WINMM_MapType	MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_MidiIn_Map32ATo16		[internal]
- */
-static	WINMM_MapType	MMDRV_MidiIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_MidiIn_UnMap32ATo16	[internal]
- */
-static	WINMM_MapType	MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    return WINMM_MAP_MSGERROR;
-}
-
-/**************************************************************************
- * 				MMDRV_MidiIn_Callback		[internal]
- */
-static void	CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
-{
-    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
-
-    switch (uMsg) {
-    case MIM_OPEN:
-    case MIM_CLOSE:
-	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
-
-    case MIM_DATA:
-    case MIM_MOREDATA:
-    case MIM_ERROR:
-	/* dwParam1 & dwParam2 are are data, nothing to do */
-	break;
-    case MIM_LONGDATA:
-    case MIM_LONGERROR:
-	/* dwParam1 points to a MidiHdr, work to be done !!! */
-	if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
-	    /* initial map is: 32 => 16 */
-	    LPMIDIHDR		mh16 = MapSL(dwParam1);
-	    LPMIDIHDR		mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
-
-	    dwParam1 = (DWORD)mh32;
-	    mh32->dwFlags = mh16->dwFlags;
-	    mh32->dwBytesRecorded = mh16->dwBytesRecorded;
-	    if (mh32->reserved >= sizeof(MIDIHDR))
-		mh32->dwOffset = mh16->dwOffset;
-	} else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
-	    /* initial map is: 16 => 32 */
-	    LPMIDIHDR		mh32 = (LPMIDIHDR)(dwParam1);
-	    SEGPTR		segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
-	    LPMIDIHDR		mh16 = MapSL(segmh16);
-
-	    dwParam1 = (DWORD)segmh16;
-	    mh16->dwFlags = mh32->dwFlags;
-	    mh16->dwBytesRecorded = mh32->dwBytesRecorded;
-	    if (mh16->reserved >= sizeof(MIDIHDR))
-		mh16->dwOffset = mh32->dwOffset;
-	}
-	/* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
-	break;
-    /* case MOM_POSITIONCB: */
-    default:
-	ERR("Unknown msg %u\n", uMsg);
-    }
-
-    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
-}
-
-/* =================================
- *   M I D I  O U T  M A P P E R S
- * ================================= */
-
-/**************************************************************************
- * 				MMDRV_MidiOut_Map16To32A	[internal]
- */
-static	WINMM_MapType	MMDRV_MidiOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    case MODM_GETNUMDEVS:
-    case MODM_DATA:
-    case MODM_RESET:
-    case MODM_SETVOLUME:
-	ret = WINMM_MAP_OK;
-	break;
-
-    case MODM_OPEN:
-    case MODM_CLOSE:
-    case MODM_GETVOLUME:
-	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
-	break;
-
-    case MODM_GETDEVCAPS:
-	{
-            LPMIDIOUTCAPSA	moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
-	    LPMIDIOUTCAPS16	moc16 = MapSL(*lpParam1);
-
-	    if (moc32) {
-		*(LPMIDIOUTCAPS16*)moc32 = moc16;
-		moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
-		*lpParam1 = (DWORD)moc32;
-		*lpParam2 = sizeof(MIDIOUTCAPSA);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case MODM_PREPARE:
-	{
-	    LPMIDIHDR		mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
-	    LPMIDIHDR		mh16 = MapSL(*lpParam1);
-
-	    if (mh32) {
-		*(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
-		mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
-		mh32->lpData = MapSL((SEGPTR)mh16->lpData);
-		mh32->dwBufferLength = mh16->dwBufferLength;
-		mh32->dwBytesRecorded = mh16->dwBytesRecorded;
-		mh32->dwUser = mh16->dwUser;
-		mh32->dwFlags = mh16->dwFlags;
-		/* FIXME: nothing on mh32->lpNext */
-		/* could link the mh32->lpNext at this level for memory house keeping */
-		mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
-		mh16->lpNext = mh32; /* for reuse in unprepare and write */
-		/* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
-		mh16->reserved = *lpParam2;
-		*lpParam1 = (DWORD)mh32;
-		*lpParam2 = sizeof(MIDIHDR);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case MODM_UNPREPARE:
-    case MODM_LONGDATA:
-	{
-	    LPMIDIHDR		mh16 = MapSL(*lpParam1);
-	    LPMIDIHDR		mh32 = (LPMIDIHDR)mh16->lpNext;
-
-	    *lpParam1 = (DWORD)mh32;
-	    *lpParam2 = sizeof(MIDIHDR);
-	    /* dwBufferLength can be reduced between prepare & write */
-	    if (wMsg == MODM_LONGDATA && mh32->dwBufferLength < mh16->dwBufferLength) {
-		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
-		    mh32->dwBufferLength, mh16->dwBufferLength);
-	    } else
-                mh32->dwBufferLength = mh16->dwBufferLength;
-	    ret = WINMM_MAP_OKMEM;
-	}
-	break;
-
-    case MODM_CACHEPATCHES:
-    case MODM_CACHEDRUMPATCHES:
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_MidiOut_UnMap16To32A	[internal]
- */
-static	WINMM_MapType	MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    case MODM_GETNUMDEVS:
-    case MODM_DATA:
-    case MODM_RESET:
-    case MODM_SETVOLUME:
-	ret = WINMM_MAP_OK;
-	break;
-
-    case MODM_OPEN:
-    case MODM_CLOSE:
-    case MODM_GETVOLUME:
-	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
-	break;
-
-    case MODM_GETDEVCAPS:
-	{
-            LPMIDIOUTCAPSA		moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
-	    LPMIDIOUTCAPS16		moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
-
-	    moc16->wMid			= moc32->wMid;
-	    moc16->wPid			= moc32->wPid;
-	    moc16->vDriverVersion	= moc32->vDriverVersion;
-	    strcpy(moc16->szPname, moc32->szPname);
-	    moc16->wTechnology		= moc32->wTechnology;
-	    moc16->wVoices		= moc32->wVoices;
-	    moc16->wNotes		= moc32->wNotes;
-	    moc16->wChannelMask		= moc32->wChannelMask;
-	    moc16->dwSupport		= moc32->dwSupport;
-	    HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case MODM_PREPARE:
-    case MODM_UNPREPARE:
-    case MODM_LONGDATA:
-	{
-	    LPMIDIHDR		mh32 = (LPMIDIHDR)(*lpParam1);
-	    LPMIDIHDR		mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
-
-	    assert(mh16->lpNext == mh32);
-	    mh16->dwBufferLength = mh32->dwBufferLength;
-	    mh16->dwBytesRecorded = mh32->dwBytesRecorded;
-	    mh16->dwUser = mh32->dwUser;
-	    mh16->dwFlags = mh32->dwFlags;
-	    if (mh16->reserved >= sizeof(MIDIHDR))
-		mh16->dwOffset = mh32->dwOffset;
-
-	    if (wMsg == MODM_UNPREPARE) {
-		HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
-		mh16->lpNext = 0;
-	    }
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-
-    case MODM_CACHEPATCHES:
-    case MODM_CACHEDRUMPATCHES:
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_MidiOut_Map32ATo16	[internal]
- */
-static	WINMM_MapType	MMDRV_MidiOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    case MODM_CLOSE:
-    case MODM_GETNUMDEVS:
-    case MODM_DATA:
-    case MODM_RESET:
-    case MODM_SETVOLUME:
-	ret = WINMM_MAP_OK;
-	break;
-    case MODM_GETDEVCAPS:
-	{
-            LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
-            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA)+sizeof(MIDIOUTCAPS16));
-
-	    if (ptr) {
-		*(LPMIDIOUTCAPSA*)ptr = moc32;
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	    *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSA);
-	    *lpParam2 = sizeof(MIDIOUTCAPS16);
-	}
-	break;
-    case MODM_PREPARE:
-	{
-	    LPMIDIHDR		mh32 = (LPMIDIHDR)*lpParam1;
-	    LPMIDIHDR		mh16;
-	    LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
-                                    sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
-
-	    if (ptr) {
-		*(LPMIDIHDR*)ptr = mh32;
-		mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
-		*lpParam1 = MapLS(mh16);
-		mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
-		/* data will be copied on WODM_WRITE */
-		mh16->dwBufferLength = mh32->dwBufferLength;
-		mh16->dwBytesRecorded = mh32->dwBytesRecorded;
-		mh16->dwUser = mh32->dwUser;
-		mh16->dwFlags = mh32->dwFlags;
-		/* FIXME: nothing on mh32->lpNext */
-		/* could link the mh32->lpNext at this level for memory house keeping */
-		mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
-
-		mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
-		mh32->reserved = *lpParam2;
-
-		TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
-		      *lpParam1, (DWORD)mh16->lpData,
-		      mh32->dwBufferLength, (DWORD)mh32->lpData);
-		*lpParam2 = sizeof(MIDIHDR);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case MODM_UNPREPARE:
-    case MODM_LONGDATA:
-	{
-	    LPMIDIHDR		mh32 = (LPMIDIHDR)(*lpParam1);
-	    LPMIDIHDR		mh16 = (LPMIDIHDR)mh32->lpNext;
-	    LPSTR		ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
-
-	    assert(*(LPMIDIHDR*)ptr == mh32);
-
-	    if (wMsg == MODM_LONGDATA)
-		memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
-
-	    *lpParam1 = MapLS(mh16);
-	    *lpParam2 = sizeof(MIDIHDR);
-	    TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
-                  *lpParam1, (DWORD)mh16->lpData, mh32->dwBufferLength, (DWORD)mh32->lpData);
-
-	    /* dwBufferLength can be reduced between prepare & write */
-	    if (wMsg == MODM_LONGDATA && mh16->dwBufferLength < mh32->dwBufferLength) {
-		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
-		    mh16->dwBufferLength, mh32->dwBufferLength);
-	    } else
-                mh16->dwBufferLength = mh32->dwBufferLength;
-	    ret = WINMM_MAP_OKMEM;
-	}
-	break;
-    case MODM_OPEN:
-	{
-            LPMIDIOPENDESC		mod32 = (LPMIDIOPENDESC)*lpParam1;
-	    LPVOID			ptr;
-	    LPMIDIOPENDESC16		mod16;
-
-	    /* allocated data are mapped as follows:
-	       LPMIDIOPENDESC	ptr to orig lParam1
-	       DWORD		orig dwUser, which is a pointer to DWORD:driver dwInstance
-	       DWORD		dwUser passed to driver
-	       MIDIOPENDESC16	mod16: openDesc passed to driver
-	       MIDIOPENSTRMID	cIds
-	    */
-            ptr = HeapAlloc( GetProcessHeap(), 0,
-                             sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
-                             mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
-
-	    if (ptr) {
-                SEGPTR segptr = MapLS(ptr);
-		*(LPMIDIOPENDESC*)ptr = mod32;
-		*(LPDWORD)((char*)ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
-		mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
-
-		mod16->hMidi = HMIDI_16(mod32->hMidi);
-		mod16->dwCallback = mod32->dwCallback;
-		mod16->dwInstance = mod32->dwInstance;
-		mod16->dnDevNode = mod32->dnDevNode;
-		mod16->cIds = mod32->cIds;
-		memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
-
-		*lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
-		*lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case MODM_GETVOLUME:
-    case MODM_CACHEPATCHES:
-    case MODM_CACHEDRUMPATCHES:
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_MidiOut_UnMap32ATo16	[internal]
- */
-static	WINMM_MapType	MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    case MODM_CLOSE:
-    case MODM_GETNUMDEVS:
-    case MODM_DATA:
-    case MODM_RESET:
-    case MODM_SETVOLUME:
-	ret = WINMM_MAP_OK;
-	break;
-    case MODM_GETDEVCAPS:
-	{
-	    LPMIDIOUTCAPS16		moc16 = MapSL(*lpParam1);
-	    LPSTR			ptr   = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
-            LPMIDIOUTCAPSA		moc32 = *(LPMIDIOUTCAPSA*)ptr;
-
-	    moc32->wMid			= moc16->wMid;
-	    moc32->wPid			= moc16->wPid;
-	    moc32->vDriverVersion	= moc16->vDriverVersion;
-	    strcpy(moc32->szPname, moc16->szPname);
-	    moc32->wTechnology		= moc16->wTechnology;
-	    moc32->wVoices		= moc16->wVoices;
-	    moc32->wNotes		= moc16->wNotes;
-	    moc32->wChannelMask		= moc16->wChannelMask;
-	    moc32->dwSupport		= moc16->dwSupport;
-            UnMapLS( *lpParam1 );
-            HeapFree( GetProcessHeap(), 0, ptr );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case MODM_PREPARE:
-    case MODM_UNPREPARE:
-    case MODM_LONGDATA:
-	{
-	    LPMIDIHDR		mh16 = MapSL(*lpParam1);
-	    LPSTR		ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
-	    LPMIDIHDR		mh32 = *(LPMIDIHDR*)ptr;
-
-	    assert(mh32->lpNext == (LPMIDIHDR)mh16);
-            UnMapLS( *lpParam1 );
-	    mh32->dwBytesRecorded = mh16->dwBytesRecorded;
-	    mh32->dwUser = mh16->dwUser;
-	    mh32->dwFlags = mh16->dwFlags;
-
-	    if (wMsg == MODM_UNPREPARE) {
-                HeapFree( GetProcessHeap(), 0, ptr );
-		mh32->lpNext = 0;
-	    }
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case MODM_OPEN:
-	{
-	    LPMIDIOPENDESC16		mod16 = MapSL(*lpParam1);
-	    LPSTR			ptr   = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
-            UnMapLS( *lpParam1 );
-	    **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
-
-            HeapFree( GetProcessHeap(), 0, ptr );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case MODM_GETVOLUME:
-    case MODM_CACHEPATCHES:
-    case MODM_CACHEDRUMPATCHES:
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_MidiOut_Callback		[internal]
- */
-static void	CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
-{
-    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
-
-    switch (uMsg) {
-    case MOM_OPEN:
-    case MOM_CLOSE:
-	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
-	break;
-    case MOM_DONE:
-	if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
-	    /* initial map is: 32 => 16 */
-	    LPMIDIHDR		mh16 = MapSL(dwParam1);
-	    LPMIDIHDR		mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
-
-	    dwParam1 = (DWORD)mh32;
-	    mh32->dwFlags = mh16->dwFlags;
-	    mh32->dwOffset = mh16->dwOffset;
-	    if (mh32->reserved >= sizeof(MIDIHDR))
-		mh32->dwOffset = mh16->dwOffset;
-	} else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
-	    /* initial map is: 16 => 32 */
-	    LPMIDIHDR		mh32 = (LPMIDIHDR)(dwParam1);
-	    SEGPTR		segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
-	    LPMIDIHDR		mh16 = MapSL(segmh16);
-
-	    dwParam1 = (DWORD)segmh16;
-	    mh16->dwFlags = mh32->dwFlags;
-	    if (mh16->reserved >= sizeof(MIDIHDR))
-		mh16->dwOffset = mh32->dwOffset;
-	}
-	/* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
-	break;
-    /* case MOM_POSITIONCB: */
-    default:
-	ERR("Unknown msg %u\n", uMsg);
-    }
-
-    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
-}
-
-/* =================================
- *   W A V E  I N    M A P P E R S
- * ================================= */
-
-/**************************************************************************
- * 				MMDRV_WaveIn_Map16To32A		[internal]
- */
-static	WINMM_MapType	MMDRV_WaveIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    case WIDM_GETNUMDEVS:
-    case WIDM_RESET:
-    case WIDM_START:
-    case WIDM_STOP:
-	ret = WINMM_MAP_OK;
-	break;
-    case WIDM_OPEN:
-    case WIDM_CLOSE:
-	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
-	break;
-    case WIDM_GETDEVCAPS:
-	{
-            LPWAVEINCAPSA	wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
-	    LPWAVEINCAPS16	wic16 = MapSL(*lpParam1);
-
-	    if (wic32) {
-		*(LPWAVEINCAPS16*)wic32 = wic16;
-		wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
-		*lpParam1 = (DWORD)wic32;
-		*lpParam2 = sizeof(WAVEINCAPSA);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WIDM_GETPOS:
-	{
-            LPMMTIME		mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
-	    LPMMTIME16		mmt16 = MapSL(*lpParam1);
-
-	    if (mmt32) {
-		*(LPMMTIME16*)mmt32 = mmt16;
-		mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
-
-		mmt32->wType = mmt16->wType;
-		*lpParam1 = (DWORD)mmt32;
-		*lpParam2 = sizeof(MMTIME);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WIDM_PREPARE:
-	{
-	    LPWAVEHDR		wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
-	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
-
-	    if (wh32) {
-		*(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
-		wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
-		wh32->lpData = MapSL((SEGPTR)wh16->lpData);
-		wh32->dwBufferLength = wh16->dwBufferLength;
-		wh32->dwBytesRecorded = wh16->dwBytesRecorded;
-		wh32->dwUser = wh16->dwUser;
-		wh32->dwFlags = wh16->dwFlags;
-		wh32->dwLoops = wh16->dwLoops;
-		/* FIXME: nothing on wh32->lpNext */
-		/* could link the wh32->lpNext at this level for memory house keeping */
-		wh16->lpNext = wh32; /* for reuse in unprepare and write */
-		*lpParam1 = (DWORD)wh32;
-		*lpParam2 = sizeof(WAVEHDR);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WIDM_ADDBUFFER:
-    case WIDM_UNPREPARE:
-	{
-	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)wh16->lpNext;
-
-	    *lpParam1 = (DWORD)wh32;
-	    *lpParam2 = sizeof(WAVEHDR);
-	    /* dwBufferLength can be reduced between prepare & write */
-	    if (wMsg == WIDM_ADDBUFFER && wh32->dwBufferLength < wh16->dwBufferLength) {
-		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
-		    wh32->dwBufferLength, wh16->dwBufferLength);
-	    } else
-                wh32->dwBufferLength = wh16->dwBufferLength;
-	    ret = WINMM_MAP_OKMEM;
-	}
-	break;
-    case WIDM_MAPPER_STATUS:
-	/* just a single DWORD */
-	*lpParam2 = (DWORD)MapSL(*lpParam2);
-	ret = WINMM_MAP_OK;
-	break;
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_WaveIn_UnMap16To32A	[internal]
- */
-static	WINMM_MapType	MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    case WIDM_GETNUMDEVS:
-    case WIDM_RESET:
-    case WIDM_START:
-    case WIDM_STOP:
-    case WIDM_MAPPER_STATUS:
-	ret = WINMM_MAP_OK;
-	break;
-    case WIDM_OPEN:
-    case WIDM_CLOSE:
-	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
-	break;
-    case WIDM_GETDEVCAPS:
-	{
-            LPWAVEINCAPSA		wic32 = (LPWAVEINCAPSA)(*lpParam1);
-	    LPWAVEINCAPS16		wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
-
-	    wic16->wMid = wic32->wMid;
-	    wic16->wPid = wic32->wPid;
-	    wic16->vDriverVersion = wic32->vDriverVersion;
-	    strcpy(wic16->szPname, wic32->szPname);
-	    wic16->dwFormats = wic32->dwFormats;
-	    wic16->wChannels = wic32->wChannels;
-	    HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WIDM_GETPOS:
-	{
-            LPMMTIME		mmt32 = (LPMMTIME)(*lpParam1);
-	    LPMMTIME16		mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
-
-	    MMSYSTEM_MMTIME32to16(mmt16, mmt32);
-	    HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WIDM_ADDBUFFER:
-    case WIDM_PREPARE:
-    case WIDM_UNPREPARE:
-	{
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)(*lpParam1);
-	    LPWAVEHDR		wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
-
-	    assert(wh16->lpNext == wh32);
-	    wh16->dwBufferLength = wh32->dwBufferLength;
-	    wh16->dwBytesRecorded = wh32->dwBytesRecorded;
-	    wh16->dwUser = wh32->dwUser;
-	    wh16->dwFlags = wh32->dwFlags;
-	    wh16->dwLoops = wh32->dwLoops;
-
-	    if (wMsg == WIDM_UNPREPARE) {
-		HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
-		wh16->lpNext = 0;
-	    }
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_WaveIn_Map32ATo16		[internal]
- */
-static	WINMM_MapType	MMDRV_WaveIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    case WIDM_CLOSE:
-    case WIDM_GETNUMDEVS:
-    case WIDM_RESET:
-    case WIDM_START:
-    case WIDM_STOP:
-	ret = WINMM_MAP_OK;
-	break;
-
-    case WIDM_OPEN:
-	{
-            LPWAVEOPENDESC		wod32 = (LPWAVEOPENDESC)*lpParam1;
-	    int				sz = sizeof(WAVEFORMATEX);
-	    LPVOID			ptr;
-	    LPWAVEOPENDESC16		wod16;
-
-	    /* allocated data are mapped as follows:
-	       LPWAVEOPENDESC	ptr to orig lParam1
-	       DWORD		orig dwUser, which is a pointer to DWORD:driver dwInstance
-	       DWORD		dwUser passed to driver
-	       WAVEOPENDESC16	wod16: openDesc passed to driver
-	       WAVEFORMATEX	openDesc->lpFormat passed to driver
-	       xxx		extra bytes to WAVEFORMATEX
-	    */
-	    if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
-		TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
-		sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
-	    }
-
-            ptr = HeapAlloc( GetProcessHeap(), 0,
-                             sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
-
-	    if (ptr) {
-                SEGPTR seg_ptr = MapLS( ptr );
-		*(LPWAVEOPENDESC*)ptr = wod32;
-		*(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
-		wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
-
-		wod16->hWave = HWAVE_16(wod32->hWave);
-		wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
-		memcpy(wod16 + 1, wod32->lpFormat, sz);
-
-		wod16->dwCallback = wod32->dwCallback;
-		wod16->dwInstance = wod32->dwInstance;
-		wod16->uMappedDeviceID = wod32->uMappedDeviceID;
-		wod16->dnDevNode = wod32->dnDevNode;
-
-		*lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
-		*lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WIDM_PREPARE:
-	{
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)*lpParam1;
-	    LPWAVEHDR		wh16;
-	    LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
-                                    sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
-
-	    if (ptr) {
-                SEGPTR seg_ptr = MapLS( ptr );
-		*(LPWAVEHDR*)ptr = wh32;
-		wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
-		wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
-		/* data will be copied on WODM_WRITE */
-		wh16->dwBufferLength = wh32->dwBufferLength;
-		wh16->dwBytesRecorded = wh32->dwBytesRecorded;
-		wh16->dwUser = wh32->dwUser;
-		wh16->dwFlags = wh32->dwFlags;
-		wh16->dwLoops = wh32->dwLoops;
-		/* FIXME: nothing on wh32->lpNext */
-		/* could link the wh32->lpNext at this level for memory house keeping */
-		wh32->lpNext = wh16; /* for reuse in unprepare and write */
-		TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
-		      seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
-		      wh32->dwBufferLength, (DWORD)wh32->lpData);
-		*lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
-		*lpParam2 = sizeof(WAVEHDR);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WIDM_ADDBUFFER:
-    case WIDM_UNPREPARE:
- 	{
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)(*lpParam1);
-	    LPWAVEHDR		wh16 = wh32->lpNext;
-	    LPSTR		ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
-            SEGPTR seg_ptr = MapLS( ptr );
-
-	    assert(*(LPWAVEHDR*)ptr == wh32);
-
-	    TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
-		  seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
-		  wh32->dwBufferLength, (DWORD)wh32->lpData);
-
-	    if (wMsg == WIDM_ADDBUFFER)
-		memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
-
-	    *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
-	    *lpParam2 = sizeof(WAVEHDR);
-	    /* dwBufferLength can be reduced between prepare & write */
-	    if (wMsg == WIDM_ADDBUFFER && wh16->dwBufferLength < wh32->dwBufferLength) {
-		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
-		    wh16->dwBufferLength, wh32->dwBufferLength);
-	    } else
-                wh16->dwBufferLength = wh32->dwBufferLength;
-	    ret = WINMM_MAP_OKMEM;
-	}
-	break;
-   case WIDM_GETDEVCAPS:
-	{
-            LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
-            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
-
-	    if (ptr) {
-		*(LPWAVEINCAPSA*)ptr = wic32;
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	    *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSA);
-	    *lpParam2 = sizeof(WAVEINCAPS16);
-	}
-	break;
-    case WIDM_GETPOS:
- 	{
-            LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
-            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
-            LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
-
-	    if (ptr) {
-		*(LPMMTIME*)ptr = mmt32;
-		mmt16->wType = mmt32->wType;
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	    *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
-	    *lpParam2 = sizeof(MMTIME16);
-	}
-	break;
-    case DRVM_MAPPER_STATUS:
- 	{
-            LPDWORD p32 = (LPDWORD)*lpParam2;
-            *lpParam2 = MapLS(p32);
-            ret = WINMM_MAP_OKMEM;
-	}
-	break;
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_WaveIn_UnMap32ATo16	[internal]
- */
-static	WINMM_MapType	MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    case WIDM_CLOSE:
-    case WIDM_GETNUMDEVS:
-    case WIDM_RESET:
-    case WIDM_START:
-    case WIDM_STOP:
-	ret = WINMM_MAP_OK;
-	break;
-
-    case WIDM_OPEN:
-	{
-	    LPWAVEOPENDESC16		wod16 = MapSL(*lpParam1);
-	    LPSTR			ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
-            LPWAVEOPENDESC		wod32 = *(LPWAVEOPENDESC*)ptr;
-
-            UnMapLS( *lpParam1 );
-	    wod32->uMappedDeviceID = wod16->uMappedDeviceID;
-	    **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
-            HeapFree( GetProcessHeap(), 0, ptr );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-
-    case WIDM_ADDBUFFER:
-    case WIDM_PREPARE:
-    case WIDM_UNPREPARE:
-	{
-	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
-	    LPSTR		ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
-	    LPWAVEHDR		wh32 = *(LPWAVEHDR*)ptr;
-
-	    assert(wh32->lpNext == wh16);
-	    wh32->dwBytesRecorded = wh16->dwBytesRecorded;
-	    wh32->dwUser = wh16->dwUser;
-	    wh32->dwFlags = wh16->dwFlags;
-	    wh32->dwLoops = wh16->dwLoops;
-            UnMapLS( *lpParam1 );
-
-	    if (wMsg == WIDM_UNPREPARE) {
-                HeapFree( GetProcessHeap(), 0, ptr );
-		wh32->lpNext = 0;
-	    }
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-     case WIDM_GETDEVCAPS:
-	{
-	    LPWAVEINCAPS16		wic16 = MapSL(*lpParam1);
-	    LPSTR			ptr   = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
-            LPWAVEINCAPSA		wic32 = *(LPWAVEINCAPSA*)ptr;
-
-	    wic32->wMid = wic16->wMid;
-	    wic32->wPid = wic16->wPid;
-	    wic32->vDriverVersion = wic16->vDriverVersion;
-	    strcpy(wic32->szPname, wic16->szPname);
-	    wic32->dwFormats = wic16->dwFormats;
-	    wic32->wChannels = wic16->wChannels;
-            UnMapLS( *lpParam1 );
-            HeapFree( GetProcessHeap(), 0, ptr );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WIDM_GETPOS:
-	{
-	    LPMMTIME16		mmt16 = MapSL(*lpParam1);
-	    LPSTR		ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
-            LPMMTIME		mmt32 = *(LPMMTIME*)ptr;
-
-	    MMSYSTEM_MMTIME16to32(mmt32, mmt16);
-            UnMapLS( *lpParam1 );
-            HeapFree( GetProcessHeap(), 0, ptr );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case DRVM_MAPPER_STATUS:
-	{
-            UnMapLS( *lpParam2 );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_WaveIn_Callback		[internal]
- */
-static void	CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
-{
-    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
-
-    switch (uMsg) {
-    case WIM_OPEN:
-    case WIM_CLOSE:
-	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
-	break;
-    case WIM_DATA:
-	if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
-	    /* initial map is: 32 => 16 */
-	    LPWAVEHDR		wh16 = MapSL(dwParam1);
-	    LPWAVEHDR		wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
-
-	    dwParam1 = (DWORD)wh32;
-	    wh32->dwFlags = wh16->dwFlags;
-	    wh32->dwBytesRecorded = wh16->dwBytesRecorded;
-	} else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
-	    /* initial map is: 16 => 32 */
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)(dwParam1);
-	    SEGPTR		segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
-	    LPWAVEHDR		wh16 = MapSL(segwh16);
-
-	    dwParam1 = (DWORD)segwh16;
-	    wh16->dwFlags = wh32->dwFlags;
-	    wh16->dwBytesRecorded = wh32->dwBytesRecorded;
-	}
-	/* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
-	break;
-    default:
-	ERR("Unknown msg %u\n", uMsg);
-    }
-
-    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
-}
-
-/* =================================
- *   W A V E  O U T  M A P P E R S
- * ================================= */
-
-/**************************************************************************
- * 				MMDRV_WaveOut_Map16To32A	[internal]
- */
-static	WINMM_MapType	MMDRV_WaveOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    /* nothing to do */
-    case WODM_BREAKLOOP:
-    case WODM_CLOSE:
-    case WODM_GETNUMDEVS:
-    case WODM_PAUSE:
-    case WODM_RESET:
-    case WODM_RESTART:
-    case WODM_SETPITCH:
-    case WODM_SETPLAYBACKRATE:
-    case WODM_SETVOLUME:
-	ret = WINMM_MAP_OK;
-	break;
-
-    case WODM_GETPITCH:
-    case WODM_GETPLAYBACKRATE:
-    case WODM_GETVOLUME:
-    case WODM_OPEN:
-	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
-	break;
-
-    case WODM_GETDEVCAPS:
-	{
-            LPWAVEOUTCAPSA		woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
-	    LPWAVEOUTCAPS16		woc16 = MapSL(*lpParam1);
-
-	    if (woc32) {
-		*(LPWAVEOUTCAPS16*)woc32 = woc16;
-		woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
-		*lpParam1 = (DWORD)woc32;
-		*lpParam2 = sizeof(WAVEOUTCAPSA);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WODM_GETPOS:
-	{
-            LPMMTIME		mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
-	    LPMMTIME16		mmt16 = MapSL(*lpParam1);
-
-	    if (mmt32) {
-		*(LPMMTIME16*)mmt32 = mmt16;
-		mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
-
-		mmt32->wType = mmt16->wType;
-		*lpParam1 = (DWORD)mmt32;
-		*lpParam2 = sizeof(MMTIME);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WODM_PREPARE:
-	{
-	    LPWAVEHDR		wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
-	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
-
-	    if (wh32) {
-		*(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
-		wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
-		wh32->lpData = MapSL((SEGPTR)wh16->lpData);
-		wh32->dwBufferLength = wh16->dwBufferLength;
-		wh32->dwBytesRecorded = wh16->dwBytesRecorded;
-		wh32->dwUser = wh16->dwUser;
-		wh32->dwFlags = wh16->dwFlags;
-		wh32->dwLoops = wh16->dwLoops;
-		/* FIXME: nothing on wh32->lpNext */
-		/* could link the wh32->lpNext at this level for memory house keeping */
-		wh16->lpNext = wh32; /* for reuse in unprepare and write */
-		*lpParam1 = (DWORD)wh32;
-		*lpParam2 = sizeof(WAVEHDR);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WODM_UNPREPARE:
-    case WODM_WRITE:
-	{
-	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)wh16->lpNext;
-
-	    *lpParam1 = (DWORD)wh32;
-	    *lpParam2 = sizeof(WAVEHDR);
-	    /* dwBufferLength can be reduced between prepare & write */
-	    if (wMsg == WODM_WRITE && wh32->dwBufferLength < wh16->dwBufferLength) {
-		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
-		    wh32->dwBufferLength, wh16->dwBufferLength);
-	    } else
-                wh32->dwBufferLength = wh16->dwBufferLength;
-	    ret = WINMM_MAP_OKMEM;
-	}
-	break;
-    case WODM_MAPPER_STATUS:
-	*lpParam2 = (DWORD)MapSL(*lpParam2);
-	ret = WINMM_MAP_OK;
-	break;
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_WaveOut_UnMap16To32A	[internal]
- */
-static	WINMM_MapType	MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
-
-    switch (wMsg) {
-    /* nothing to do */
-    case WODM_BREAKLOOP:
-    case WODM_CLOSE:
-    case WODM_GETNUMDEVS:
-    case WODM_PAUSE:
-    case WODM_RESET:
-    case WODM_RESTART:
-    case WODM_SETPITCH:
-    case WODM_SETPLAYBACKRATE:
-    case WODM_SETVOLUME:
-    case WODM_MAPPER_STATUS:
-	ret = WINMM_MAP_OK;
-	break;
-
-    case WODM_GETPITCH:
-    case WODM_GETPLAYBACKRATE:
-    case WODM_GETVOLUME:
-    case WODM_OPEN:
-	FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
-	break;
-
-    case WODM_GETDEVCAPS:
-	{
-            LPWAVEOUTCAPSA		woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
-	    LPWAVEOUTCAPS16		woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
-
-	    woc16->wMid = woc32->wMid;
-	    woc16->wPid = woc32->wPid;
-	    woc16->vDriverVersion = woc32->vDriverVersion;
-	    strcpy(woc16->szPname, woc32->szPname);
-	    woc16->dwFormats = woc32->dwFormats;
-	    woc16->wChannels = woc32->wChannels;
-	    woc16->dwSupport = woc32->dwSupport;
-	    HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WODM_GETPOS:
-	{
-            LPMMTIME		mmt32 = (LPMMTIME)(*lpParam1);
-	    LPMMTIME16		mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
-
-	    MMSYSTEM_MMTIME32to16(mmt16, mmt32);
-	    HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WODM_PREPARE:
-    case WODM_UNPREPARE:
-    case WODM_WRITE:
-	{
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)(*lpParam1);
-	    LPWAVEHDR		wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
-
-	    assert(wh16->lpNext == wh32);
-	    wh16->dwBufferLength = wh32->dwBufferLength;
-	    wh16->dwBytesRecorded = wh32->dwBytesRecorded;
-	    wh16->dwUser = wh32->dwUser;
-	    wh16->dwFlags = wh32->dwFlags;
-	    wh16->dwLoops = wh32->dwLoops;
-
-	    if (wMsg == WODM_UNPREPARE) {
-		HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
-		wh16->lpNext = 0;
-	    }
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    default:
-	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_WaveOut_Map32ATo16	[internal]
- */
-static	WINMM_MapType	MMDRV_WaveOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret;
-
-    switch (wMsg) {
-	/* nothing to do */
-    case WODM_BREAKLOOP:
-    case WODM_CLOSE:
-    case WODM_GETNUMDEVS:
-    case WODM_PAUSE:
-    case WODM_RESET:
-    case WODM_RESTART:
-    case WODM_SETPITCH:
-    case WODM_SETPLAYBACKRATE:
-    case WODM_SETVOLUME:
-	ret = WINMM_MAP_OK;
-	break;
-
-    case WODM_GETDEVCAPS:
-	{
-            LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
-            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
-                                   sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
-
-	    if (ptr) {
-		*(LPWAVEOUTCAPSA*)ptr = woc32;
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	    *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSA);
-	    *lpParam2 = sizeof(WAVEOUTCAPS16);
-	}
-	break;
-    case WODM_GETPITCH:
-	FIXME("NIY: no conversion yet\n");
-	ret = WINMM_MAP_MSGERROR;
-	break;
-    case WODM_GETPLAYBACKRATE:
-	FIXME("NIY: no conversion yet\n");
-	ret = WINMM_MAP_MSGERROR;
-	break;
-    case WODM_GETPOS:
-	{
-            LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
-            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
-            LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
-
-	    if (ptr) {
-		*(LPMMTIME*)ptr = mmt32;
-		mmt16->wType = mmt32->wType;
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	    *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
-	    *lpParam2 = sizeof(MMTIME16);
-	}
-	break;
-    case WODM_GETVOLUME:
-	FIXME("NIY: no conversion yet\n");
-	ret = WINMM_MAP_MSGERROR;
-	break;
-    case WODM_OPEN:
-	{
-            LPWAVEOPENDESC		wod32 = (LPWAVEOPENDESC)*lpParam1;
-	    int				sz = sizeof(WAVEFORMATEX);
-	    LPVOID			ptr;
-	    LPWAVEOPENDESC16		wod16;
-
-	    /* allocated data are mapped as follows:
-	       LPWAVEOPENDESC	ptr to orig lParam1
-	       DWORD		orig dwUser, which is a pointer to DWORD:driver dwInstance
-	       DWORD		dwUser passed to driver
-	       WAVEOPENDESC16	wod16: openDesc passed to driver
-	       WAVEFORMATEX	openDesc->lpFormat passed to driver
-	       xxx		extra bytes to WAVEFORMATEX
-	    */
-	    if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
-		TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
-		sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
-	    }
-
-	    ptr = HeapAlloc( GetProcessHeap(), 0,
-                             sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
-
-	    if (ptr) {
-                SEGPTR seg_ptr = MapLS( ptr );
-		*(LPWAVEOPENDESC*)ptr = wod32;
-		*(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
-		wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
-
-		wod16->hWave = HWAVE_16(wod32->hWave);
-		wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
-		memcpy(wod16 + 1, wod32->lpFormat, sz);
-
-		wod16->dwCallback = wod32->dwCallback;
-		wod16->dwInstance = wod32->dwInstance;
-		wod16->uMappedDeviceID = wod32->uMappedDeviceID;
-		wod16->dnDevNode = wod32->dnDevNode;
-
-		*lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
-		*lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WODM_PREPARE:
-	{
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)*lpParam1;
-	    LPWAVEHDR		wh16;
-	    LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
-                                    sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
-
-	    if (ptr) {
-                SEGPTR seg_ptr = MapLS( ptr );
-		*(LPWAVEHDR*)ptr = wh32;
-		wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
-		wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
-		/* data will be copied on WODM_WRITE */
-		wh16->dwBufferLength = wh32->dwBufferLength;
-		wh16->dwBytesRecorded = wh32->dwBytesRecorded;
-		wh16->dwUser = wh32->dwUser;
-		wh16->dwFlags = wh32->dwFlags;
-		wh16->dwLoops = wh32->dwLoops;
-		/* FIXME: nothing on wh32->lpNext */
-		/* could link the wh32->lpNext at this level for memory house keeping */
-		wh32->lpNext = wh16; /* for reuse in unprepare and write */
-		TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
-		      seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
-		      wh32->dwBufferLength, (DWORD)wh32->lpData);
-		*lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
-		*lpParam2 = sizeof(WAVEHDR);
-
-		ret = WINMM_MAP_OKMEM;
-	    } else {
-		ret = WINMM_MAP_NOMEM;
-	    }
-	}
-	break;
-    case WODM_UNPREPARE:
-    case WODM_WRITE:
-	{
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)(*lpParam1);
-	    LPWAVEHDR		wh16 = wh32->lpNext;
-	    LPSTR		ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
-            SEGPTR seg_ptr = MapLS( ptr );
-
-	    assert(*(LPWAVEHDR*)ptr == wh32);
-
-	    TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
-		  seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
-		  wh32->dwBufferLength, (DWORD)wh32->lpData);
-
-	    if (wMsg == WODM_WRITE)
-		memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
-
-	    *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
-	    *lpParam2 = sizeof(WAVEHDR);
-	    /* dwBufferLength can be reduced between prepare & write */
-	    if (wMsg == WODM_WRITE && wh16->dwBufferLength < wh32->dwBufferLength) {
-		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
-		    wh16->dwBufferLength, wh32->dwBufferLength);
-	    } else
-                wh16->dwBufferLength = wh32->dwBufferLength;
-	    ret = WINMM_MAP_OKMEM;
-	}
-	break;
-    case DRVM_MAPPER_STATUS:
- 	{
-            LPDWORD p32 = (LPDWORD)*lpParam2;
-            *lpParam2 = MapLS(p32);
-            ret = WINMM_MAP_OKMEM;
-	}
-	break;
-    default:
-	FIXME("NIY: no conversion yet\n");
-	ret = WINMM_MAP_MSGERROR;
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_WaveOut_UnMap32ATo16	[internal]
- */
-static	WINMM_MapType	MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
-{
-    WINMM_MapType	ret;
-
-    switch (wMsg) {
-	/* nothing to do */
-    case WODM_BREAKLOOP:
-    case WODM_CLOSE:
-    case WODM_GETNUMDEVS:
-    case WODM_PAUSE:
-    case WODM_RESET:
-    case WODM_RESTART:
-    case WODM_SETPITCH:
-    case WODM_SETPLAYBACKRATE:
-    case WODM_SETVOLUME:
-	ret = WINMM_MAP_OK;
-	break;
-
-    case WODM_GETDEVCAPS:
-	{
-	    LPWAVEOUTCAPS16		woc16 = MapSL(*lpParam1);
-	    LPSTR			ptr   = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
-            LPWAVEOUTCAPSA		woc32 = *(LPWAVEOUTCAPSA*)ptr;
-
-	    woc32->wMid = woc16->wMid;
-	    woc32->wPid = woc16->wPid;
-	    woc32->vDriverVersion = woc16->vDriverVersion;
-	    strcpy(woc32->szPname, woc16->szPname);
-	    woc32->dwFormats = woc16->dwFormats;
-	    woc32->wChannels = woc16->wChannels;
-	    woc32->dwSupport = woc16->dwSupport;
-            UnMapLS( *lpParam1 );
-            HeapFree( GetProcessHeap(), 0, ptr );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WODM_GETPITCH:
-	FIXME("NIY: no conversion yet\n");
-	ret = WINMM_MAP_MSGERROR;
-	break;
-    case WODM_GETPLAYBACKRATE:
-	FIXME("NIY: no conversion yet\n");
-	ret = WINMM_MAP_MSGERROR;
-	break;
-    case WODM_GETPOS:
-	{
-	    LPMMTIME16		mmt16 = MapSL(*lpParam1);
-	    LPSTR		ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
-            LPMMTIME		mmt32 = *(LPMMTIME*)ptr;
-
-	    MMSYSTEM_MMTIME16to32(mmt32, mmt16);
-            UnMapLS( *lpParam1 );
-            HeapFree( GetProcessHeap(), 0, ptr );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WODM_OPEN:
-	{
-	    LPWAVEOPENDESC16		wod16 = MapSL(*lpParam1);
-	    LPSTR			ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
-            LPWAVEOPENDESC		wod32 = *(LPWAVEOPENDESC*)ptr;
-
-	    wod32->uMappedDeviceID = wod16->uMappedDeviceID;
-	    **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
-            UnMapLS( *lpParam1 );
-            HeapFree( GetProcessHeap(), 0, ptr );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WODM_PREPARE:
-    case WODM_UNPREPARE:
-    case WODM_WRITE:
-	{
-	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
-	    LPSTR		ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
-	    LPWAVEHDR		wh32 = *(LPWAVEHDR*)ptr;
-
-	    assert(wh32->lpNext == wh16);
-	    wh32->dwBytesRecorded = wh16->dwBytesRecorded;
-	    wh32->dwUser = wh16->dwUser;
-	    wh32->dwFlags = wh16->dwFlags;
-	    wh32->dwLoops = wh16->dwLoops;
-
-            UnMapLS( *lpParam1 );
-	    if (wMsg == WODM_UNPREPARE) {
-                HeapFree( GetProcessHeap(), 0, ptr );
-		wh32->lpNext = 0;
-	    }
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    case WODM_GETVOLUME:
-	FIXME("NIY: no conversion yet\n");
-	ret = WINMM_MAP_MSGERROR;
-	break;
-    case DRVM_MAPPER_STATUS:
-	{
-            UnMapLS( *lpParam2 );
-	    ret = WINMM_MAP_OK;
-	}
-	break;
-    default:
-	FIXME("NIY: no conversion yet\n");
-	ret = WINMM_MAP_MSGERROR;
-	break;
-    }
-    return ret;
-}
-
-/**************************************************************************
- * 				MMDRV_WaveOut_Callback		[internal]
- */
-static void	CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
-{
-    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
-
-    switch (uMsg) {
-    case WOM_OPEN:
-    case WOM_CLOSE:
-	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
-	break;
-    case WOM_DONE:
-	if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
-	    /* initial map is: 32 => 16 */
-	    LPWAVEHDR		wh16 = MapSL(dwParam1);
-	    LPWAVEHDR		wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
-
-	    dwParam1 = (DWORD)wh32;
-	    wh32->dwFlags = wh16->dwFlags;
-	} else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
-	    /* initial map is: 16 => 32 */
-	    LPWAVEHDR		wh32 = (LPWAVEHDR)(dwParam1);
-	    SEGPTR		segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
-	    LPWAVEHDR		wh16 = MapSL(segwh16);
-
-	    dwParam1 = (DWORD)segwh16;
-	    wh16->dwFlags = wh32->dwFlags;
-	}
-	/* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
-	break;
-    default:
-	ERR("Unknown msg %u\n", uMsg);
-    }
-
-    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
 }
 
 #define A(_x,_y) {#_y, _x, \
--- ../winmm_m/message16.c	Sat Oct 26 19:04:34 2002
+++ message16.c	Sat Oct 26 19:21:32 2002
@@ -32,6 +32,1736 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(winmm);
 
+/* ### start build ### */
+extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
+/* ### stop build ### */
+
+/**************************************************************************
+ * 				MMDRV_Callback			[internal]
+ */
+void	MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
+{
+    TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
+	  mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
+
+    if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
+	/* 16 bit func, call it */
+	TRACE("Function (16 bit) !\n");
+	MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, HDRVR_16(hDev), uMsg,
+				  mld->dwClientInstance, dwParam1, dwParam2);
+    } else {
+	DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
+		       mld->dwClientInstance, dwParam1, dwParam2);
+    }
+}
+
+/* =================================
+ *       A U X    M A P P E R S
+ * ================================= */
+
+/**************************************************************************
+ * 				MMDRV_Aux_Map16To32A		[internal]
+ */
+WINMM_MapType	MMDRV_Aux_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_Aux_UnMap16To32A		[internal]
+ */
+WINMM_MapType	MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_Aux_Map32ATo16		[internal]
+ */
+WINMM_MapType	MMDRV_Aux_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_Aux_UnMap32ATo16		[internal]
+ */
+WINMM_MapType	MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+#if 0
+ case AUXDM_GETDEVCAPS:
+    lpCaps->wMid = ac16.wMid;
+    lpCaps->wPid = ac16.wPid;
+    lpCaps->vDriverVersion = ac16.vDriverVersion;
+    strcpy(lpCaps->szPname, ac16.szPname);
+    lpCaps->wTechnology = ac16.wTechnology;
+    lpCaps->dwSupport = ac16.dwSupport;
+#endif
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_Aux_Callback		[internal]
+ */
+void	CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
+{
+    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
+
+    FIXME("NIY\n");
+    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
+}
+
+/* =================================
+ *     M I X E R  M A P P E R S
+ * ================================= */
+
+/**************************************************************************
+ * 				xMMDRV_Mixer_Map16To32A		[internal]
+ */
+WINMM_MapType	MMDRV_Mixer_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_Mixer_UnMap16To32A	[internal]
+ */
+WINMM_MapType	MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+#if 0
+    MIXERCAPSA	micA;
+    UINT	ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
+
+    if (ret == MMSYSERR_NOERROR) {
+	mixcaps->wMid           = micA.wMid;
+	mixcaps->wPid           = micA.wPid;
+	mixcaps->vDriverVersion = micA.vDriverVersion;
+	strcpy(mixcaps->szPname, micA.szPname);
+	mixcaps->fdwSupport     = micA.fdwSupport;
+	mixcaps->cDestinations  = micA.cDestinations;
+    }
+    return ret;
+#endif
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_Mixer_Map32ATo16		[internal]
+ */
+WINMM_MapType	MMDRV_Mixer_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_Mixer_UnMap32ATo16	[internal]
+ */
+WINMM_MapType	MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_Mixer_Callback		[internal]
+ */
+void	CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
+{
+    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
+
+    FIXME("NIY\n");
+    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
+}
+
+/* =================================
+ *   M I D I  I N    M A P P E R S
+ * ================================= */
+
+/**************************************************************************
+ * 				MMDRV_MidiIn_Map16To32A		[internal]
+ */
+WINMM_MapType	MMDRV_MidiIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_MidiIn_UnMap16To32A	[internal]
+ */
+WINMM_MapType	MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_MidiIn_Map32ATo16		[internal]
+ */
+WINMM_MapType	MMDRV_MidiIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_MidiIn_UnMap32ATo16	[internal]
+ */
+WINMM_MapType	MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    return WINMM_MAP_MSGERROR;
+}
+
+/**************************************************************************
+ * 				MMDRV_MidiIn_Callback		[internal]
+ */
+void	CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
+{
+    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
+
+    switch (uMsg) {
+    case MIM_OPEN:
+    case MIM_CLOSE:
+	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
+
+    case MIM_DATA:
+    case MIM_MOREDATA:
+    case MIM_ERROR:
+	/* dwParam1 & dwParam2 are are data, nothing to do */
+	break;
+    case MIM_LONGDATA:
+    case MIM_LONGERROR:
+	/* dwParam1 points to a MidiHdr, work to be done !!! */
+	if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
+	    /* initial map is: 32 => 16 */
+	    LPMIDIHDR		mh16 = MapSL(dwParam1);
+	    LPMIDIHDR		mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
+
+	    dwParam1 = (DWORD)mh32;
+	    mh32->dwFlags = mh16->dwFlags;
+	    mh32->dwBytesRecorded = mh16->dwBytesRecorded;
+	    if (mh32->reserved >= sizeof(MIDIHDR))
+		mh32->dwOffset = mh16->dwOffset;
+	} else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
+	    /* initial map is: 16 => 32 */
+	    LPMIDIHDR		mh32 = (LPMIDIHDR)(dwParam1);
+	    SEGPTR		segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
+	    LPMIDIHDR		mh16 = MapSL(segmh16);
+
+	    dwParam1 = (DWORD)segmh16;
+	    mh16->dwFlags = mh32->dwFlags;
+	    mh16->dwBytesRecorded = mh32->dwBytesRecorded;
+	    if (mh16->reserved >= sizeof(MIDIHDR))
+		mh16->dwOffset = mh32->dwOffset;
+	}
+	/* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
+	break;
+    /* case MOM_POSITIONCB: */
+    default:
+	ERR("Unknown msg %u\n", uMsg);
+    }
+
+    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
+}
+
+/* =================================
+ *   M I D I  O U T  M A P P E R S
+ * ================================= */
+
+/**************************************************************************
+ * 				MMDRV_MidiOut_Map16To32A	[internal]
+ */
+WINMM_MapType	MMDRV_MidiOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    case MODM_GETNUMDEVS:
+    case MODM_DATA:
+    case MODM_RESET:
+    case MODM_SETVOLUME:
+	ret = WINMM_MAP_OK;
+	break;
+
+    case MODM_OPEN:
+    case MODM_CLOSE:
+    case MODM_GETVOLUME:
+	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
+	break;
+
+    case MODM_GETDEVCAPS:
+	{
+            LPMIDIOUTCAPSA	moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
+	    LPMIDIOUTCAPS16	moc16 = MapSL(*lpParam1);
+
+	    if (moc32) {
+		*(LPMIDIOUTCAPS16*)moc32 = moc16;
+		moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
+		*lpParam1 = (DWORD)moc32;
+		*lpParam2 = sizeof(MIDIOUTCAPSA);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case MODM_PREPARE:
+	{
+	    LPMIDIHDR		mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
+	    LPMIDIHDR		mh16 = MapSL(*lpParam1);
+
+	    if (mh32) {
+		*(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
+		mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
+		mh32->lpData = MapSL((SEGPTR)mh16->lpData);
+		mh32->dwBufferLength = mh16->dwBufferLength;
+		mh32->dwBytesRecorded = mh16->dwBytesRecorded;
+		mh32->dwUser = mh16->dwUser;
+		mh32->dwFlags = mh16->dwFlags;
+		/* FIXME: nothing on mh32->lpNext */
+		/* could link the mh32->lpNext at this level for memory house keeping */
+		mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
+		mh16->lpNext = mh32; /* for reuse in unprepare and write */
+		/* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
+		mh16->reserved = *lpParam2;
+		*lpParam1 = (DWORD)mh32;
+		*lpParam2 = sizeof(MIDIHDR);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case MODM_UNPREPARE:
+    case MODM_LONGDATA:
+	{
+	    LPMIDIHDR		mh16 = MapSL(*lpParam1);
+	    LPMIDIHDR		mh32 = (LPMIDIHDR)mh16->lpNext;
+
+	    *lpParam1 = (DWORD)mh32;
+	    *lpParam2 = sizeof(MIDIHDR);
+	    /* dwBufferLength can be reduced between prepare & write */
+	    if (wMsg == MODM_LONGDATA && mh32->dwBufferLength < mh16->dwBufferLength) {
+		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
+		    mh32->dwBufferLength, mh16->dwBufferLength);
+	    } else
+                mh32->dwBufferLength = mh16->dwBufferLength;
+	    ret = WINMM_MAP_OKMEM;
+	}
+	break;
+
+    case MODM_CACHEPATCHES:
+    case MODM_CACHEDRUMPATCHES:
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_MidiOut_UnMap16To32A	[internal]
+ */
+WINMM_MapType	MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    case MODM_GETNUMDEVS:
+    case MODM_DATA:
+    case MODM_RESET:
+    case MODM_SETVOLUME:
+	ret = WINMM_MAP_OK;
+	break;
+
+    case MODM_OPEN:
+    case MODM_CLOSE:
+    case MODM_GETVOLUME:
+	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
+	break;
+
+    case MODM_GETDEVCAPS:
+	{
+            LPMIDIOUTCAPSA		moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
+	    LPMIDIOUTCAPS16		moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
+
+	    moc16->wMid			= moc32->wMid;
+	    moc16->wPid			= moc32->wPid;
+	    moc16->vDriverVersion	= moc32->vDriverVersion;
+	    strcpy(moc16->szPname, moc32->szPname);
+	    moc16->wTechnology		= moc32->wTechnology;
+	    moc16->wVoices		= moc32->wVoices;
+	    moc16->wNotes		= moc32->wNotes;
+	    moc16->wChannelMask		= moc32->wChannelMask;
+	    moc16->dwSupport		= moc32->dwSupport;
+	    HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case MODM_PREPARE:
+    case MODM_UNPREPARE:
+    case MODM_LONGDATA:
+	{
+	    LPMIDIHDR		mh32 = (LPMIDIHDR)(*lpParam1);
+	    LPMIDIHDR		mh16 = MapSL(*(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
+
+	    assert(mh16->lpNext == mh32);
+	    mh16->dwBufferLength = mh32->dwBufferLength;
+	    mh16->dwBytesRecorded = mh32->dwBytesRecorded;
+	    mh16->dwUser = mh32->dwUser;
+	    mh16->dwFlags = mh32->dwFlags;
+	    if (mh16->reserved >= sizeof(MIDIHDR))
+		mh16->dwOffset = mh32->dwOffset;
+
+	    if (wMsg == MODM_UNPREPARE) {
+		HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
+		mh16->lpNext = 0;
+	    }
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+
+    case MODM_CACHEPATCHES:
+    case MODM_CACHEDRUMPATCHES:
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_MidiOut_Map32ATo16	[internal]
+ */
+WINMM_MapType	MMDRV_MidiOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    case MODM_CLOSE:
+    case MODM_GETNUMDEVS:
+    case MODM_DATA:
+    case MODM_RESET:
+    case MODM_SETVOLUME:
+	ret = WINMM_MAP_OK;
+	break;
+    case MODM_GETDEVCAPS:
+	{
+            LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
+            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPSA)+sizeof(MIDIOUTCAPS16));
+
+	    if (ptr) {
+		*(LPMIDIOUTCAPSA*)ptr = moc32;
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	    *lpParam1 = (DWORD)MapLS(ptr) + sizeof(LPMIDIOUTCAPSA);
+	    *lpParam2 = sizeof(MIDIOUTCAPS16);
+	}
+	break;
+    case MODM_PREPARE:
+	{
+	    LPMIDIHDR		mh32 = (LPMIDIHDR)*lpParam1;
+	    LPMIDIHDR		mh16;
+	    LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
+                                    sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
+
+	    if (ptr) {
+		*(LPMIDIHDR*)ptr = mh32;
+		mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
+		*lpParam1 = MapLS(mh16);
+		mh16->lpData = (LPSTR)*lpParam1 + sizeof(MIDIHDR);
+		/* data will be copied on WODM_WRITE */
+		mh16->dwBufferLength = mh32->dwBufferLength;
+		mh16->dwBytesRecorded = mh32->dwBytesRecorded;
+		mh16->dwUser = mh32->dwUser;
+		mh16->dwFlags = mh32->dwFlags;
+		/* FIXME: nothing on mh32->lpNext */
+		/* could link the mh32->lpNext at this level for memory house keeping */
+		mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
+
+		mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
+		mh32->reserved = *lpParam2;
+
+		TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
+		      *lpParam1, (DWORD)mh16->lpData,
+		      mh32->dwBufferLength, (DWORD)mh32->lpData);
+		*lpParam2 = sizeof(MIDIHDR);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case MODM_UNPREPARE:
+    case MODM_LONGDATA:
+	{
+	    LPMIDIHDR		mh32 = (LPMIDIHDR)(*lpParam1);
+	    LPMIDIHDR		mh16 = (LPMIDIHDR)mh32->lpNext;
+	    LPSTR		ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
+
+	    assert(*(LPMIDIHDR*)ptr == mh32);
+
+	    if (wMsg == MODM_LONGDATA)
+		memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
+
+	    *lpParam1 = MapLS(mh16);
+	    *lpParam2 = sizeof(MIDIHDR);
+	    TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
+                  *lpParam1, (DWORD)mh16->lpData, mh32->dwBufferLength, (DWORD)mh32->lpData);
+
+	    /* dwBufferLength can be reduced between prepare & write */
+	    if (wMsg == MODM_LONGDATA && mh16->dwBufferLength < mh32->dwBufferLength) {
+		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
+		    mh16->dwBufferLength, mh32->dwBufferLength);
+	    } else
+                mh16->dwBufferLength = mh32->dwBufferLength;
+	    ret = WINMM_MAP_OKMEM;
+	}
+	break;
+    case MODM_OPEN:
+	{
+            LPMIDIOPENDESC		mod32 = (LPMIDIOPENDESC)*lpParam1;
+	    LPVOID			ptr;
+	    LPMIDIOPENDESC16		mod16;
+
+	    /* allocated data are mapped as follows:
+	       LPMIDIOPENDESC	ptr to orig lParam1
+	       DWORD		orig dwUser, which is a pointer to DWORD:driver dwInstance
+	       DWORD		dwUser passed to driver
+	       MIDIOPENDESC16	mod16: openDesc passed to driver
+	       MIDIOPENSTRMID	cIds
+	    */
+            ptr = HeapAlloc( GetProcessHeap(), 0,
+                             sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
+                             mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
+
+	    if (ptr) {
+                SEGPTR segptr = MapLS(ptr);
+		*(LPMIDIOPENDESC*)ptr = mod32;
+		*(LPDWORD)((char*)ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
+		mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
+
+		mod16->hMidi = HMIDI_16(mod32->hMidi);
+		mod16->dwCallback = mod32->dwCallback;
+		mod16->dwInstance = mod32->dwInstance;
+		mod16->dnDevNode = mod32->dnDevNode;
+		mod16->cIds = mod32->cIds;
+		memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
+
+		*lpParam1 = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
+		*lpdwUser = (DWORD)segptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case MODM_GETVOLUME:
+    case MODM_CACHEPATCHES:
+    case MODM_CACHEDRUMPATCHES:
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_MidiOut_UnMap32ATo16	[internal]
+ */
+WINMM_MapType	MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    case MODM_CLOSE:
+    case MODM_GETNUMDEVS:
+    case MODM_DATA:
+    case MODM_RESET:
+    case MODM_SETVOLUME:
+	ret = WINMM_MAP_OK;
+	break;
+    case MODM_GETDEVCAPS:
+	{
+	    LPMIDIOUTCAPS16		moc16 = MapSL(*lpParam1);
+	    LPSTR			ptr   = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
+            LPMIDIOUTCAPSA		moc32 = *(LPMIDIOUTCAPSA*)ptr;
+
+	    moc32->wMid			= moc16->wMid;
+	    moc32->wPid			= moc16->wPid;
+	    moc32->vDriverVersion	= moc16->vDriverVersion;
+	    strcpy(moc32->szPname, moc16->szPname);
+	    moc32->wTechnology		= moc16->wTechnology;
+	    moc32->wVoices		= moc16->wVoices;
+	    moc32->wNotes		= moc16->wNotes;
+	    moc32->wChannelMask		= moc16->wChannelMask;
+	    moc32->dwSupport		= moc16->dwSupport;
+            UnMapLS( *lpParam1 );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case MODM_PREPARE:
+    case MODM_UNPREPARE:
+    case MODM_LONGDATA:
+	{
+	    LPMIDIHDR		mh16 = MapSL(*lpParam1);
+	    LPSTR		ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
+	    LPMIDIHDR		mh32 = *(LPMIDIHDR*)ptr;
+
+	    assert(mh32->lpNext == (LPMIDIHDR)mh16);
+            UnMapLS( *lpParam1 );
+	    mh32->dwBytesRecorded = mh16->dwBytesRecorded;
+	    mh32->dwUser = mh16->dwUser;
+	    mh32->dwFlags = mh16->dwFlags;
+
+	    if (wMsg == MODM_UNPREPARE) {
+                HeapFree( GetProcessHeap(), 0, ptr );
+		mh32->lpNext = 0;
+	    }
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case MODM_OPEN:
+	{
+	    LPMIDIOPENDESC16		mod16 = MapSL(*lpParam1);
+	    LPSTR			ptr   = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
+            UnMapLS( *lpParam1 );
+	    **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
+
+            HeapFree( GetProcessHeap(), 0, ptr );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case MODM_GETVOLUME:
+    case MODM_CACHEPATCHES:
+    case MODM_CACHEDRUMPATCHES:
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_MidiOut_Callback		[internal]
+ */
+void	CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
+{
+    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
+
+    switch (uMsg) {
+    case MOM_OPEN:
+    case MOM_CLOSE:
+	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
+	break;
+    case MOM_DONE:
+	if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
+	    /* initial map is: 32 => 16 */
+	    LPMIDIHDR		mh16 = MapSL(dwParam1);
+	    LPMIDIHDR		mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
+
+	    dwParam1 = (DWORD)mh32;
+	    mh32->dwFlags = mh16->dwFlags;
+	    mh32->dwOffset = mh16->dwOffset;
+	    if (mh32->reserved >= sizeof(MIDIHDR))
+		mh32->dwOffset = mh16->dwOffset;
+	} else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
+	    /* initial map is: 16 => 32 */
+	    LPMIDIHDR		mh32 = (LPMIDIHDR)(dwParam1);
+	    SEGPTR		segmh16 = *(SEGPTR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
+	    LPMIDIHDR		mh16 = MapSL(segmh16);
+
+	    dwParam1 = (DWORD)segmh16;
+	    mh16->dwFlags = mh32->dwFlags;
+	    if (mh16->reserved >= sizeof(MIDIHDR))
+		mh16->dwOffset = mh32->dwOffset;
+	}
+	/* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
+	break;
+    /* case MOM_POSITIONCB: */
+    default:
+	ERR("Unknown msg %u\n", uMsg);
+    }
+
+    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
+}
+
+/* =================================
+ *   W A V E  I N    M A P P E R S
+ * ================================= */
+
+/**************************************************************************
+ * 				MMDRV_WaveIn_Map16To32A		[internal]
+ */
+WINMM_MapType	MMDRV_WaveIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    case WIDM_GETNUMDEVS:
+    case WIDM_RESET:
+    case WIDM_START:
+    case WIDM_STOP:
+	ret = WINMM_MAP_OK;
+	break;
+    case WIDM_OPEN:
+    case WIDM_CLOSE:
+	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
+	break;
+    case WIDM_GETDEVCAPS:
+	{
+            LPWAVEINCAPSA	wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
+	    LPWAVEINCAPS16	wic16 = MapSL(*lpParam1);
+
+	    if (wic32) {
+		*(LPWAVEINCAPS16*)wic32 = wic16;
+		wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
+		*lpParam1 = (DWORD)wic32;
+		*lpParam2 = sizeof(WAVEINCAPSA);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WIDM_GETPOS:
+	{
+            LPMMTIME		mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
+	    LPMMTIME16		mmt16 = MapSL(*lpParam1);
+
+	    if (mmt32) {
+		*(LPMMTIME16*)mmt32 = mmt16;
+		mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
+
+		mmt32->wType = mmt16->wType;
+		*lpParam1 = (DWORD)mmt32;
+		*lpParam2 = sizeof(MMTIME);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WIDM_PREPARE:
+	{
+	    LPWAVEHDR		wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
+	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
+
+	    if (wh32) {
+		*(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
+		wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
+		wh32->lpData = MapSL((SEGPTR)wh16->lpData);
+		wh32->dwBufferLength = wh16->dwBufferLength;
+		wh32->dwBytesRecorded = wh16->dwBytesRecorded;
+		wh32->dwUser = wh16->dwUser;
+		wh32->dwFlags = wh16->dwFlags;
+		wh32->dwLoops = wh16->dwLoops;
+		/* FIXME: nothing on wh32->lpNext */
+		/* could link the wh32->lpNext at this level for memory house keeping */
+		wh16->lpNext = wh32; /* for reuse in unprepare and write */
+		*lpParam1 = (DWORD)wh32;
+		*lpParam2 = sizeof(WAVEHDR);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WIDM_ADDBUFFER:
+    case WIDM_UNPREPARE:
+	{
+	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)wh16->lpNext;
+
+	    *lpParam1 = (DWORD)wh32;
+	    *lpParam2 = sizeof(WAVEHDR);
+	    /* dwBufferLength can be reduced between prepare & write */
+	    if (wMsg == WIDM_ADDBUFFER && wh32->dwBufferLength < wh16->dwBufferLength) {
+		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
+		    wh32->dwBufferLength, wh16->dwBufferLength);
+	    } else
+                wh32->dwBufferLength = wh16->dwBufferLength;
+	    ret = WINMM_MAP_OKMEM;
+	}
+	break;
+    case WIDM_MAPPER_STATUS:
+	/* just a single DWORD */
+	*lpParam2 = (DWORD)MapSL(*lpParam2);
+	ret = WINMM_MAP_OK;
+	break;
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_WaveIn_UnMap16To32A	[internal]
+ */
+WINMM_MapType	MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    case WIDM_GETNUMDEVS:
+    case WIDM_RESET:
+    case WIDM_START:
+    case WIDM_STOP:
+    case WIDM_MAPPER_STATUS:
+	ret = WINMM_MAP_OK;
+	break;
+    case WIDM_OPEN:
+    case WIDM_CLOSE:
+	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
+	break;
+    case WIDM_GETDEVCAPS:
+	{
+            LPWAVEINCAPSA		wic32 = (LPWAVEINCAPSA)(*lpParam1);
+	    LPWAVEINCAPS16		wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
+
+	    wic16->wMid = wic32->wMid;
+	    wic16->wPid = wic32->wPid;
+	    wic16->vDriverVersion = wic32->vDriverVersion;
+	    strcpy(wic16->szPname, wic32->szPname);
+	    wic16->dwFormats = wic32->dwFormats;
+	    wic16->wChannels = wic32->wChannels;
+	    HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WIDM_GETPOS:
+	{
+            LPMMTIME		mmt32 = (LPMMTIME)(*lpParam1);
+	    LPMMTIME16		mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
+
+	    MMSYSTEM_MMTIME32to16(mmt16, mmt32);
+	    HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WIDM_ADDBUFFER:
+    case WIDM_PREPARE:
+    case WIDM_UNPREPARE:
+	{
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)(*lpParam1);
+	    LPWAVEHDR		wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
+
+	    assert(wh16->lpNext == wh32);
+	    wh16->dwBufferLength = wh32->dwBufferLength;
+	    wh16->dwBytesRecorded = wh32->dwBytesRecorded;
+	    wh16->dwUser = wh32->dwUser;
+	    wh16->dwFlags = wh32->dwFlags;
+	    wh16->dwLoops = wh32->dwLoops;
+
+	    if (wMsg == WIDM_UNPREPARE) {
+		HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
+		wh16->lpNext = 0;
+	    }
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_WaveIn_Map32ATo16		[internal]
+ */
+WINMM_MapType	MMDRV_WaveIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    case WIDM_CLOSE:
+    case WIDM_GETNUMDEVS:
+    case WIDM_RESET:
+    case WIDM_START:
+    case WIDM_STOP:
+	ret = WINMM_MAP_OK;
+	break;
+
+    case WIDM_OPEN:
+	{
+            LPWAVEOPENDESC		wod32 = (LPWAVEOPENDESC)*lpParam1;
+	    int				sz = sizeof(WAVEFORMATEX);
+	    LPVOID			ptr;
+	    LPWAVEOPENDESC16		wod16;
+
+	    /* allocated data are mapped as follows:
+	       LPWAVEOPENDESC	ptr to orig lParam1
+	       DWORD		orig dwUser, which is a pointer to DWORD:driver dwInstance
+	       DWORD		dwUser passed to driver
+	       WAVEOPENDESC16	wod16: openDesc passed to driver
+	       WAVEFORMATEX	openDesc->lpFormat passed to driver
+	       xxx		extra bytes to WAVEFORMATEX
+	    */
+	    if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
+		TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
+		sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
+	    }
+
+            ptr = HeapAlloc( GetProcessHeap(), 0,
+                             sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
+
+	    if (ptr) {
+                SEGPTR seg_ptr = MapLS( ptr );
+		*(LPWAVEOPENDESC*)ptr = wod32;
+		*(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
+		wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
+
+		wod16->hWave = HWAVE_16(wod32->hWave);
+		wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
+		memcpy(wod16 + 1, wod32->lpFormat, sz);
+
+		wod16->dwCallback = wod32->dwCallback;
+		wod16->dwInstance = wod32->dwInstance;
+		wod16->uMappedDeviceID = wod32->uMappedDeviceID;
+		wod16->dnDevNode = wod32->dnDevNode;
+
+		*lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
+		*lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WIDM_PREPARE:
+	{
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)*lpParam1;
+	    LPWAVEHDR		wh16;
+	    LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
+                                    sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
+
+	    if (ptr) {
+                SEGPTR seg_ptr = MapLS( ptr );
+		*(LPWAVEHDR*)ptr = wh32;
+		wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
+		wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
+		/* data will be copied on WODM_WRITE */
+		wh16->dwBufferLength = wh32->dwBufferLength;
+		wh16->dwBytesRecorded = wh32->dwBytesRecorded;
+		wh16->dwUser = wh32->dwUser;
+		wh16->dwFlags = wh32->dwFlags;
+		wh16->dwLoops = wh32->dwLoops;
+		/* FIXME: nothing on wh32->lpNext */
+		/* could link the wh32->lpNext at this level for memory house keeping */
+		wh32->lpNext = wh16; /* for reuse in unprepare and write */
+		TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
+		      seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
+		      wh32->dwBufferLength, (DWORD)wh32->lpData);
+		*lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
+		*lpParam2 = sizeof(WAVEHDR);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WIDM_ADDBUFFER:
+    case WIDM_UNPREPARE:
+ 	{
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)(*lpParam1);
+	    LPWAVEHDR		wh16 = wh32->lpNext;
+	    LPSTR		ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
+            SEGPTR seg_ptr = MapLS( ptr );
+
+	    assert(*(LPWAVEHDR*)ptr == wh32);
+
+	    TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
+		  seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
+		  wh32->dwBufferLength, (DWORD)wh32->lpData);
+
+	    if (wMsg == WIDM_ADDBUFFER)
+		memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
+
+	    *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
+	    *lpParam2 = sizeof(WAVEHDR);
+	    /* dwBufferLength can be reduced between prepare & write */
+	    if (wMsg == WIDM_ADDBUFFER && wh16->dwBufferLength < wh32->dwBufferLength) {
+		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
+		    wh16->dwBufferLength, wh32->dwBufferLength);
+	    } else
+                wh16->dwBufferLength = wh32->dwBufferLength;
+	    ret = WINMM_MAP_OKMEM;
+	}
+	break;
+   case WIDM_GETDEVCAPS:
+	{
+            LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
+            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0 ,sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
+
+	    if (ptr) {
+		*(LPWAVEINCAPSA*)ptr = wic32;
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	    *lpParam1 = MapLS(ptr) + sizeof(LPWAVEINCAPSA);
+	    *lpParam2 = sizeof(WAVEINCAPS16);
+	}
+	break;
+    case WIDM_GETPOS:
+ 	{
+            LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
+            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
+            LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
+
+	    if (ptr) {
+		*(LPMMTIME*)ptr = mmt32;
+		mmt16->wType = mmt32->wType;
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	    *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
+	    *lpParam2 = sizeof(MMTIME16);
+	}
+	break;
+    case DRVM_MAPPER_STATUS:
+ 	{
+            LPDWORD p32 = (LPDWORD)*lpParam2;
+            *lpParam2 = MapLS(p32);
+            ret = WINMM_MAP_OKMEM;
+	}
+	break;
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_WaveIn_UnMap32ATo16	[internal]
+ */
+WINMM_MapType	MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    case WIDM_CLOSE:
+    case WIDM_GETNUMDEVS:
+    case WIDM_RESET:
+    case WIDM_START:
+    case WIDM_STOP:
+	ret = WINMM_MAP_OK;
+	break;
+
+    case WIDM_OPEN:
+	{
+	    LPWAVEOPENDESC16		wod16 = MapSL(*lpParam1);
+	    LPSTR			ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
+            LPWAVEOPENDESC		wod32 = *(LPWAVEOPENDESC*)ptr;
+
+            UnMapLS( *lpParam1 );
+	    wod32->uMappedDeviceID = wod16->uMappedDeviceID;
+	    **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
+            HeapFree( GetProcessHeap(), 0, ptr );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+
+    case WIDM_ADDBUFFER:
+    case WIDM_PREPARE:
+    case WIDM_UNPREPARE:
+	{
+	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
+	    LPSTR		ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
+	    LPWAVEHDR		wh32 = *(LPWAVEHDR*)ptr;
+
+	    assert(wh32->lpNext == wh16);
+	    wh32->dwBytesRecorded = wh16->dwBytesRecorded;
+	    wh32->dwUser = wh16->dwUser;
+	    wh32->dwFlags = wh16->dwFlags;
+	    wh32->dwLoops = wh16->dwLoops;
+            UnMapLS( *lpParam1 );
+
+	    if (wMsg == WIDM_UNPREPARE) {
+                HeapFree( GetProcessHeap(), 0, ptr );
+		wh32->lpNext = 0;
+	    }
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+     case WIDM_GETDEVCAPS:
+	{
+	    LPWAVEINCAPS16		wic16 = MapSL(*lpParam1);
+	    LPSTR			ptr   = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
+            LPWAVEINCAPSA		wic32 = *(LPWAVEINCAPSA*)ptr;
+
+	    wic32->wMid = wic16->wMid;
+	    wic32->wPid = wic16->wPid;
+	    wic32->vDriverVersion = wic16->vDriverVersion;
+	    strcpy(wic32->szPname, wic16->szPname);
+	    wic32->dwFormats = wic16->dwFormats;
+	    wic32->wChannels = wic16->wChannels;
+            UnMapLS( *lpParam1 );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WIDM_GETPOS:
+	{
+	    LPMMTIME16		mmt16 = MapSL(*lpParam1);
+	    LPSTR		ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
+            LPMMTIME		mmt32 = *(LPMMTIME*)ptr;
+
+	    MMSYSTEM_MMTIME16to32(mmt32, mmt16);
+            UnMapLS( *lpParam1 );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case DRVM_MAPPER_STATUS:
+	{
+            UnMapLS( *lpParam2 );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_WaveIn_Callback		[internal]
+ */
+void	CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
+{
+    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
+
+    switch (uMsg) {
+    case WIM_OPEN:
+    case WIM_CLOSE:
+	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
+	break;
+    case WIM_DATA:
+	if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
+	    /* initial map is: 32 => 16 */
+	    LPWAVEHDR		wh16 = MapSL(dwParam1);
+	    LPWAVEHDR		wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
+
+	    dwParam1 = (DWORD)wh32;
+	    wh32->dwFlags = wh16->dwFlags;
+	    wh32->dwBytesRecorded = wh16->dwBytesRecorded;
+	} else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
+	    /* initial map is: 16 => 32 */
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)(dwParam1);
+	    SEGPTR		segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
+	    LPWAVEHDR		wh16 = MapSL(segwh16);
+
+	    dwParam1 = (DWORD)segwh16;
+	    wh16->dwFlags = wh32->dwFlags;
+	    wh16->dwBytesRecorded = wh32->dwBytesRecorded;
+	}
+	/* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
+	break;
+    default:
+	ERR("Unknown msg %u\n", uMsg);
+    }
+
+    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
+}
+
+/* =================================
+ *   W A V E  O U T  M A P P E R S
+ * ================================= */
+
+/**************************************************************************
+ * 				MMDRV_WaveOut_Map16To32A	[internal]
+ */
+WINMM_MapType	MMDRV_WaveOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    /* nothing to do */
+    case WODM_BREAKLOOP:
+    case WODM_CLOSE:
+    case WODM_GETNUMDEVS:
+    case WODM_PAUSE:
+    case WODM_RESET:
+    case WODM_RESTART:
+    case WODM_SETPITCH:
+    case WODM_SETPLAYBACKRATE:
+    case WODM_SETVOLUME:
+	ret = WINMM_MAP_OK;
+	break;
+
+    case WODM_GETPITCH:
+    case WODM_GETPLAYBACKRATE:
+    case WODM_GETVOLUME:
+    case WODM_OPEN:
+	FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
+	break;
+
+    case WODM_GETDEVCAPS:
+	{
+            LPWAVEOUTCAPSA		woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
+	    LPWAVEOUTCAPS16		woc16 = MapSL(*lpParam1);
+
+	    if (woc32) {
+		*(LPWAVEOUTCAPS16*)woc32 = woc16;
+		woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
+		*lpParam1 = (DWORD)woc32;
+		*lpParam2 = sizeof(WAVEOUTCAPSA);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WODM_GETPOS:
+	{
+            LPMMTIME		mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
+	    LPMMTIME16		mmt16 = MapSL(*lpParam1);
+
+	    if (mmt32) {
+		*(LPMMTIME16*)mmt32 = mmt16;
+		mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
+
+		mmt32->wType = mmt16->wType;
+		*lpParam1 = (DWORD)mmt32;
+		*lpParam2 = sizeof(MMTIME);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WODM_PREPARE:
+	{
+	    LPWAVEHDR		wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
+	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
+
+	    if (wh32) {
+		*(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
+		wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
+		wh32->lpData = MapSL((SEGPTR)wh16->lpData);
+		wh32->dwBufferLength = wh16->dwBufferLength;
+		wh32->dwBytesRecorded = wh16->dwBytesRecorded;
+		wh32->dwUser = wh16->dwUser;
+		wh32->dwFlags = wh16->dwFlags;
+		wh32->dwLoops = wh16->dwLoops;
+		/* FIXME: nothing on wh32->lpNext */
+		/* could link the wh32->lpNext at this level for memory house keeping */
+		wh16->lpNext = wh32; /* for reuse in unprepare and write */
+		*lpParam1 = (DWORD)wh32;
+		*lpParam2 = sizeof(WAVEHDR);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WODM_UNPREPARE:
+    case WODM_WRITE:
+	{
+	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)wh16->lpNext;
+
+	    *lpParam1 = (DWORD)wh32;
+	    *lpParam2 = sizeof(WAVEHDR);
+	    /* dwBufferLength can be reduced between prepare & write */
+	    if (wMsg == WODM_WRITE && wh32->dwBufferLength < wh16->dwBufferLength) {
+		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
+		    wh32->dwBufferLength, wh16->dwBufferLength);
+	    } else
+                wh32->dwBufferLength = wh16->dwBufferLength;
+	    ret = WINMM_MAP_OKMEM;
+	}
+	break;
+    case WODM_MAPPER_STATUS:
+	*lpParam2 = (DWORD)MapSL(*lpParam2);
+	ret = WINMM_MAP_OK;
+	break;
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_WaveOut_UnMap16To32A	[internal]
+ */
+WINMM_MapType	MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
+
+    switch (wMsg) {
+    /* nothing to do */
+    case WODM_BREAKLOOP:
+    case WODM_CLOSE:
+    case WODM_GETNUMDEVS:
+    case WODM_PAUSE:
+    case WODM_RESET:
+    case WODM_RESTART:
+    case WODM_SETPITCH:
+    case WODM_SETPLAYBACKRATE:
+    case WODM_SETVOLUME:
+    case WODM_MAPPER_STATUS:
+	ret = WINMM_MAP_OK;
+	break;
+
+    case WODM_GETPITCH:
+    case WODM_GETPLAYBACKRATE:
+    case WODM_GETVOLUME:
+    case WODM_OPEN:
+	FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
+	break;
+
+    case WODM_GETDEVCAPS:
+	{
+            LPWAVEOUTCAPSA		woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
+	    LPWAVEOUTCAPS16		woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
+
+	    woc16->wMid = woc32->wMid;
+	    woc16->wPid = woc32->wPid;
+	    woc16->vDriverVersion = woc32->vDriverVersion;
+	    strcpy(woc16->szPname, woc32->szPname);
+	    woc16->dwFormats = woc32->dwFormats;
+	    woc16->wChannels = woc32->wChannels;
+	    woc16->dwSupport = woc32->dwSupport;
+	    HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WODM_GETPOS:
+	{
+            LPMMTIME		mmt32 = (LPMMTIME)(*lpParam1);
+	    LPMMTIME16		mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
+
+	    MMSYSTEM_MMTIME32to16(mmt16, mmt32);
+	    HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WODM_PREPARE:
+    case WODM_UNPREPARE:
+    case WODM_WRITE:
+	{
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)(*lpParam1);
+	    LPWAVEHDR		wh16 = MapSL(*(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
+
+	    assert(wh16->lpNext == wh32);
+	    wh16->dwBufferLength = wh32->dwBufferLength;
+	    wh16->dwBytesRecorded = wh32->dwBytesRecorded;
+	    wh16->dwUser = wh32->dwUser;
+	    wh16->dwFlags = wh32->dwFlags;
+	    wh16->dwLoops = wh32->dwLoops;
+
+	    if (wMsg == WODM_UNPREPARE) {
+		HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
+		wh16->lpNext = 0;
+	    }
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    default:
+	FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_WaveOut_Map32ATo16	[internal]
+ */
+WINMM_MapType	MMDRV_WaveOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret;
+
+    switch (wMsg) {
+	/* nothing to do */
+    case WODM_BREAKLOOP:
+    case WODM_CLOSE:
+    case WODM_GETNUMDEVS:
+    case WODM_PAUSE:
+    case WODM_RESET:
+    case WODM_RESTART:
+    case WODM_SETPITCH:
+    case WODM_SETPLAYBACKRATE:
+    case WODM_SETVOLUME:
+	ret = WINMM_MAP_OK;
+	break;
+
+    case WODM_GETDEVCAPS:
+	{
+            LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
+            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0,
+                                   sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
+
+	    if (ptr) {
+		*(LPWAVEOUTCAPSA*)ptr = woc32;
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	    *lpParam1 = MapLS(ptr) + sizeof(LPWAVEOUTCAPSA);
+	    *lpParam2 = sizeof(WAVEOUTCAPS16);
+	}
+	break;
+    case WODM_GETPITCH:
+	FIXME("NIY: no conversion yet\n");
+	ret = WINMM_MAP_MSGERROR;
+	break;
+    case WODM_GETPLAYBACKRATE:
+	FIXME("NIY: no conversion yet\n");
+	ret = WINMM_MAP_MSGERROR;
+	break;
+    case WODM_GETPOS:
+	{
+            LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
+            LPSTR ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(LPMMTIME) + sizeof(MMTIME16));
+            LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
+
+	    if (ptr) {
+		*(LPMMTIME*)ptr = mmt32;
+		mmt16->wType = mmt32->wType;
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	    *lpParam1 = MapLS(ptr) + sizeof(LPMMTIME);
+	    *lpParam2 = sizeof(MMTIME16);
+	}
+	break;
+    case WODM_GETVOLUME:
+	FIXME("NIY: no conversion yet\n");
+	ret = WINMM_MAP_MSGERROR;
+	break;
+    case WODM_OPEN:
+	{
+            LPWAVEOPENDESC		wod32 = (LPWAVEOPENDESC)*lpParam1;
+	    int				sz = sizeof(WAVEFORMATEX);
+	    LPVOID			ptr;
+	    LPWAVEOPENDESC16		wod16;
+
+	    /* allocated data are mapped as follows:
+	       LPWAVEOPENDESC	ptr to orig lParam1
+	       DWORD		orig dwUser, which is a pointer to DWORD:driver dwInstance
+	       DWORD		dwUser passed to driver
+	       WAVEOPENDESC16	wod16: openDesc passed to driver
+	       WAVEFORMATEX	openDesc->lpFormat passed to driver
+	       xxx		extra bytes to WAVEFORMATEX
+	    */
+	    if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
+		TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
+		sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
+	    }
+
+	    ptr = HeapAlloc( GetProcessHeap(), 0,
+                             sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
+
+	    if (ptr) {
+                SEGPTR seg_ptr = MapLS( ptr );
+		*(LPWAVEOPENDESC*)ptr = wod32;
+		*(LPDWORD)((char*)ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
+		wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
+
+		wod16->hWave = HWAVE_16(wod32->hWave);
+		wod16->lpFormat = (LPWAVEFORMATEX)(seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
+		memcpy(wod16 + 1, wod32->lpFormat, sz);
+
+		wod16->dwCallback = wod32->dwCallback;
+		wod16->dwInstance = wod32->dwInstance;
+		wod16->uMappedDeviceID = wod32->uMappedDeviceID;
+		wod16->dnDevNode = wod32->dnDevNode;
+
+		*lpParam1 = seg_ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
+		*lpdwUser = seg_ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WODM_PREPARE:
+	{
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)*lpParam1;
+	    LPWAVEHDR		wh16;
+	    LPVOID ptr = HeapAlloc( GetProcessHeap(), 0,
+                                    sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
+
+	    if (ptr) {
+                SEGPTR seg_ptr = MapLS( ptr );
+		*(LPWAVEHDR*)ptr = wh32;
+		wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
+		wh16->lpData = (LPSTR)seg_ptr + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
+		/* data will be copied on WODM_WRITE */
+		wh16->dwBufferLength = wh32->dwBufferLength;
+		wh16->dwBytesRecorded = wh32->dwBytesRecorded;
+		wh16->dwUser = wh32->dwUser;
+		wh16->dwFlags = wh32->dwFlags;
+		wh16->dwLoops = wh32->dwLoops;
+		/* FIXME: nothing on wh32->lpNext */
+		/* could link the wh32->lpNext at this level for memory house keeping */
+		wh32->lpNext = wh16; /* for reuse in unprepare and write */
+		TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
+		      seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
+		      wh32->dwBufferLength, (DWORD)wh32->lpData);
+		*lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
+		*lpParam2 = sizeof(WAVEHDR);
+
+		ret = WINMM_MAP_OKMEM;
+	    } else {
+		ret = WINMM_MAP_NOMEM;
+	    }
+	}
+	break;
+    case WODM_UNPREPARE:
+    case WODM_WRITE:
+	{
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)(*lpParam1);
+	    LPWAVEHDR		wh16 = wh32->lpNext;
+	    LPSTR		ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
+            SEGPTR seg_ptr = MapLS( ptr );
+
+	    assert(*(LPWAVEHDR*)ptr == wh32);
+
+	    TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
+		  seg_ptr + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
+		  wh32->dwBufferLength, (DWORD)wh32->lpData);
+
+	    if (wMsg == WODM_WRITE)
+		memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
+
+	    *lpParam1 = seg_ptr + sizeof(LPWAVEHDR);
+	    *lpParam2 = sizeof(WAVEHDR);
+	    /* dwBufferLength can be reduced between prepare & write */
+	    if (wMsg == WODM_WRITE && wh16->dwBufferLength < wh32->dwBufferLength) {
+		ERR("Size of buffer has been increased from %ld to %ld, keeping initial value\n",
+		    wh16->dwBufferLength, wh32->dwBufferLength);
+	    } else
+                wh16->dwBufferLength = wh32->dwBufferLength;
+	    ret = WINMM_MAP_OKMEM;
+	}
+	break;
+    case DRVM_MAPPER_STATUS:
+ 	{
+            LPDWORD p32 = (LPDWORD)*lpParam2;
+            *lpParam2 = MapLS(p32);
+            ret = WINMM_MAP_OKMEM;
+	}
+	break;
+    default:
+	FIXME("NIY: no conversion yet\n");
+	ret = WINMM_MAP_MSGERROR;
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_WaveOut_UnMap32ATo16	[internal]
+ */
+WINMM_MapType	MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
+{
+    WINMM_MapType	ret;
+
+    switch (wMsg) {
+	/* nothing to do */
+    case WODM_BREAKLOOP:
+    case WODM_CLOSE:
+    case WODM_GETNUMDEVS:
+    case WODM_PAUSE:
+    case WODM_RESET:
+    case WODM_RESTART:
+    case WODM_SETPITCH:
+    case WODM_SETPLAYBACKRATE:
+    case WODM_SETVOLUME:
+	ret = WINMM_MAP_OK;
+	break;
+
+    case WODM_GETDEVCAPS:
+	{
+	    LPWAVEOUTCAPS16		woc16 = MapSL(*lpParam1);
+	    LPSTR			ptr   = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
+            LPWAVEOUTCAPSA		woc32 = *(LPWAVEOUTCAPSA*)ptr;
+
+	    woc32->wMid = woc16->wMid;
+	    woc32->wPid = woc16->wPid;
+	    woc32->vDriverVersion = woc16->vDriverVersion;
+	    strcpy(woc32->szPname, woc16->szPname);
+	    woc32->dwFormats = woc16->dwFormats;
+	    woc32->wChannels = woc16->wChannels;
+	    woc32->dwSupport = woc16->dwSupport;
+            UnMapLS( *lpParam1 );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WODM_GETPITCH:
+	FIXME("NIY: no conversion yet\n");
+	ret = WINMM_MAP_MSGERROR;
+	break;
+    case WODM_GETPLAYBACKRATE:
+	FIXME("NIY: no conversion yet\n");
+	ret = WINMM_MAP_MSGERROR;
+	break;
+    case WODM_GETPOS:
+	{
+	    LPMMTIME16		mmt16 = MapSL(*lpParam1);
+	    LPSTR		ptr   = (LPSTR)mmt16 - sizeof(LPMMTIME);
+            LPMMTIME		mmt32 = *(LPMMTIME*)ptr;
+
+	    MMSYSTEM_MMTIME16to32(mmt32, mmt16);
+            UnMapLS( *lpParam1 );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WODM_OPEN:
+	{
+	    LPWAVEOPENDESC16		wod16 = MapSL(*lpParam1);
+	    LPSTR			ptr   = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
+            LPWAVEOPENDESC		wod32 = *(LPWAVEOPENDESC*)ptr;
+
+	    wod32->uMappedDeviceID = wod16->uMappedDeviceID;
+	    **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
+            UnMapLS( *lpParam1 );
+            HeapFree( GetProcessHeap(), 0, ptr );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WODM_PREPARE:
+    case WODM_UNPREPARE:
+    case WODM_WRITE:
+	{
+	    LPWAVEHDR		wh16 = MapSL(*lpParam1);
+	    LPSTR		ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
+	    LPWAVEHDR		wh32 = *(LPWAVEHDR*)ptr;
+
+	    assert(wh32->lpNext == wh16);
+	    wh32->dwBytesRecorded = wh16->dwBytesRecorded;
+	    wh32->dwUser = wh16->dwUser;
+	    wh32->dwFlags = wh16->dwFlags;
+	    wh32->dwLoops = wh16->dwLoops;
+
+            UnMapLS( *lpParam1 );
+	    if (wMsg == WODM_UNPREPARE) {
+                HeapFree( GetProcessHeap(), 0, ptr );
+		wh32->lpNext = 0;
+	    }
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    case WODM_GETVOLUME:
+	FIXME("NIY: no conversion yet\n");
+	ret = WINMM_MAP_MSGERROR;
+	break;
+    case DRVM_MAPPER_STATUS:
+	{
+            UnMapLS( *lpParam2 );
+	    ret = WINMM_MAP_OK;
+	}
+	break;
+    default:
+	FIXME("NIY: no conversion yet\n");
+	ret = WINMM_MAP_MSGERROR;
+	break;
+    }
+    return ret;
+}
+
+/**************************************************************************
+ * 				MMDRV_WaveOut_Callback		[internal]
+ */
+void	CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
+{
+    LPWINE_MLD	mld = (LPWINE_MLD)dwInstance;
+
+    switch (uMsg) {
+    case WOM_OPEN:
+    case WOM_CLOSE:
+	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
+	break;
+    case WOM_DONE:
+	if (mld->bFrom32 && !MMDRV_Is32(mld->mmdIndex)) {
+	    /* initial map is: 32 => 16 */
+	    LPWAVEHDR		wh16 = MapSL(dwParam1);
+	    LPWAVEHDR		wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
+
+	    dwParam1 = (DWORD)wh32;
+	    wh32->dwFlags = wh16->dwFlags;
+	} else if (!mld->bFrom32 && MMDRV_Is32(mld->mmdIndex)) {
+	    /* initial map is: 16 => 32 */
+	    LPWAVEHDR		wh32 = (LPWAVEHDR)(dwParam1);
+	    SEGPTR		segwh16 = *(SEGPTR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
+	    LPWAVEHDR		wh16 = MapSL(segwh16);
+
+	    dwParam1 = (DWORD)segwh16;
+	    wh16->dwFlags = wh32->dwFlags;
+	}
+	/* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
+	break;
+    default:
+	ERR("Unknown msg %u\n", uMsg);
+    }
+
+    MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
+}
+
+/**************************************************************************
+ * 				MMDRV_GetDescription16		[internal]
+ */
+BOOL	MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
+{
+    OFSTRUCT   	ofs;
+    HFILE	hFile;
+    WORD 	w;
+    DWORD	dw;
+    BOOL	ret = FALSE;
+
+    if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
+	ERR("Can't open file %s (builtin driver ?)\n", fname);
+	return FALSE;
+    }
+
+#define E(_x)	do {TRACE _x;goto theEnd;} while(0)
+
+    if (_lread(hFile, &w, 2) != 2)			E(("Can't read sig\n"));
+    if (w != ('Z' * 256 + 'M')) 			E(("Bad sig %04x\n", w));
+    if (_llseek(hFile, 0x3C, SEEK_SET) < 0) 		E(("Can't seek to ext header offset\n"));
+    if (_lread(hFile, &dw, 4) != 4)			E(("Can't read ext header offset\n"));
+    if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) 	E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
+    if (_lread(hFile, &dw, 4) != 4)			E(("Can't read nr table offset\n"));
+    if (_llseek(hFile, dw, SEEK_SET) < 0) 		E(("Can't seek to nr table %lu\n", dw));
+    if (_lread(hFile, buf, 1) != 1)			E(("Can't read descr length\n"));
+    buflen = min((int)(unsigned)(BYTE)buf[0], buflen - 1);
+    if (_lread(hFile, buf, buflen) != buflen)		E(("Can't read descr (%d)\n", buflen));
+    buf[buflen] = '\0';
+    ret = TRUE;
+    TRACE("Got '%s' [%d]\n", buf, buflen);
+theEnd:
+    CloseHandle(hFile);
+    return ret;
+}
+
+/* =================================
+ *              M C I
+ * ================================= */
+
 /**************************************************************************
  * 			MCI_MapMsg16To32A			[internal]
  */
--- ../winmm_m/winemm.h	Sat Oct 26 19:02:05 2002
+++ winemm.h	Sat Oct 26 19:24:15 2002
@@ -57,6 +57,40 @@
     struct tagWINE_DRIVER*	lpNextItem;
 } WINE_DRIVER, *LPWINE_DRIVER;
 
+typedef	DWORD	(CALLBACK *WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
+typedef	DWORD	(CALLBACK *WINEMM_msgFunc32)(UINT  , UINT, DWORD, DWORD, DWORD);
+
+/* for each loaded driver and each known type of driver, this structure contains
+ * the information needed to access it
+ */
+typedef struct tagWINE_MM_DRIVER_PART {
+    int				nIDMin;		/* lower bound of global indexes for this type */
+    int				nIDMax;		/* hhigher bound of global indexes for this type */
+    union {
+	WINEMM_msgFunc32	fnMessage32;	/* pointer to fonction */
+	WINEMM_msgFunc16	fnMessage16;
+    } u;
+} WINE_MM_DRIVER_PART;
+
+#define	MMDRV_AUX		0
+#define	MMDRV_MIXER		1
+#define	MMDRV_MIDIIN		2
+#define	MMDRV_MIDIOUT		3
+#define	MMDRV_WAVEIN		4
+#define	MMDRV_WAVEOUT		5
+#define MMDRV_MAX		6
+
+/* each low-level .drv will be associated with an instance of this structure */
+typedef struct tagWINE_MM_DRIVER {
+    HDRVR			hDriver;
+    LPSTR			drvname;	/* name of the driver */
+    BOOL			bIs32 : 1,	/* TRUE if 32 bit driver, FALSE for 16 */
+	                        bIsMapper : 1;	/* TRUE if mapper */
+    WINE_MM_DRIVER_PART		parts[MMDRV_MAX];/* Information for all known types */
+} WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
+
+typedef	WINMM_MapType	(*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+
 typedef struct tagWINE_MLD {
 /* EPP struct tagWINE_MLD*	lpNext; */		/* not used so far */
        UINT			uDeviceID;
@@ -83,26 +117,6 @@
        WINE_MLD			mld;
 } WINE_MIXER, *LPWINE_MIXER;
 
-extern	BOOL		MMDRV_Init(void);
-extern	UINT		MMDRV_GetNum(UINT);
-extern	LPWINE_MLD	MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
-				    DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32);
-extern	void		MMDRV_Free(HANDLE hndl, LPWINE_MLD mld);
-extern	DWORD		MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwParam2);
-extern	DWORD		MMDRV_Close(LPWINE_MLD mld, UINT wMsg);
-extern	LPWINE_MLD	MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID);
-extern  LPWINE_MLD	MMDRV_GetRelated(HANDLE hndl, UINT srcType, BOOL bSrcCanBeID, UINT dstTyped);
-extern	DWORD		MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1, DWORD dwParam2, BOOL bFrom32);
-extern	UINT		MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1, DWORD dwParam2);
-
-#define	MMDRV_AUX		0
-#define	MMDRV_MIXER		1
-#define	MMDRV_MIDIIN		2
-#define	MMDRV_MIDIOUT		3
-#define	MMDRV_WAVEIN		4
-#define	MMDRV_WAVEOUT		5
-#define MMDRV_MAX		6
-
 #define WINE_MMTHREAD_CREATED	0x4153494C	/* "BSIL" */
 #define WINE_MMTHREAD_DELETED	0xDEADDEAD
 
@@ -215,63 +229,114 @@
 typedef LONG			(*MCIPROC16)(DWORD, HDRVR16, WORD, DWORD, DWORD);
 typedef LONG			(*MCIPROC)(DWORD, HDRVR, DWORD, DWORD, DWORD);
 
-extern LPWINE_DRIVER		DRIVER_FindFromHDrvr(HDRVR hDrvr);
-extern BOOL			DRIVER_GetLibName(LPCSTR keyName, LPCSTR sectName, LPSTR buf, int sz);
-extern LPWINE_DRIVER		DRIVER_TryOpenDriver32(LPCSTR fn, LPARAM lParam2);
-
-extern LPWINE_MCIDRIVER		MCI_GetDriver(UINT16 uDevID);
-extern UINT			MCI_GetDriverFromString(LPCSTR str);
-extern DWORD			MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr);
-extern const char* 		MCI_MessageToString(UINT16 wMsg);
-
-extern UINT		WINAPI	MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data);
-
-extern LRESULT			MCI_CleanUp(LRESULT dwRet, UINT wMsg, DWORD dwParam2, BOOL bIs32);
-
-extern DWORD			MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2, BOOL bFrom32);
-extern DWORD 			MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2);
-extern DWORD 			MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2);
-
-void		CALLBACK	WINE_mmThreadEntryPoint(DWORD _pmt);
-
-void 				MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16);
-void 				MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32);
-
-UINT                            MMSYSTEM_mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback,
-                                                   DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32);
-UINT                            MMSYSTEM_midiOutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, DWORD dwCallback,
-                                                     DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
-UINT                            MMSYSTEM_midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID, DWORD dwCallback,
-                                                    DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
-MMRESULT                        MMSYSTEM_MidiStream_Open(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
-                                                         DWORD cMidi, DWORD dwCallback,
-                                                         DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32);
-UINT                            MMSYSTEM_waveOpen(HANDLE* lphndl, UINT uDeviceID, UINT uType,
-                                                  const LPWAVEFORMATEX lpFormat, DWORD dwCallback, 
-                                                  DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
-WORD	                        timeSetEventInternal(UINT wDelay, UINT wResol,
-                                                     FARPROC16 lpFunc, DWORD dwUser, UINT wFlags);
-HMMIO                           MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo,
-                                          DWORD dwOpenFlags, enum mmioProcType type);
-LPMMIOPROC                      MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
-                                                   DWORD dwFlags, enum mmioProcType type);
-LRESULT                         MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1, 
-                                                 LPARAM lParam2, enum mmioProcType type);
-LPWINE_MMIO	                MMIO_Get(HMMIO h);
+LPWINE_DRIVER	DRIVER_FindFromHDrvr(HDRVR hDrvr);
+BOOL		DRIVER_GetLibName(LPCSTR keyName, LPCSTR sectName, LPSTR buf, int sz);
+LPWINE_DRIVER	DRIVER_TryOpenDriver32(LPCSTR fn, LPARAM lParam2);
+
+BOOL		MMDRV_Init(void);
+UINT		MMDRV_GetNum(UINT);
+LPWINE_MLD	MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
+                            DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32);
+void		MMDRV_Free(HANDLE hndl, LPWINE_MLD mld);
+DWORD		MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwParam2);
+DWORD		MMDRV_Close(LPWINE_MLD mld, UINT wMsg);
+LPWINE_MLD	MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID);
+LPWINE_MLD	MMDRV_GetRelated(HANDLE hndl, UINT srcType, BOOL bSrcCanBeID, UINT dstTyped);
+DWORD		MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1, DWORD dwParam2, BOOL bFrom32);
+UINT		MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1, DWORD dwParam2);
+BOOL            MMDRV_Is32(unsigned int);
+
+WINE_MCIDRIVER* MCI_GetDriver(UINT16 uDevID);
+UINT		MCI_GetDriverFromString(LPCSTR str);
+DWORD		MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr);
+const char* 	MCI_MessageToString(UINT16 wMsg);
+UINT	WINAPI	MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data);
+LRESULT		MCI_CleanUp(LRESULT dwRet, UINT wMsg, DWORD dwParam2, BOOL bIs32);
+DWORD		MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2, BOOL bFrom32);
+DWORD		MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2);
+DWORD		MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2);
+
+void CALLBACK	WINE_mmThreadEntryPoint(DWORD _pmt);
+
+void 		MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16);
+void 		MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32);
+
+UINT            MMSYSTEM_mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback,
+                                   DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32);
+UINT            MMSYSTEM_midiOutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, DWORD dwCallback,
+                                     DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
+UINT            MMSYSTEM_midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID, DWORD dwCallback,
+                                    DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
+MMRESULT        MMSYSTEM_MidiStream_Open(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
+                                         DWORD cMidi, DWORD dwCallback,
+                                         DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32);
+UINT            MMSYSTEM_waveOpen(HANDLE* lphndl, UINT uDeviceID, UINT uType,
+                                  const LPWAVEFORMATEX lpFormat, DWORD dwCallback, 
+                                  DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
+
+WORD            timeSetEventInternal(UINT wDelay, UINT wResol,
+                                     FARPROC16 lpFunc, DWORD dwUser, UINT wFlags);
+
+HMMIO           MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo,
+                          DWORD dwOpenFlags, enum mmioProcType type);
+LPMMIOPROC      MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc,
+                                   DWORD dwFlags, enum mmioProcType type);
+LRESULT         MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1, 
+                                 LPARAM lParam2, enum mmioProcType type);
+LPWINE_MMIO     MMIO_Get(HMMIO h);
 
-BOOL				MULTIMEDIA_MciInit(void);
-BOOL                            MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode);
+BOOL    	MULTIMEDIA_MciInit(void);
+BOOL            MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode);
 
-void    			TIME_MMTimeStart(void);
-void				TIME_MMTimeStop(void);
+void    	TIME_MMTimeStart(void);
+void		TIME_MMTimeStop(void);
 
-/* temporary defines */
+/* temporary definitions */
 WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2);
 WINMM_MapType DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2);
 WINMM_MapType	MCI_MapMsg16To32A  (WORD uDevType, WORD wMsg,                DWORD* lParam);
 WINMM_MapType	MCI_UnMapMsg16To32A(WORD uDevType, WORD wMsg,                DWORD  lParam);
 WINMM_MapType	MCI_MapMsg32ATo16  (WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD* lParam);
 WINMM_MapType	MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD  lParam);
+void	MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2);
+
+WINMM_MapType	MMDRV_Aux_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_Aux_UnMap16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_Aux_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_Aux_UnMap32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+void	CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
+
+WINMM_MapType	MMDRV_Mixer_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_Mixer_UnMap16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_Mixer_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_Mixer_UnMap32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+void	CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
+
+WINMM_MapType	MMDRV_MidiIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_MidiIn_UnMap16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_MidiIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_MidiIn_UnMap32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+void	CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
+
+WINMM_MapType	MMDRV_MidiOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_MidiOut_UnMap16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_MidiOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_MidiOut_UnMap32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+void	CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
+
+WINMM_MapType	MMDRV_WaveIn_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_WaveIn_UnMap16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_WaveIn_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_WaveIn_UnMap32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+void	CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
+
+WINMM_MapType	MMDRV_WaveOut_Map16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_WaveOut_UnMap16To32A  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_WaveOut_Map32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+WINMM_MapType	MMDRV_WaveOut_UnMap32ATo16  (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
+void	CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
+
+BOOL	MMDRV_GetDescription16(const char* fname, char* buf, int buflen);
 
 /* Global variables */
 extern LPWINE_MM_IDATA		WINMM_IData;


More information about the wine-patches mailing list