示例#1
0
文件: mci16.c 项目: DeltaYang/wine
/**************************************************************************
 * 				mciSendCommand			[MMSYSTEM.701]
 */
DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD p2)
{
    DWORD		dwRet;
    BOOL                to32;
    DWORD_PTR           dwParam2 = p2;

    TRACE("(%04X, %s, %08X, %08lX)\n", wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);

    switch (wMsg) {
    case MCI_CLOSE:
    case MCI_OPEN:
    case MCI_SYSINFO:
    case MCI_BREAK:
    case MCI_SOUND:
        to32 = TRUE;
	break;
    default:
        /* FIXME: this is suboptimal. If MCI driver is a 16bit one, we'll be
         * doing 16=>32W, then 32W=>16 conversions.
         * We could directly call the 16bit driver if we had the information.
         */
        to32 = TRUE;
    }
    if (to32) {
        MMSYSTEM_MapType res;

	dwRet = MCIERR_INVALID_DEVICE_ID;

        switch (res = MCI_MapMsg16To32W(wMsg, dwParam1, &dwParam2)) {
        case MMSYSTEM_MAP_MSGERROR:
            dwRet = MCIERR_DRIVER_INTERNAL;
            break;
        case MMSYSTEM_MAP_NOMEM:
            TRACE("Problem mapping %s from 16 to 32\n", MCI_MessageToString(wMsg));
            dwRet = MCIERR_OUT_OF_MEMORY;
            break;
        case MMSYSTEM_MAP_OK:
        case MMSYSTEM_MAP_OKMEM:
            dwRet = mciSendCommandW(wDevID, wMsg, dwParam1, dwParam2);
            if (res == MMSYSTEM_MAP_OKMEM)
                MCI_UnMapMsg16To32W(wMsg, dwParam1, dwParam2, dwRet);
            break;
        }
    }
    else
    {
#if 0
	if (wDevID == MCI_ALL_DEVICE_ID) {
	    FIXME("unhandled MCI_ALL_DEVICE_ID\n");
	    dwRet = MCIERR_CANNOT_USE_ALL;
	} else {
            dwRet = SendDriverMessage(hdrv, wMsg, dwParam1, dwParam2);
	}
#endif
    }
    if (wMsg == MCI_CLOSE && dwRet == 0 && MCI_Thunks)
    {
        /* free yield thunks, if any */
        unsigned    i;
        for (i = 0; i < MCI_MAX_THUNKS; i++)
        {
            if (MCI_Thunks[i].id == wDevID)
                MCI_Thunks[i].yield16 = NULL;
        }
    }
    return dwRet;
}
示例#2
0
文件: mci16.c 项目: DeltaYang/wine
/**************************************************************************
 * 			MCI_MapMsg16To32W			[internal]
 */
static MMSYSTEM_MapType	MCI_MapMsg16To32W(WORD wMsg, DWORD dwFlags, DWORD_PTR* lParam)
{
    if (*lParam == 0)
	return MMSYSTEM_MAP_OK;
    /* FIXME: to add also (with seg/linear modifications to do):
     * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
     * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
     */
    switch (wMsg) {
	/* case MCI_CAPTURE */
    case MCI_CLOSE:
    case MCI_CLOSE_DRIVER:
    case MCI_CONFIGURE:
    case MCI_COPY:
    case MCI_CUE:
    case MCI_CUT:
    case MCI_DELETE:
    case MCI_GETDEVCAPS:
	/* case MCI_INDEX: */
	/* case MCI_MARK: */
	/* case MCI_MONITOR: */
    case MCI_PASTE:
    case MCI_PAUSE:
    case MCI_PLAY:
    case MCI_REALIZE:
    case MCI_RECORD:
    case MCI_RESUME:
    case MCI_SEEK:
    case MCI_SET:
	/* case MCI_SETTIMECODE:*/
	/* case MCI_SIGNAL:*/
    case MCI_SPIN:
    case MCI_STEP:
    case MCI_STOP:
	/* case MCI_UNDO: */
    case MCI_UPDATE:
	*lParam = (DWORD)MapSL(*lParam);
	return MMSYSTEM_MAP_OK;
    case MCI_WHERE:
    case MCI_FREEZE:
    case MCI_UNFREEZE:
    case MCI_PUT:
        {
            LPMCI_DGV_RECT_PARMS mdrp32 = HeapAlloc(GetProcessHeap(), 0,
                sizeof(LPMCI_DGV_RECT_PARMS16) + sizeof(MCI_DGV_RECT_PARMS));
            LPMCI_DGV_RECT_PARMS16 mdrp16 = MapSL(*lParam);
            if (mdrp32) {
                *(LPMCI_DGV_RECT_PARMS16*)(mdrp32) = mdrp16;
                mdrp32 = (LPMCI_DGV_RECT_PARMS)((char*)mdrp32 + sizeof(LPMCI_DGV_RECT_PARMS16));
                mdrp32->dwCallback = mdrp16->dwCallback;
                mdrp32->rc.left = mdrp16->rc.left;
                mdrp32->rc.top = mdrp16->rc.top;
                mdrp32->rc.right = mdrp16->rc.right;
                mdrp32->rc.bottom = mdrp16->rc.bottom;
            } else {
                return MMSYSTEM_MAP_NOMEM;
            }
            *lParam = (DWORD)mdrp32;
        }
        return MMSYSTEM_MAP_OKMEM;
    case MCI_STATUS:
        {
            if (dwFlags & (MCI_DGV_STATUS_REFERENCE | MCI_DGV_STATUS_DISKSPACE)) {
                LPMCI_DGV_STATUS_PARMSW mdsp32w = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                    sizeof(LPMCI_DGV_STATUS_PARMS16) + sizeof(MCI_DGV_STATUS_PARMSW));
                LPMCI_DGV_STATUS_PARMS16 mdsp16 = MapSL(*lParam);
                if (mdsp32w) {
                    *(LPMCI_DGV_STATUS_PARMS16*)(mdsp32w) = mdsp16;
                    mdsp32w = (LPMCI_DGV_STATUS_PARMSW)((char*)mdsp32w + sizeof(LPMCI_DGV_STATUS_PARMS16));
                    mdsp32w->dwCallback = mdsp16->dwCallback;
                    mdsp32w->dwReturn = mdsp16->dwReturn;
                    mdsp32w->dwItem = mdsp16->dwItem;
                    mdsp32w->dwTrack = mdsp16->dwTrack;
                    if (dwFlags & MCI_DGV_STATUS_DISKSPACE)
                        mdsp32w->lpstrDrive = MCI_strdupAtoW(MapSL(mdsp16->lpstrDrive));
                    if (dwFlags & MCI_DGV_STATUS_REFERENCE)
                        mdsp32w->dwReference = mdsp16->dwReference;
                    *lParam = (DWORD)mdsp32w;
                } else {
                    return MMSYSTEM_MAP_NOMEM;
                }
            } else {
                *lParam = (DWORD)MapSL(*lParam);
                return MMSYSTEM_MAP_OK;
            }
        }
        return MMSYSTEM_MAP_OKMEM;
    case MCI_WINDOW:
        {
            LPMCI_OVLY_WINDOW_PARMSW mowp32w = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MCI_OVLY_WINDOW_PARMSW));
            LPMCI_OVLY_WINDOW_PARMS16 mowp16 = MapSL(*lParam);
            if (mowp32w) {
                mowp32w->dwCallback = mowp16->dwCallback;
                mowp32w->hWnd = HWND_32(mowp16->hWnd);
                mowp32w->nCmdShow = mowp16->nCmdShow;
                if (dwFlags & (MCI_DGV_WINDOW_TEXT | MCI_OVLY_WINDOW_TEXT))
                    mowp32w->lpstrText = MCI_strdupAtoW(MapSL(mowp16->lpstrText));
            } else {
                return MMSYSTEM_MAP_NOMEM;
            }
            *lParam = (DWORD)mowp32w;
        }
        return MMSYSTEM_MAP_OKMEM;
    case MCI_BREAK:
	{
            LPMCI_BREAK_PARMS		mbp32 = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_BREAK_PARMS));
	    LPMCI_BREAK_PARMS16		mbp16 = MapSL(*lParam);

	    if (mbp32) {
		mbp32->dwCallback = mbp16->dwCallback;
		mbp32->nVirtKey = mbp16->nVirtKey;
		mbp32->hwndBreak = HWND_32(mbp16->hwndBreak);
	    } else {
		return MMSYSTEM_MAP_NOMEM;
	    }
	    *lParam = (DWORD)mbp32;
	}
	return MMSYSTEM_MAP_OKMEM;
    case MCI_ESCAPE:
	{
            LPMCI_VD_ESCAPE_PARMSW	mvep32w = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_VD_ESCAPE_PARMSW));
	    LPMCI_VD_ESCAPE_PARMS16	mvep16  = MapSL(*lParam);

	    if (mvep32w) {
		mvep32w->dwCallback       = mvep16->dwCallback;
		mvep32w->lpstrCommand     = MCI_strdupAtoW(MapSL(mvep16->lpstrCommand));
	    } else {
		return MMSYSTEM_MAP_NOMEM;
	    }
	    *lParam = (DWORD)mvep32w;
	}
	return MMSYSTEM_MAP_OKMEM;
    case MCI_INFO:
	{
            LPMCI_DGV_INFO_PARMSW	mip32w = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_DGV_INFO_PARMS16) + sizeof(MCI_DGV_INFO_PARMSW));
	    LPMCI_DGV_INFO_PARMS16	mip16  = MapSL(*lParam);

	    if (mip32w) {
		*(LPMCI_DGV_INFO_PARMS16*)(mip32w) = mip16;
		mip32w = (LPMCI_DGV_INFO_PARMSW)((char*)mip32w + sizeof(LPMCI_DGV_INFO_PARMS16));
		mip32w->dwCallback  = mip16->dwCallback;
		mip32w->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mip16->dwRetSize * sizeof(WCHAR));
		mip32w->dwRetSize   = mip16->dwRetSize;
		if (dwFlags & MCI_DGV_INFO_ITEM)
		    mip32w->dwItem  = mip16->dwItem;
	    } else {
		return MMSYSTEM_MAP_NOMEM;
	    }
	    *lParam = (DWORD)mip32w;
	}
	return MMSYSTEM_MAP_OKMEM;
    case MCI_OPEN:
    case MCI_OPEN_DRIVER:
	{
            LPMCI_OPEN_PARMSW	mop32w = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_ANIM_OPEN_PARMSW));
	    LPMCI_OPEN_PARMS16	mop16  = MapSL(*lParam);

	    if (mop32w) {
		*(LPMCI_OPEN_PARMS16*)(mop32w) = mop16;
		mop32w = (LPMCI_OPEN_PARMSW)((char*)mop32w + sizeof(LPMCI_OPEN_PARMS16));
		mop32w->dwCallback       = mop16->dwCallback;
		mop32w->wDeviceID        = mop16->wDeviceID;
                if( ( dwFlags & ( MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID)) == MCI_OPEN_TYPE)
                    mop32w->lpstrDeviceType  = MCI_strdupAtoW(MapSL(mop16->lpstrDeviceType));
                else
                    mop32w->lpstrDeviceType  = (LPWSTR) mop16->lpstrDeviceType;
                if( ( dwFlags & ( MCI_OPEN_ELEMENT | MCI_OPEN_ELEMENT_ID)) == MCI_OPEN_ELEMENT)
                    mop32w->lpstrElementName = MCI_strdupAtoW(MapSL(mop16->lpstrElementName));
                else
                    mop32w->lpstrElementName = (LPWSTR) mop16->lpstrElementName;
                if( ( dwFlags &  MCI_OPEN_ALIAS))
                    mop32w->lpstrAlias = MCI_strdupAtoW(MapSL(mop16->lpstrAlias));
                else
                    mop32w->lpstrAlias = (LPWSTR) mop16->lpstrAlias;
		/* copy extended information if any...
		 * FIXME: this may seg fault if initial structure does not contain them and
		 * the reads after msip16 fail under LDT limits...
		 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
		 * should not take care of extended parameters, and should be used by MCI_Open
		 * to fetch uDevType. When, this is known, the mapping for sending the
		 * MCI_OPEN_DRIVER shall be done depending on uDevType.
		 */
		if (HIWORD(dwFlags))
		    memcpy(mop32w + 1, mop16 + 1, sizeof(MCI_ANIM_OPEN_PARMS16) - sizeof(MCI_OPEN_PARMS16));
	    } else {
		return MMSYSTEM_MAP_NOMEM;
	    }
	    *lParam = (DWORD)mop32w;
	}
	return MMSYSTEM_MAP_OKMEM;
    case MCI_SYSINFO:
    {
        MCI_SYSINFO_PARMSW *origmsip32w;
        MCI_SYSINFO_PARMSW *msip32w = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_OPEN_PARMS16 *) + sizeof(MCI_SYSINFO_PARMSW));
        MCI_SYSINFO_PARMS16 *msip16 = MapSL(*lParam);

        if (!msip32w)
            return MMSYSTEM_MAP_NOMEM;

        origmsip32w = msip32w;
        *(MCI_SYSINFO_PARMS16 **)msip32w = msip16;
        msip32w = (MCI_SYSINFO_PARMSW *)((char *)msip32w + sizeof(MCI_OPEN_PARMS16 *));
        msip32w->dwCallback       = msip16->dwCallback;
        msip32w->lpstrReturn      = HeapAlloc(GetProcessHeap(), 0, (dwFlags & MCI_SYSINFO_QUANTITY) ?
                                                                    sizeof(DWORD) :
                                                                    msip16->dwRetSize * sizeof(WCHAR));
        if (!msip32w->lpstrReturn)
        {
            HeapFree(GetProcessHeap(), 0, origmsip32w);
            return MMSYSTEM_MAP_NOMEM;
        }
        msip32w->dwRetSize        = (dwFlags & MCI_SYSINFO_QUANTITY) ? sizeof(DWORD) : msip16->dwRetSize;
        msip32w->dwNumber         = msip16->dwNumber;
        msip32w->wDeviceType      = msip16->wDeviceType;

        *lParam = (DWORD)msip32w;
    }
	return MMSYSTEM_MAP_OKMEM;
    case MCI_SOUND:
	{
            LPMCI_SOUND_PARMSW		mbp32 = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_SOUND_PARMSW));
	    LPMCI_SOUND_PARMS16		mbp16 = MapSL(*lParam);

	    if (mbp32) {
		mbp32->dwCallback = mbp16->dwCallback;
		mbp32->lpstrSoundName = MCI_strdupAtoW(MapSL(mbp16->lpstrSoundName));
	    } else {
		return MMSYSTEM_MAP_NOMEM;
	    }
	    *lParam = (DWORD)mbp32;
	}
	return MMSYSTEM_MAP_OKMEM;
    case DRV_LOAD:
    case DRV_ENABLE:
    case DRV_OPEN:
    case DRV_CLOSE:
    case DRV_DISABLE:
    case DRV_FREE:
    case DRV_CONFIGURE:
    case DRV_QUERYCONFIGURE:
    case DRV_INSTALL:
    case DRV_REMOVE:
    case DRV_EXITSESSION:
    case DRV_EXITAPPLICATION:
    case DRV_POWER:
	FIXME("This is a hack\n");
	return MMSYSTEM_MAP_OK;
    default:
	FIXME("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
    }
    return MMSYSTEM_MAP_MSGERROR;
}
示例#3
0
文件: mci16.c 项目: DeltaYang/wine
/**************************************************************************
 * 			MCI_UnMapMsg16To32W			[internal]
 */
static  void	MCI_UnMapMsg16To32W(WORD wMsg, DWORD dwFlags, DWORD_PTR lParam, DWORD result)
{
    switch (wMsg) {
    case MCI_WHERE:
    case MCI_FREEZE:
    case MCI_UNFREEZE:
    case MCI_PUT:
        if (lParam) {
            LPMCI_DGV_RECT_PARMS mdrp32 = (LPMCI_DGV_RECT_PARMS)lParam;
            char *base = (char*)lParam - sizeof(LPMCI_DGV_RECT_PARMS16);
            LPMCI_DGV_RECT_PARMS16 mdrp16 = *(LPMCI_DGV_RECT_PARMS16*)base;
            mdrp16->rc.left = mdrp32->rc.left;
            mdrp16->rc.top = mdrp32->rc.top;
            mdrp16->rc.right = mdrp32->rc.right;
            mdrp16->rc.bottom = mdrp32->rc.bottom;
            HeapFree(GetProcessHeap(), 0, base);
        }
        break;
    case MCI_STATUS:
        if (lParam) {
            LPMCI_DGV_STATUS_PARMSW mdsp32w = (LPMCI_DGV_STATUS_PARMSW)lParam;
            char *base = (char*)lParam - sizeof(LPMCI_DGV_STATUS_PARMS16);
            LPMCI_DGV_STATUS_PARMS16 mdsp16 = *(LPMCI_DGV_STATUS_PARMS16*)base;
            mdsp16->dwReturn = mdsp32w->dwReturn;
            HeapFree(GetProcessHeap(), 0, (LPVOID)mdsp32w->lpstrDrive);
            HeapFree(GetProcessHeap(), 0, base);
        }
        break;
    case MCI_WINDOW:
        if (lParam) {
            LPMCI_OVLY_WINDOW_PARMSW mowp32w = (LPMCI_OVLY_WINDOW_PARMSW)lParam;
            HeapFree(GetProcessHeap(), 0, (LPVOID)mowp32w->lpstrText);
            HeapFree(GetProcessHeap(), 0, mowp32w);
        }
        break;
    case MCI_BREAK:
	HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
        break;
    case MCI_ESCAPE:
        if (lParam) {
            LPMCI_VD_ESCAPE_PARMSW	mvep32W = (LPMCI_VD_ESCAPE_PARMSW)lParam;
            HeapFree(GetProcessHeap(), 0, (LPVOID)mvep32W->lpstrCommand);
            HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
        }
        break;
    case MCI_INFO:
        if (lParam) {
            LPMCI_INFO_PARMSW	        mip32w = (LPMCI_INFO_PARMSW)lParam;
            char                       *base   = (char*)lParam - sizeof(LPMCI_INFO_PARMS16);
	    LPMCI_INFO_PARMS16          mip16  = *(LPMCI_INFO_PARMS16*)base;

            if (result == MMSYSERR_NOERROR)
                WideCharToMultiByte(CP_ACP, 0,
                                    mip32w->lpstrReturn, mip32w->dwRetSize,
                                    MapSL(mip16->lpstrReturn), mip16->dwRetSize,
                                    NULL, NULL);
            mip16->dwRetSize = mip32w->dwRetSize; /* never update prior to NT? */
            HeapFree(GetProcessHeap(), 0, mip32w->lpstrReturn);
            HeapFree(GetProcessHeap(), 0, base);
        }
        break;
    case MCI_SYSINFO:
        if (lParam) {
            MCI_SYSINFO_PARMSW *msip32w = (MCI_SYSINFO_PARMSW *)lParam;
            char               *base    = (char*)lParam - sizeof(MCI_SYSINFO_PARMS16 *);
            MCI_SYSINFO_PARMS16 *msip16  = *(MCI_SYSINFO_PARMS16 **)base;

            if (dwFlags & MCI_SYSINFO_QUANTITY) {
                DWORD *quantity = MapSL(msip16->lpstrReturn);

                *quantity = *(DWORD *)msip32w->lpstrReturn;
            }
            else if (result == MMSYSERR_NOERROR) {
                WideCharToMultiByte(CP_ACP, 0,
                                    msip32w->lpstrReturn, msip32w->dwRetSize,
                                    MapSL(msip16->lpstrReturn), msip16->dwRetSize,
                                    NULL, NULL);
            }

            HeapFree(GetProcessHeap(), 0, msip32w->lpstrReturn);
            HeapFree(GetProcessHeap(), 0, base);
        }
        break;
    case MCI_SOUND:
        if (lParam) {
            LPMCI_SOUND_PARMSW          msp32W = (LPMCI_SOUND_PARMSW)lParam;
            HeapFree(GetProcessHeap(), 0, (LPVOID)msp32W->lpstrSoundName);
            HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
        }
        break;
    case MCI_OPEN:
    case MCI_OPEN_DRIVER:
	if (lParam) {
            LPMCI_OPEN_PARMSW	mop32w = (LPMCI_OPEN_PARMSW)lParam;
            char               *base   = (char*)lParam - sizeof(LPMCI_OPEN_PARMS16);
	    LPMCI_OPEN_PARMS16	mop16  = *(LPMCI_OPEN_PARMS16*)base;

	    mop16->wDeviceID = mop32w->wDeviceID;
            if( ( dwFlags & ( MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID)) == MCI_OPEN_TYPE)
                HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrDeviceType);
            if( ( dwFlags & ( MCI_OPEN_ELEMENT | MCI_OPEN_ELEMENT_ID)) == MCI_OPEN_ELEMENT)
                HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrElementName);
            if( ( dwFlags &  MCI_OPEN_ALIAS))
                HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrAlias);
            HeapFree(GetProcessHeap(), 0, base);
	}
        break;
    default:
	FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
    }
}
示例#4
0
文件: mci16.c 项目: diosmosis/wine
/**************************************************************************
 * 			MCI_UnMapMsg16To32W			[internal]
 */
static  MMSYSTEM_MapType	MCI_UnMapMsg16To32W(WORD wMsg, DWORD dwFlags, DWORD_PTR lParam)
{
    switch (wMsg) {
	/* case MCI_CAPTURE */
    case MCI_CLOSE:
    case MCI_CLOSE_DRIVER:
    case MCI_CONFIGURE:
    case MCI_COPY:
    case MCI_CUE:
    case MCI_CUT:
    case MCI_DELETE:
    case MCI_GETDEVCAPS:
	/* case MCI_INDEX: */
	/* case MCI_MARK: */
	/* case MCI_MONITOR: */
    case MCI_PASTE:
    case MCI_PAUSE:
    case MCI_PLAY:
    case MCI_REALIZE:
    case MCI_RECORD:
    case MCI_RESUME:
    case MCI_SEEK:
    case MCI_SET:
	/* case MCI_SETTIMECODE:*/
	/* case MCI_SIGNAL:*/
    case MCI_SPIN:
    case MCI_STEP:
    case MCI_STOP:
	/* case MCI_UNDO: */
    case MCI_UPDATE:
	return MMSYSTEM_MAP_OK;

    case MCI_WHERE:
    case MCI_FREEZE:
    case MCI_UNFREEZE:
    case MCI_PUT:
        if (lParam) {
            LPMCI_DGV_RECT_PARMS mdrp32 = (LPMCI_DGV_RECT_PARMS)lParam;
            char *base = (char*)lParam - sizeof(LPMCI_DGV_RECT_PARMS16);
            LPMCI_DGV_RECT_PARMS16 mdrp16 = *(LPMCI_DGV_RECT_PARMS16*)base;
            mdrp16->dwCallback = mdrp32->dwCallback;
            mdrp16->rc.left = mdrp32->rc.left;
            mdrp16->rc.top = mdrp32->rc.top;
            mdrp16->rc.right = mdrp32->rc.right;
            mdrp16->rc.bottom = mdrp32->rc.bottom;
            HeapFree(GetProcessHeap(), 0, base);
        }
        return MMSYSTEM_MAP_OK;
    case MCI_STATUS:
        if (lParam && (dwFlags & (MCI_DGV_STATUS_REFERENCE | MCI_DGV_STATUS_DISKSPACE))) {
            LPMCI_DGV_STATUS_PARMSW mdsp32w = (LPMCI_DGV_STATUS_PARMSW)lParam;
            char *base = (char*)lParam - sizeof(LPMCI_DGV_STATUS_PARMS16);
            LPMCI_DGV_STATUS_PARMS16 mdsp16 = *(LPMCI_DGV_STATUS_PARMS16*)base;
            mdsp16->dwCallback = mdsp32w->dwCallback;
            mdsp16->dwReturn = mdsp32w->dwReturn;
            mdsp16->dwItem = mdsp32w->dwItem;
            mdsp16->dwTrack = mdsp32w->dwTrack;
            mdsp16->dwReference = mdsp32w->dwReference;
            HeapFree(GetProcessHeap(), 0, (LPVOID)mdsp32w->lpstrDrive);
            HeapFree(GetProcessHeap(), 0, base);
        }
        return MMSYSTEM_MAP_OK;
    case MCI_WINDOW:
        if (lParam) {
            LPMCI_OVLY_WINDOW_PARMSW mowp32w = (LPMCI_OVLY_WINDOW_PARMSW)lParam;
            HeapFree(GetProcessHeap(), 0, (LPVOID)mowp32w->lpstrText);
            HeapFree(GetProcessHeap(), 0, mowp32w);
        }
        return MMSYSTEM_MAP_OK;

    case MCI_BREAK:
	HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
	return MMSYSTEM_MAP_OK;
    case MCI_ESCAPE:
        if (lParam) {
            LPMCI_VD_ESCAPE_PARMSW	mvep32W = (LPMCI_VD_ESCAPE_PARMSW)lParam;
            HeapFree(GetProcessHeap(), 0, (LPVOID)mvep32W->lpstrCommand);
            HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
        }
	return MMSYSTEM_MAP_OK;
    case MCI_INFO:
        if (lParam) {
            LPMCI_INFO_PARMSW	        mip32w = (LPMCI_INFO_PARMSW)lParam;
            char                       *base   = (char*)lParam - sizeof(LPMCI_INFO_PARMS16);
	    LPMCI_INFO_PARMS16          mip16  = *(LPMCI_INFO_PARMS16*)base;

            WideCharToMultiByte(CP_ACP, 0,
                                mip32w->lpstrReturn, mip32w->dwRetSize / sizeof(WCHAR),
                                MapSL(mip16->lpstrReturn), mip16->dwRetSize,
                                NULL, NULL);
            HeapFree(GetProcessHeap(), 0, mip32w->lpstrReturn);
            HeapFree(GetProcessHeap(), 0, base);
        }
	return MMSYSTEM_MAP_OK;
    case MCI_SYSINFO:
        if (lParam) {
            MCI_SYSINFO_PARMSW *msip32w = (MCI_SYSINFO_PARMSW *)lParam;
            char               *base    = (char*)lParam - sizeof(MCI_SYSINFO_PARMS16 *);
            MCI_SYSINFO_PARMS16 *msip16  = *(MCI_SYSINFO_PARMS16 **)base;

            if (dwFlags & MCI_SYSINFO_QUANTITY) {
                DWORD *quantity = MapSL(msip16->lpstrReturn);

                *quantity = *(DWORD *)msip32w->lpstrReturn;
            }
            else {
                WideCharToMultiByte(CP_ACP, 0,
                                    msip32w->lpstrReturn, msip32w->dwRetSize,
                                    MapSL(msip16->lpstrReturn), msip16->dwRetSize,
                                    NULL, NULL);
            }

            HeapFree(GetProcessHeap(), 0, msip32w->lpstrReturn);
            HeapFree(GetProcessHeap(), 0, base);
        }
	return MMSYSTEM_MAP_OK;
    case MCI_SOUND:
        if (lParam) {
            LPMCI_SOUND_PARMSW          msp32W = (LPMCI_SOUND_PARMSW)lParam;
            HeapFree(GetProcessHeap(), 0, (LPVOID)msp32W->lpstrSoundName);
            HeapFree(GetProcessHeap(), 0, (LPVOID)lParam);
        }
	return MMSYSTEM_MAP_OK;
    case MCI_OPEN:
    case MCI_OPEN_DRIVER:
	if (lParam) {
            LPMCI_OPEN_PARMSW	mop32w = (LPMCI_OPEN_PARMSW)lParam;
            char               *base   = (char*)lParam - sizeof(LPMCI_OPEN_PARMS16);
	    LPMCI_OPEN_PARMS16	mop16  = *(LPMCI_OPEN_PARMS16*)base;

	    mop16->wDeviceID = mop32w->wDeviceID;
            if( ( dwFlags & ( MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID)) == MCI_OPEN_TYPE)
                HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrDeviceType);
            if( ( dwFlags & ( MCI_OPEN_ELEMENT | MCI_OPEN_ELEMENT_ID)) == MCI_OPEN_ELEMENT)
                HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrElementName);
            if( ( dwFlags &  MCI_OPEN_ALIAS))
                HeapFree(GetProcessHeap(), 0, (LPWSTR)mop32w->lpstrAlias);
	    if (!HeapFree(GetProcessHeap(), 0, base))
		FIXME("bad free line=%d\n", __LINE__);
	}
	return MMSYSTEM_MAP_OK;
    case DRV_LOAD:
    case DRV_ENABLE:
    case DRV_OPEN:
    case DRV_CLOSE:
    case DRV_DISABLE:
    case DRV_FREE:
    case DRV_CONFIGURE:
    case DRV_QUERYCONFIGURE:
    case DRV_INSTALL:
    case DRV_REMOVE:
    case DRV_EXITSESSION:
    case DRV_EXITAPPLICATION:
    case DRV_POWER:
	FIXME("This is a hack\n");
	return MMSYSTEM_MAP_OK;
    default:
	FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
    }
    return MMSYSTEM_MAP_MSGERROR;
}