diff --git a/reactos/lib/winmm/.cvsignore b/reactos/lib/winmm/.cvsignore index a2a90a48943..b37e844ff3e 100644 --- a/reactos/lib/winmm/.cvsignore +++ b/reactos/lib/winmm/.cvsignore @@ -4,3 +4,4 @@ *.d *.sym *.map +*.spec.def \ No newline at end of file diff --git a/reactos/lib/winmm/Makefile b/reactos/lib/winmm/Makefile index 2f24a9dd4b7..da6c89451cf 100644 --- a/reactos/lib/winmm/Makefile +++ b/reactos/lib/winmm/Makefile @@ -1,51 +1,8 @@ -# $Id: makefile +# $Id: Makefile,v 1.12 2004/02/25 20:00:41 sedwards Exp $ PATH_TO_TOP = ../.. -TARGET_TYPE = dynlink - -TARGET_NAME = winmm - -TARGET_BASE = 0x777c0000 - -WINE_RC = winmm_res - -TARGET_CFLAGS = \ - -Wall \ - -fno-builtin - -# Compile definitions usage: -# __USE_W32API - Compilation with w32api headers -# __REACTOS__ - Compilation of Wine sources for ReactOS -# _WIN32_IE=0x600 - Internet Explorer 6 compatible defintions -# WINVER=0x501 - Windows XP definitions -# __need_offsetof - Force definition of macro offsetof in stddef.h -# -DEFINES = \ - -D_DISABLE_TIDENTS \ - -D__USE_W32API \ - -D__REACTOS__ \ - -D_WIN32_IE=0x600 \ - -D_WIN32_WINNT=0x501 \ - -DWINVER=0x501 - -TARGET_CFLAGS += \ - $(DEFINES) \ - -I$(PATH_TO_TOP)/include/wine - -TARGET_RCFLAGS += -D__REACTOS__ -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x501 - -TARGET_SDKLIBS = libwine.a ntdll.a kernel32.a - -TARGET_OBJECTS = \ - driver.o \ - joystick.o \ - lolvldrv.o \ - mci.o \ - mmio.o \ - playsound.o \ - time.o \ - winmm.o +TARGET_TYPE = winedll include $(PATH_TO_TOP)/rules.mak diff --git a/reactos/lib/winmm/Makefile.in b/reactos/lib/winmm/Makefile.in new file mode 100644 index 00000000000..39b3c461fc8 --- /dev/null +++ b/reactos/lib/winmm/Makefile.in @@ -0,0 +1,33 @@ +EXTRADEFS = -D_WINMM_ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = winmm.dll +IMPORTS = user32 advapi32 kernel32 ntdll +ALTNAMES = mmsystem.dll sound.dll + +SPEC_SRCS16 = $(ALTNAMES:.dll=.spec) + +C_SRCS = \ + driver.c \ + joystick.c \ + lolvldrv.c \ + mci.c \ + mmio.c \ + playsound.c \ + time.c \ + winmm.c + +C_SRCS16 = \ + message16.c \ + mmsystem.c \ + sound16.c + +RC_SRCS = winmm_res.rc + +SUBDIRS = tests + +@MAKE_DLL_RULES@ + +### Dependencies: diff --git a/reactos/lib/winmm/Makefile.ros b/reactos/lib/winmm/Makefile.ros new file mode 100644 index 00000000000..83748808560 --- /dev/null +++ b/reactos/lib/winmm/Makefile.ros @@ -0,0 +1,21 @@ +# $Id: Makefile.ros,v 1.1 2004/02/25 20:00:41 sedwards Exp $ + +TARGET_NAME = winmm + +TARGET_OBJECTS = driver.o joystick.o lolvldrv.o mci.o mmio.o playsound.o time.o winmm.o + +TARGET_CFLAGS = -D_WINMM_ -D__REACTOS__ + +TARGET_SDKLIBS = user32.a advapi32.a kernel32.a ntdll.a libwine.a wine_uuid.a ntdll.a + +TARGET_BASE = 0x76160000 + +TARGET_RC_SRCS = winmm_res.rc +TARGET_RC_BINSRC = +TARGET_RC_BINARIES = + +default: all + +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(TOOLS_PATH)/depend.mk diff --git a/reactos/lib/winmm/Makefile.ros-template b/reactos/lib/winmm/Makefile.ros-template new file mode 100644 index 00000000000..ef52169c385 --- /dev/null +++ b/reactos/lib/winmm/Makefile.ros-template @@ -0,0 +1,21 @@ +# $Id: Makefile.ros-template,v 1.1 2004/02/25 20:00:41 sedwards Exp $ + +TARGET_NAME = winmm + +TARGET_OBJECTS = @C_SRCS@ + +TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__ + +TARGET_SDKLIBS = @IMPORTS@ libwine.a wine_uuid.a ntdll.a + +TARGET_BASE = 0x76160000 + +TARGET_RC_SRCS = @RC_SRCS@ +TARGET_RC_BINSRC = @RC_BINSRC@ +TARGET_RC_BINARIES = @RC_BINARIES@ + +default: all + +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(TOOLS_PATH)/depend.mk diff --git a/reactos/lib/winmm/driver.c b/reactos/lib/winmm/driver.c index 076a0e0ff6e..4a43469049a 100644 --- a/reactos/lib/winmm/driver.c +++ b/reactos/lib/winmm/driver.c @@ -389,7 +389,7 @@ LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2) DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0L, 0L); lpDrv0->d.d32.dwDriverID = 0; DRIVER_RemoveFromList(lpDrv0); - FreeLibrary(lpDrv->d.d32.hModule); + FreeLibrary(lpDrv0->d.d32.hModule); HeapFree(GetProcessHeap(), 0, lpDrv0); } FreeLibrary(lpDrv->d.d32.hModule); diff --git a/reactos/lib/winmm/joystick.c b/reactos/lib/winmm/joystick.c index e21831dc0ca..b95a91bc61f 100644 --- a/reactos/lib/winmm/joystick.c +++ b/reactos/lib/winmm/joystick.c @@ -139,7 +139,7 @@ UINT WINAPI joyGetNumDevs(void) /************************************************************************** * joyGetDevCapsA [WINMM.@] */ -MMRESULT WINAPI joyGetDevCapsA(UINT wID, LPJOYCAPSA lpCaps, UINT wSize) +MMRESULT WINAPI joyGetDevCapsA(UINT_PTR wID, LPJOYCAPSA lpCaps, UINT wSize) { if (wID >= MAXJOYSTICK) return JOYERR_PARMS; if (!JOY_LoadDriver(wID)) return MMSYSERR_NODRIVER; @@ -153,7 +153,7 @@ MMRESULT WINAPI joyGetDevCapsA(UINT wID, LPJOYCAPSA lpCaps, UINT wSize) /************************************************************************** * joyGetDevCapsW [WINMM.@] */ -MMRESULT WINAPI joyGetDevCapsW(UINT wID, LPJOYCAPSW lpCaps, UINT wSize) +MMRESULT WINAPI joyGetDevCapsW(UINT_PTR wID, LPJOYCAPSW lpCaps, UINT wSize) { JOYCAPSA jca; MMRESULT ret = joyGetDevCapsA(wID, &jca, sizeof(jca)); diff --git a/reactos/lib/winmm/lolvldrv.c b/reactos/lib/winmm/lolvldrv.c index 4246d1f0aa0..4eb6b5b7da4 100644 --- a/reactos/lib/winmm/lolvldrv.c +++ b/reactos/lib/winmm/lolvldrv.c @@ -171,8 +171,8 @@ UINT MMDRV_GetNum(UINT type) /************************************************************************** * MMDRV_Message [internal] */ -DWORD MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1, - DWORD dwParam2, BOOL bFrom32) +DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, + DWORD_PTR dwParam2, BOOL bFrom32) { LPWINE_MM_DRIVER lpDrv; DWORD ret; @@ -502,7 +502,8 @@ UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1, case DRV_QUERYDSOUNDDESC: /* Wine-specific: Retrieve DirectSound driver description*/ case DRV_QUERYDSOUNDGUID: /* Wine-specific: Retrieve DirectSound driver GUID */ return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE); -#endif /* __REACTOS__ */ +#endif + default: WARN("Unknown call %04x\n", uMsg); return MMSYSERR_INVALPARAM; @@ -742,8 +743,9 @@ static BOOL MMDRV_InitFromRegistry(void) static BOOL MMDRV_InitHardcoded(void) { /* first load hardware drivers */ +#ifndef __REACTOS__ MMDRV_Install("wineoss.drv", "wineoss.drv", FALSE); - +#endif /* __REACTOS__ */ /* finish with mappers */ MMDRV_Install("wavemapper", "msacm.drv", TRUE); MMDRV_Install("midimapper", "midimap.drv", TRUE); diff --git a/reactos/lib/winmm/mci.c b/reactos/lib/winmm/mci.c index 79100505110..b22a00a9f00 100644 --- a/reactos/lib/winmm/mci.c +++ b/reactos/lib/winmm/mci.c @@ -1027,13 +1027,11 @@ DWORD WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR lpstrRet, */ if (lpstrRet && uRetLen) *lpstrRet = '\0'; -#define STR_OF(_x) (IsBadReadPtr((char*)_x,1)?"?":(char*)(_x)) TRACE("[%d, %s, %08lx, %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s]\n", wmd->wDeviceID, MCI_MessageToString(MCI_GetMessage(lpCmd)), dwFlags, - data[0], STR_OF(data[0]), data[1], STR_OF(data[1]), - data[2], STR_OF(data[2]), data[3], STR_OF(data[3]), - data[4], STR_OF(data[4]), data[5], STR_OF(data[5])); -#undef STR_OF + data[0], debugstr_a((char *)data[0]), data[1], debugstr_a((char *)data[1]), + data[2], debugstr_a((char *)data[2]), data[3], debugstr_a((char *)data[3]), + data[4], debugstr_a((char *)data[4]), data[5], debugstr_a((char *)data[5])); if (strcmp(verb, "open") == 0) { if ((dwRet = MCI_FinishOpen(wmd, (LPMCI_OPEN_PARMSA)data, dwFlags))) @@ -1157,7 +1155,7 @@ BOOL WINAPI mciFreeCommandResource(UINT uTable) /************************************************************************** * MCI_SendCommandFrom32 [internal] */ -DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2) +DWORD MCI_SendCommandFrom32(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { DWORD dwRet = MCIERR_INVALID_DEVICE_ID; LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID); @@ -1192,7 +1190,7 @@ DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwPa /************************************************************************** * MCI_SendCommandFrom16 [internal] */ -DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2) +DWORD MCI_SendCommandFrom16(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { DWORD dwRet = MCIERR_INVALID_DEVICE_ID; LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID); diff --git a/reactos/lib/winmm/message16.c b/reactos/lib/winmm/message16.c new file mode 100644 index 00000000000..475c988d18a --- /dev/null +++ b/reactos/lib/winmm/message16.c @@ -0,0 +1,2778 @@ +/* -*- tab-width: 8; c-basic-offset: 4 -*- */ + +/* + * MMSYTEM MCI and low level mapping functions + * + * Copyright 1999 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include "wine/winbase16.h" +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winver.h" +#include "wownt32.h" +#include "winemm16.h" +#include "digitalv.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winmm); + +/************************************************************************** + * MMDRV_Callback [internal] + */ +static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2) +{ + TRACE("CB (*%08lx)(%p %08x %08lx %08lx %08lx\n", + mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2); + + if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) + { + WORD args[8]; + /* 16 bit func, call it */ + TRACE("Function (16 bit) !\n"); + + args[7] = HDRVR_16(hDev); + args[6] = uMsg; + args[5] = HIWORD(mld->dwClientInstance); + args[4] = LOWORD(mld->dwClientInstance); + args[3] = HIWORD(dwParam1); + args[2] = LOWORD(dwParam1); + args[1] = HIWORD(dwParam2); + args[0] = LOWORD(dwParam2); + WOWCallback16Ex( mld->dwCallback, WCB16_PASCAL, sizeof(args), args, NULL ); + } 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, MMRESULT fn_ret) +{ + 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, MMRESULT fn_ret) +{ +#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, MMRESULT fn_ret) +{ +#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, MMRESULT fn_ret) +{ + 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, MMRESULT fn_ret) +{ + 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, MMRESULT fn_ret) +{ + 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 && !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] + */ +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, MMRESULT fn_ret) +{ + 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 && fn_ret == MMSYSERR_NOERROR) { + 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, MMRESULT fn_ret) +{ + 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 && fn_ret == MMSYSERR_NOERROR) { + 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 && !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] + */ +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, MMRESULT fn_ret) +{ + 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 && fn_ret == MMSYSERR_NOERROR) { + 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, MMRESULT fn_ret) +{ + 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 && fn_ret == MMSYSERR_NOERROR) { + 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 && !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] + */ +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, MMRESULT fn_ret) +{ + 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 && fn_ret == MMSYSERR_NOERROR) { + 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, MMRESULT fn_ret) +{ + 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 && fn_ret == MMSYSERR_NOERROR) { + 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 && !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); +} + +/* ================================= + * M A P P E R S H A N D L I N G + * ================================= */ + +static LRESULT MMDRV_CallMMDrvFunc16(DWORD fp16, WORD dev, WORD msg, LONG instance, + LONG lp1, LONG lp2) +{ + WORD args[8]; + DWORD ret; + + args[7] = dev; + args[6] = msg; + args[5] = HIWORD(instance); + args[4] = LOWORD(instance); + args[3] = HIWORD(lp1); + args[2] = LOWORD(lp1); + args[1] = HIWORD(lp2); + args[0] = LOWORD(lp2); + WOWCallback16Ex( fp16, WCB16_PASCAL, sizeof(args), args, &ret ); + return LOWORD(ret); +} + +/************************************************************************** + * MMDRV_GetDescription16 [internal] + */ +static 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: + _lclose(hFile); + return ret; +} + +/****************************************************************** + * MMDRV_LoadMMDrvFunc16 + * + */ +unsigned MMDRV_LoadMMDrvFunc16(LPCSTR drvName, LPWINE_DRIVER d, + LPWINE_MM_DRIVER lpDrv) +{ + WINEMM_msgFunc16 func; + unsigned count = 0; + char buffer[128]; + /* + * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver' + * The beginning of the module description indicates the driver supports + * waveform, auxiliary, and mixer devices. Use one of the following + * device-type names, followed by a colon (:) to indicate the type of + * device your driver supports. If the driver supports more than one + * type of device, separate each device-type name with a comma (,). + * + * wave for waveform audio devices + * wavemapper for wave mappers + * midi for MIDI audio devices + * midimapper for midi mappers + * aux for auxiliary audio devices + * mixer for mixer devices + */ + + if (d->d.d16.hDriver16) { + HMODULE16 hMod16 = GetDriverModuleHandle16(d->d.d16.hDriver16); + +#define AA(_h,_w,_x,_y,_z) \ + func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \ + if (func != NULL) \ + { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \ + TRACE("Got %d bit func '%s'\n", _y, #_x); } + +#define A(_x,_y) AA(hMod16,_x,_y,16,GetProcAddress16) + A(MMDRV_AUX, auxMessage); + A(MMDRV_MIXER, mxdMessage); + A(MMDRV_MIDIIN, midMessage); + A(MMDRV_MIDIOUT,modMessage); + A(MMDRV_WAVEIN, widMessage); + A(MMDRV_WAVEOUT,wodMessage); +#undef A +#undef AA + } + if (TRACE_ON(winmm)) { + if (MMDRV_GetDescription16(drvName, buffer, sizeof(buffer))) + TRACE("%s => %s\n", drvName, buffer); + else + TRACE("%s => No description\n", drvName); + } + + return count; +} + +/* ================================= + * M C I + * ================================= */ + +/************************************************************************** + * MCI_MapMsg16To32A [internal] + */ +static WINMM_MapType MCI_MapMsg16To32A(WORD uDevType, WORD wMsg, DWORD* lParam) +{ + if (*lParam == 0) + return WINMM_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_FREEZE: + case MCI_GETDEVCAPS: + /* case MCI_INDEX: */ + /* case MCI_MARK: */ + /* case MCI_MONITOR: */ + case MCI_PASTE: + case MCI_PAUSE: + case MCI_PLAY: + case MCI_PUT: + 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_STATUS: /* FIXME: is wrong for digital video */ + case MCI_STEP: + case MCI_STOP: + /* case MCI_UNDO: */ + case MCI_UNFREEZE: + case MCI_UPDATE: + case MCI_WHERE: + *lParam = (DWORD)MapSL(*lParam); + return WINMM_MAP_OK; + case MCI_WINDOW: + /* in fact, I would also need the dwFlags... to see + * which members of lParam are effectively used + */ + *lParam = (DWORD)MapSL(*lParam); + FIXME("Current mapping may be wrong\n"); + break; + 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 WINMM_MAP_NOMEM; + } + *lParam = (DWORD)mbp32; + } + return WINMM_MAP_OKMEM; + case MCI_ESCAPE: + { + LPMCI_VD_ESCAPE_PARMSA mvep32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_VD_ESCAPE_PARMSA)); + LPMCI_VD_ESCAPE_PARMS16 mvep16 = MapSL(*lParam); + + if (mvep32a) { + mvep32a->dwCallback = mvep16->dwCallback; + mvep32a->lpstrCommand = MapSL(mvep16->lpstrCommand); + } else { + return WINMM_MAP_NOMEM; + } + *lParam = (DWORD)mvep32a; + } + return WINMM_MAP_OKMEM; + case MCI_INFO: + { + LPMCI_INFO_PARMSA mip32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_INFO_PARMSA)); + LPMCI_INFO_PARMS16 mip16 = MapSL(*lParam); + + /* FIXME this is wrong if device is of type + * MCI_DEVTYPE_DIGITAL_VIDEO, some members are not mapped + */ + if (mip32a) { + mip32a->dwCallback = mip16->dwCallback; + mip32a->lpstrReturn = MapSL(mip16->lpstrReturn); + mip32a->dwRetSize = mip16->dwRetSize; + } else { + return WINMM_MAP_NOMEM; + } + *lParam = (DWORD)mip32a; + } + return WINMM_MAP_OKMEM; + case MCI_OPEN: + case MCI_OPEN_DRIVER: + { + LPMCI_OPEN_PARMSA mop32a = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_OPEN_PARMSA) + 2 * sizeof(DWORD)); + LPMCI_OPEN_PARMS16 mop16 = MapSL(*lParam); + + if (mop32a) { + *(LPMCI_OPEN_PARMS16*)(mop32a) = mop16; + mop32a = (LPMCI_OPEN_PARMSA)((char*)mop32a + sizeof(LPMCI_OPEN_PARMS16)); + mop32a->dwCallback = mop16->dwCallback; + mop32a->wDeviceID = mop16->wDeviceID; + mop32a->lpstrDeviceType = MapSL(mop16->lpstrDeviceType); + mop32a->lpstrElementName = MapSL(mop16->lpstrElementName); + mop32a->lpstrAlias = MapSL(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. + */ + memcpy(mop32a + 1, mop16 + 1, 2 * sizeof(DWORD)); + } else { + return WINMM_MAP_NOMEM; + } + *lParam = (DWORD)mop32a; + } + return WINMM_MAP_OKMEM; + case MCI_SYSINFO: + { + LPMCI_SYSINFO_PARMSA msip32a = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_SYSINFO_PARMSA)); + LPMCI_SYSINFO_PARMS16 msip16 = MapSL(*lParam); + + if (msip32a) { + msip32a->dwCallback = msip16->dwCallback; + msip32a->lpstrReturn = MapSL(msip16->lpstrReturn); + msip32a->dwRetSize = msip16->dwRetSize; + msip32a->dwNumber = msip16->dwNumber; + msip32a->wDeviceType = msip16->wDeviceType; + } else { + return WINMM_MAP_NOMEM; + } + *lParam = (DWORD)msip32a; + } + return WINMM_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 WINMM_MAP_OK; + + default: + WARN("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg)); + } + return WINMM_MAP_MSGERROR; +} + +/************************************************************************** + * MCI_UnMapMsg16To32A [internal] + */ +static WINMM_MapType MCI_UnMapMsg16To32A(WORD uDevType, WORD wMsg, DWORD 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_FREEZE: + case MCI_GETDEVCAPS: + /* case MCI_INDEX: */ + /* case MCI_MARK: */ + /* case MCI_MONITOR: */ + case MCI_PASTE: + case MCI_PAUSE: + case MCI_PLAY: + case MCI_PUT: + 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_STATUS: + case MCI_STEP: + case MCI_STOP: + /* case MCI_UNDO: */ + case MCI_UNFREEZE: + case MCI_UPDATE: + case MCI_WHERE: + return WINMM_MAP_OK; + + case MCI_WINDOW: + /* FIXME ?? see Map function */ + return WINMM_MAP_OK; + + case MCI_BREAK: + case MCI_ESCAPE: + case MCI_INFO: + case MCI_SYSINFO: + HeapFree(GetProcessHeap(), 0, (LPVOID)lParam); + return WINMM_MAP_OK; + case MCI_OPEN: + case MCI_OPEN_DRIVER: + if (lParam) { + LPMCI_OPEN_PARMSA mop32a = (LPMCI_OPEN_PARMSA)lParam; + LPMCI_OPEN_PARMS16 mop16 = *(LPMCI_OPEN_PARMS16*)((char*)mop32a - sizeof(LPMCI_OPEN_PARMS16)); + + mop16->wDeviceID = mop32a->wDeviceID; + if (!HeapFree(GetProcessHeap(), 0, (LPVOID)(lParam - sizeof(LPMCI_OPEN_PARMS16)))) + FIXME("bad free line=%d\n", __LINE__); + } + return WINMM_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 WINMM_MAP_OK; + default: + FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg)); + } + return WINMM_MAP_MSGERROR; +} + +/* + * 0000 stop + * 0001 squeeze signed 4 bytes to 2 bytes *( LPINT16)D = ( INT16)*( LPINT16)S; D += 2; S += 4 + * 0010 squeeze unsigned 4 bytes to 2 bytes *(LPUINT16)D = (UINT16)*(LPUINT16)S; D += 2; S += 4 + * 0100 + * 0101 + * 0110 zero 4 bytes *(DWORD)D = 0 D += 4; S += 4 + * 0111 copy string *(LPSTR*)D = seg dup(*(LPSTR*)S) D += 4; S += 4 + * 1xxx copy xxx + 1 bytes memcpy(D, S, xxx + 1); D += xxx+1; S += xxx+1 + */ + +/************************************************************************** + * MCI_MsgMapper32To16_Create [internal] + * + * Helper for MCI_MapMsg32ATo16. + * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit + * segmented pointer. + * map contains a list of action to be performed for the mapping (see list + * above) + * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area. + */ +static WINMM_MapType MCI_MsgMapper32To16_Create(void** ptr, int size16, DWORD map, BOOLEAN keep) +{ + void* lp = HeapAlloc( GetProcessHeap(), 0, (keep ? sizeof(void**) : 0) + size16 ); + LPBYTE p16, p32; + + if (!lp) { + return WINMM_MAP_NOMEM; + } + p32 = (LPBYTE)(*ptr); + if (keep) { + *(void**)lp = *ptr; + p16 = (LPBYTE)lp + sizeof(void**); + *ptr = (char*)MapLS(lp) + sizeof(void**); + } else { + p16 = lp; + *ptr = (void*)MapLS(lp); + } + + if (map == 0) { + memcpy(p16, p32, size16); + } else { + unsigned nibble; + unsigned sz; + + while (map & 0xF) { + nibble = map & 0xF; + if (nibble & 0x8) { + sz = (nibble & 7) + 1; + memcpy(p16, p32, sz); + p16 += sz; + p32 += sz; + size16 -= sz; /* DEBUG only */ + } else { + switch (nibble) { + case 0x1: + *(LPINT16)p16 = *(LPINT)p32; + p16 += sizeof(INT16); + p32 += sizeof(INT); + size16 -= sizeof(INT16); + break; + case 0x2: + *(LPUINT16)p16 = *(LPUINT)p32; + p16 += sizeof(UINT16); + p32 += sizeof(UINT); + size16 -= sizeof(UINT16); + break; + case 0x6: + *(LPDWORD)p16 = 0; + p16 += sizeof(DWORD); + p32 += sizeof(DWORD); + size16 -= sizeof(DWORD); + break; + case 0x7: + *(SEGPTR *)p16 = MapLS( *(LPSTR *)p32 ); + p16 += sizeof(SEGPTR); + p32 += sizeof(LPSTR); + size16 -= sizeof(SEGPTR); + break; + default: + FIXME("Unknown nibble for mapping (%x)\n", nibble); + } + } + map >>= 4; + } + if (size16 != 0) /* DEBUG only */ + FIXME("Mismatch between 16 bit struct size and map nibbles serie\n"); + } + return WINMM_MAP_OKMEM; +} + +/************************************************************************** + * MCI_MsgMapper32To16_Destroy [internal] + * + * Helper for MCI_UnMapMsg32ATo16. + */ +static WINMM_MapType MCI_MsgMapper32To16_Destroy(void* ptr, int size16, DWORD map, BOOLEAN kept) +{ + if (ptr) { + void* msg16 = MapSL((SEGPTR)ptr); + void* alloc; + LPBYTE p32, p16; + unsigned nibble; + + UnMapLS( (SEGPTR)ptr ); + if (kept) { + alloc = (char*)msg16 - sizeof(void**); + p32 = *(void**)alloc; + p16 = msg16; + + if (map == 0) { + memcpy(p32, p16, size16); + } else { + while (map & 0xF) { + nibble = map & 0xF; + if (nibble & 0x8) { + memcpy(p32, p16, (nibble & 7) + 1); + p16 += (nibble & 7) + 1; + p32 += (nibble & 7) + 1; + size16 -= (nibble & 7) + 1; + } else { + switch (nibble) { + case 0x1: + *(LPINT)p32 = *(LPINT16)p16; + p16 += sizeof(INT16); + p32 += sizeof(INT); + size16 -= sizeof(INT16); + break; + case 0x2: + *(LPUINT)p32 = *(LPUINT16)p16; + p16 += sizeof(UINT16); + p32 += sizeof(UINT); + size16 -= sizeof(UINT16); + break; + case 0x6: + p16 += sizeof(UINT); + p32 += sizeof(UINT); + size16 -= sizeof(UINT); + break; + case 0x7: + UnMapLS( *(SEGPTR *)p16 ); + p16 += sizeof(SEGPTR); + p32 += sizeof(char*); + size16 -= sizeof(SEGPTR); + break; + default: + FIXME("Unknown nibble for mapping (%x)\n", nibble); + } + } + map >>= 4; + } + if (size16 != 0) /* DEBUG only */ + FIXME("Mismatch between 16 bit struct size and map nibbles serie\n"); + } + } else { + alloc = msg16; + } + + HeapFree( GetProcessHeap(), 0, alloc ); + } + return WINMM_MAP_OK; +} + +/************************************************************************** + * MCI_MapMsg32ATo16 [internal] + * + * Map a 32-A bit MCI message to a 16 bit MCI message. + */ +static WINMM_MapType MCI_MapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD* lParam) +{ + int size; + BOOLEAN keep = FALSE; + DWORD map = 0; + + if (*lParam == 0) + return WINMM_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_BREAK: + size = sizeof(MCI_BREAK_PARMS); + break; + /* case MCI_CAPTURE */ + case MCI_CLOSE: + case MCI_CLOSE_DRIVER: + case MCI_CONFIGURE: + size = sizeof(MCI_GENERIC_PARMS); + break; + /* case MCI_COPY: */ + case MCI_CUE: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_CUE_PARMS); break; + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_CUE_PARMS); break;*/ FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + /* case MCI_CUT:*/ + case MCI_DELETE: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_DELETE_PARMS16); map = 0x0F1111FB; break; + case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_DELETE_PARMS); break; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + /* case MCI_ESCAPE: */ + case MCI_FREEZE: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_FREEZE_PARMS); map = 0x0001111B; break; + case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + case MCI_GETDEVCAPS: + keep = TRUE; + size = sizeof(MCI_GETDEVCAPS_PARMS); + break; + /* case MCI_INDEX: */ + case MCI_INFO: + { + LPMCI_INFO_PARMSA mip32a = (LPMCI_INFO_PARMSA)(*lParam); + LPMCI_INFO_PARMS16 mip16; + + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_INFO_PARMS16); break; + default: size = sizeof(MCI_INFO_PARMS16); break; + } + mip16 = HeapAlloc( GetProcessHeap(), 0, size); + if (mip16) + { + mip16->dwCallback = mip32a->dwCallback; + mip16->lpstrReturn = MapLS( mip32a->lpstrReturn ); + mip16->dwRetSize = mip32a->dwRetSize; + if (uDevType == MCI_DEVTYPE_DIGITAL_VIDEO) { + ((LPMCI_DGV_INFO_PARMS16)mip16)->dwItem = ((LPMCI_DGV_INFO_PARMSA)mip32a)->dwItem; + } + } else { + return WINMM_MAP_NOMEM; + } + *lParam = MapLS(mip16); + } + return WINMM_MAP_OKMEM; + /* case MCI_MARK: */ + /* case MCI_MONITOR: */ + case MCI_OPEN: + case MCI_OPEN_DRIVER: + { + LPMCI_OPEN_PARMSA mop32a = (LPMCI_OPEN_PARMSA)(*lParam); + char* ptr = HeapAlloc( GetProcessHeap(), 0, + sizeof(LPMCI_OPEN_PARMSA) + sizeof(MCI_OPEN_PARMS16) + 2 * sizeof(DWORD)); + LPMCI_OPEN_PARMS16 mop16; + + + if (ptr) { + *(LPMCI_OPEN_PARMSA*)(ptr) = mop32a; + mop16 = (LPMCI_OPEN_PARMS16)(ptr + sizeof(LPMCI_OPEN_PARMSA)); + mop16->dwCallback = mop32a->dwCallback; + mop16->wDeviceID = mop32a->wDeviceID; + if (dwFlags & MCI_OPEN_TYPE) { + if (dwFlags & MCI_OPEN_TYPE_ID) { + /* dword "transparent" value */ + mop16->lpstrDeviceType = (SEGPTR)mop32a->lpstrDeviceType; + } else { + /* string */ + mop16->lpstrDeviceType = MapLS( mop32a->lpstrDeviceType ); + } + } else { + /* nuthin' */ + mop16->lpstrDeviceType = 0; + } + if (dwFlags & MCI_OPEN_ELEMENT) { + if (dwFlags & MCI_OPEN_ELEMENT_ID) { + mop16->lpstrElementName = (SEGPTR)mop32a->lpstrElementName; + } else { + mop16->lpstrElementName = MapLS( mop32a->lpstrElementName ); + } + } else { + mop16->lpstrElementName = 0; + } + if (dwFlags & MCI_OPEN_ALIAS) { + mop16->lpstrAlias = MapLS( mop32a->lpstrAlias ); + } else { + mop16->lpstrAlias = 0; + } + /* 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. + */ + memcpy(mop16 + 1, mop32a + 1, 2 * sizeof(DWORD)); + } else { + return WINMM_MAP_NOMEM; + } + *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_PARMSA); + } + return WINMM_MAP_OKMEM; + /* case MCI_PASTE:*/ + case MCI_PAUSE: + size = sizeof(MCI_GENERIC_PARMS); + break; + case MCI_PLAY: + size = sizeof(MCI_PLAY_PARMS); + break; + case MCI_PUT: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break; + case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); map = 0x0001111B; break; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + case MCI_REALIZE: + size = sizeof(MCI_GENERIC_PARMS); + break; + case MCI_RECORD: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECORD_PARMS16); map = 0x0F1111FB; break; + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_RECORD_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + default: size = sizeof(MCI_RECORD_PARMS); break; + } + break; + case MCI_RESUME: + size = sizeof(MCI_GENERIC_PARMS); + break; + case MCI_SEEK: + switch (uDevType) { + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SEEK_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + default: size = sizeof(MCI_SEEK_PARMS); break; + } + break; + case MCI_SET: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SET_PARMS); break; + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SET_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + case MCI_DEVTYPE_SEQUENCER: size = sizeof(MCI_SEQ_SET_PARMS); break; + /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned, + * so not doing anything should work... + */ + case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_SET_PARMS); break; + default: size = sizeof(MCI_SET_PARMS); break; + } + break; + case MCI_SETAUDIO: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SETAUDIO_PARMS16);map = 0x0000077FF; break; + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + /* case MCI_SETTIMECODE:*/ + /* case MCI_SIGNAL:*/ + case MCI_SPIN: + size = sizeof(MCI_SET_PARMS); + break; + case MCI_STATUS: + keep = TRUE; + switch (uDevType) { + /* FIXME: + * don't know if buffer for value is the one passed through lpstrDevice + * or is provided by MCI driver. + * Assuming solution 2: provided by MCI driver, so zeroing on entry + */ + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16); map = 0x0B6FF; break; + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + default: size = sizeof(MCI_STATUS_PARMS); break; + } + break; + case MCI_STEP: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STEP_PARMS); break; + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STEP_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + case MCI_DEVTYPE_VIDEODISC: size = sizeof(MCI_VD_STEP_PARMS); break; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + case MCI_STOP: + size = sizeof(MCI_SET_PARMS); + break; + case MCI_SYSINFO: + { + LPMCI_SYSINFO_PARMSA msip32a = (LPMCI_SYSINFO_PARMSA)(*lParam); + LPMCI_SYSINFO_PARMS16 msip16; + char* ptr = HeapAlloc( GetProcessHeap(), 0, + sizeof(LPMCI_SYSINFO_PARMSA) + sizeof(MCI_SYSINFO_PARMS16) ); + + if (ptr) { + *(LPMCI_SYSINFO_PARMSA*)(ptr) = msip32a; + msip16 = (LPMCI_SYSINFO_PARMS16)(ptr + sizeof(LPMCI_SYSINFO_PARMSA)); + + msip16->dwCallback = msip32a->dwCallback; + msip16->lpstrReturn = MapLS( msip32a->lpstrReturn ); + msip16->dwRetSize = msip32a->dwRetSize; + msip16->dwNumber = msip32a->dwNumber; + msip16->wDeviceType = msip32a->wDeviceType; + } else { + return WINMM_MAP_NOMEM; + } + *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_SYSINFO_PARMSA); + } + return WINMM_MAP_OKMEM; + /* case MCI_UNDO: */ + case MCI_UNFREEZE: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; break; + case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; break; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + case MCI_UPDATE: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_UPDATE_PARMS16); map = 0x000B1111B; break; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + case MCI_WHERE: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break; + case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; keep = TRUE; break; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + case MCI_WINDOW: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7FB; break; + case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7FB; break; + default: size = sizeof(MCI_GENERIC_PARMS); break; + } + break; + case DRV_OPEN: + { + LPMCI_OPEN_DRIVER_PARMSA modp32a = (LPMCI_OPEN_DRIVER_PARMSA)(*lParam); + LPMCI_OPEN_DRIVER_PARMS16 modp16; + char *ptr = HeapAlloc( GetProcessHeap(), 0, + sizeof(LPMCI_OPEN_DRIVER_PARMSA) + sizeof(MCI_OPEN_DRIVER_PARMS16)); + + if (ptr) { + *(LPMCI_OPEN_DRIVER_PARMSA*)(ptr) = modp32a; + modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSA)); + modp16->wDeviceID = modp32a->wDeviceID; + modp16->lpstrParams = MapLS( modp32a->lpstrParams ); + /* other fields are gonna be filled by the driver, don't copy them */ + } else { + return WINMM_MAP_NOMEM; + } + *lParam = (LPARAM)MapLS(ptr) + sizeof(LPMCI_OPEN_DRIVER_PARMSA); + } + return WINMM_MAP_OKMEM; + case DRV_LOAD: + case DRV_ENABLE: + 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: + return WINMM_MAP_OK; + + default: + WARN("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg)); + return WINMM_MAP_MSGERROR; + } + return MCI_MsgMapper32To16_Create((void**)lParam, size, map, keep); +} + +/************************************************************************** + * MCI_UnMapMsg32ATo16 [internal] + */ +static WINMM_MapType MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD lParam) +{ + int size = 0; + BOOLEAN kept = FALSE; /* there is no need to compute size when kept is FALSE */ + DWORD map = 0; + + switch (wMsg) { + case MCI_BREAK: + break; + /* case MCI_CAPTURE */ + case MCI_CLOSE: + case MCI_CLOSE_DRIVER: + case MCI_CONFIGURE: + break; + /* case MCI_COPY: */ + case MCI_CUE: + break; + /* case MCI_CUT: */ + case MCI_DELETE: + break; + /* case MCI_ESCAPE: */ + case MCI_FREEZE: + break; + case MCI_GETDEVCAPS: + kept = TRUE; + size = sizeof(MCI_GETDEVCAPS_PARMS); + break; + /* case MCI_INDEX: */ + case MCI_INFO: + { + LPMCI_INFO_PARMS16 mip16 = (LPMCI_INFO_PARMS16)MapSL(lParam); + UnMapLS( lParam ); + UnMapLS( mip16->lpstrReturn ); + HeapFree( GetProcessHeap(), 0, mip16 ); + } + return WINMM_MAP_OK; + /* case MCI_MARK: */ + /* case MCI_MONITOR: */ + case MCI_OPEN: + case MCI_OPEN_DRIVER: + if (lParam) { + LPMCI_OPEN_PARMS16 mop16 = (LPMCI_OPEN_PARMS16)MapSL(lParam); + LPMCI_OPEN_PARMSA mop32a = *(LPMCI_OPEN_PARMSA*)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSA)); + UnMapLS( lParam ); + mop32a->wDeviceID = mop16->wDeviceID; + if ((dwFlags & MCI_OPEN_TYPE) && !(dwFlags & MCI_OPEN_TYPE_ID)) + UnMapLS( mop16->lpstrDeviceType ); + if ((dwFlags & MCI_OPEN_ELEMENT) && !(dwFlags & MCI_OPEN_ELEMENT_ID)) + UnMapLS( mop16->lpstrElementName ); + if (dwFlags & MCI_OPEN_ALIAS) + UnMapLS( mop16->lpstrAlias ); + HeapFree( GetProcessHeap(), 0, (char*)mop16 - sizeof(LPMCI_OPEN_PARMSA) ); + } + return WINMM_MAP_OK; + /* case MCI_PASTE:*/ + case MCI_PAUSE: + break; + case MCI_PLAY: + break; + case MCI_PUT: + break; + case MCI_REALIZE: + break; + case MCI_RECORD: + break; + case MCI_RESUME: + break; + case MCI_SEEK: + break; + case MCI_SET: + break; + case MCI_SETAUDIO: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: map = 0x0000077FF; break; + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SETAUDIO_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + } + break; + /* case MCI_SETTIMECODE:*/ + /* case MCI_SIGNAL:*/ + case MCI_SPIN: + break; + case MCI_STATUS: + kept = TRUE; + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: + if (lParam) { + LPMCI_DGV_STATUS_PARMS16 mdsp16 = (LPMCI_DGV_STATUS_PARMS16)MapSL(lParam); + LPMCI_DGV_STATUS_PARMSA mdsp32a = *(LPMCI_DGV_STATUS_PARMSA*)((char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA)); + + UnMapLS( lParam ); + if (mdsp16) { + mdsp32a->dwReturn = mdsp16->dwReturn; + if (dwFlags & MCI_DGV_STATUS_DISKSPACE) { + TRACE("MCI_STATUS (DGV) lpstrDrive=%08lx\n", mdsp16->lpstrDrive); + TRACE("MCI_STATUS (DGV) lpstrDrive=%s\n", (LPSTR)MapSL(mdsp16->lpstrDrive)); + UnMapLS( mdsp16->lpstrDrive ); + } + HeapFree( GetProcessHeap(), 0, (char*)mdsp16 - sizeof(LPMCI_DGV_STATUS_PARMSA) ); + } else { + return WINMM_MAP_NOMEM; + } + } + return WINMM_MAP_OKMEM; + case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME("NIY vcr\n"); return WINMM_MAP_NOMEM; + default: size = sizeof(MCI_STATUS_PARMS); break; + } + break; + case MCI_STEP: + break; + case MCI_STOP: + break; + case MCI_SYSINFO: + if (lParam) { + LPMCI_SYSINFO_PARMS16 msip16 = (LPMCI_SYSINFO_PARMS16)MapSL(lParam); + LPMCI_SYSINFO_PARMSA msip32a = *(LPMCI_SYSINFO_PARMSA*)((char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA)); + + UnMapLS( lParam ); + if (msip16) { + msip16->dwCallback = msip32a->dwCallback; + UnMapLS( msip16->lpstrReturn ); + HeapFree( GetProcessHeap(), 0, (char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA) ); + } else { + return WINMM_MAP_NOMEM; + } + } + return WINMM_MAP_OKMEM; + /* case MCI_UNDO: */ + case MCI_UNFREEZE: + break; + case MCI_UPDATE: + break; + case MCI_WHERE: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break; + case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS16); map = 0x0001111B; kept = TRUE; break; + default: break; + } + break; + case MCI_WINDOW: + switch (uDevType) { + case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); if (dwFlags & MCI_DGV_WINDOW_TEXT) map = 0x7666; break; + case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_WINDOW_PARMS16); if (dwFlags & MCI_OVLY_WINDOW_TEXT) map = 0x7666; break; + default: break; + } + /* FIXME: see map function */ + break; + + case DRV_OPEN: + if (lParam) { + LPMCI_OPEN_DRIVER_PARMS16 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)MapSL(lParam); + LPMCI_OPEN_DRIVER_PARMSA modp32a = *(LPMCI_OPEN_DRIVER_PARMSA*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA)); + + UnMapLS( lParam ); + modp32a->wCustomCommandTable = modp16->wCustomCommandTable; + modp32a->wType = modp16->wType; + UnMapLS( modp16->lpstrParams ); + HeapFree( GetProcessHeap(), 0, (char *)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA) ); + } + return WINMM_MAP_OK; + case DRV_LOAD: + case DRV_ENABLE: + 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 WINMM_MAP_OK; + default: + FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg)); + return WINMM_MAP_MSGERROR; + } + return MCI_MsgMapper32To16_Destroy((void*)lParam, size, map, kept); +} + +void MMDRV_Init16(void) +{ +#define A(_x,_y) MMDRV_InstallMap(_x, \ +MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \ +MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \ +MMDRV_##_y##_Callback) + A(MMDRV_AUX, Aux); + A(MMDRV_MIXER, Mixer); + A(MMDRV_MIDIIN, MidiIn); + A(MMDRV_MIDIOUT, MidiOut); + A(MMDRV_WAVEIN, WaveIn); + A(MMDRV_WAVEOUT, WaveOut); +#undef A + + pFnCallMMDrvFunc16 = MMDRV_CallMMDrvFunc16; + pFnLoadMMDrvFunc16 = MMDRV_LoadMMDrvFunc16; + + pFnMciMapMsg16To32A = MCI_MapMsg16To32A; + pFnMciUnMapMsg16To32A = MCI_UnMapMsg16To32A; + pFnMciMapMsg32ATo16 = MCI_MapMsg32ATo16; + pFnMciUnMapMsg32ATo16 = MCI_UnMapMsg32ATo16; +} diff --git a/reactos/lib/winmm/mmsystem.c b/reactos/lib/winmm/mmsystem.c new file mode 100644 index 00000000000..bef26db50d7 --- /dev/null +++ b/reactos/lib/winmm/mmsystem.c @@ -0,0 +1,3175 @@ +/* -*- tab-width: 8; c-basic-offset: 4 -*- */ + +/* + * MMSYTEM functions + * + * Copyright 1993 Martin Ayotte + * 1998-2003 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Eric POUECH : + * 99/4 added mmTask and mmThread functions support + */ + +#include +#include + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "windef.h" +#include "winbase.h" +#include "mmsystem.h" +#include "winreg.h" +#include "ntstatus.h" +#include "winternl.h" +#include "wownt32.h" +#include "winnls.h" + +#include "wine/winuser16.h" +#include "winemm16.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mmsys); + +static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16); +static LPWINE_DRIVER DRIVER_OpenDriver16(LPCSTR, LPCSTR, LPARAM); +static LRESULT DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM); +static LRESULT DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM); +static LRESULT MMIO_Callback16(SEGPTR, LPMMIOINFO, UINT, LPARAM, LPARAM); + +/* ################################################### + * # LIBRARY # + * ################################################### + */ + +/************************************************************************** + * DllEntryPoint (MMSYSTEM.2046) + * + * MMSYSTEM DLL entry point + * + */ +BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds, + WORD wHeapSize, DWORD dwReserved1, WORD wReserved2) +{ + TRACE("%p 0x%lx\n", hinstDLL, fdwReason); + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + /* need to load WinMM in order to: + * - initiate correctly shared variables (WINMM_Init()) + */ + if (!GetModuleHandleA("WINMM.DLL") && !LoadLibraryA("WINMM.DLL")) + { + ERR("Could not load sibling WinMM.dll\n"); + return FALSE; + } + WINMM_IData->hWinMM16Instance = hinstDLL; + /* hook in our 16 bit function pointers */ + pFnGetMMThread16 = WINMM_GetmmThread; + pFnOpenDriver16 = DRIVER_OpenDriver16; + pFnCloseDriver16 = DRIVER_CloseDriver16; + pFnSendMessage16 = DRIVER_SendMessage16; + pFnMmioCallback16 = MMIO_Callback16; + pFnReleaseThunkLock = ReleaseThunkLock; + pFnRestoreThunkLock = RestoreThunkLock; + MMDRV_Init16(); + break; + case DLL_PROCESS_DETACH: + WINMM_IData->hWinMM16Instance = 0; + pFnGetMMThread16 = NULL; + pFnOpenDriver16 = NULL; + pFnCloseDriver16 = NULL; + pFnSendMessage16 = NULL; + pFnMmioCallback16 = NULL; + pFnReleaseThunkLock = NULL; + pFnRestoreThunkLock = NULL; + /* FIXME: add equivalent for MMDRV_Init16() */ + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + } + return TRUE; +} + +/************************************************************************** + * MMSYSTEM_WEP [MMSYSTEM.1] + */ +int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg, + WORD cbHeapSize, LPSTR lpCmdLine) +{ + FIXME("STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance); + return TRUE; +} + +/* ################################################### + * # PlaySound # + * ################################################### + */ + +/************************************************************************** + * PlaySound [MMSYSTEM.3] + */ +BOOL16 WINAPI PlaySound16(LPCSTR pszSound, HMODULE16 hmod, DWORD fdwSound) +{ + BOOL16 retv; + DWORD lc; + + if ((fdwSound & SND_RESOURCE) == SND_RESOURCE) + { + HGLOBAL16 handle; + HRSRC16 res; + + if (!(res = FindResource16( hmod, pszSound, "WAVE" ))) return FALSE; + if (!(handle = LoadResource16( hmod, res ))) return FALSE; + pszSound = LockResource16(handle); + fdwSound = (fdwSound & ~SND_RESOURCE) | SND_MEMORY; + /* FIXME: FreeResource16 */ + } + + ReleaseThunkLock(&lc); + retv = PlaySoundA(pszSound, 0, fdwSound); + RestoreThunkLock(lc); + + return retv; +} + +/************************************************************************** + * sndPlaySound [MMSYSTEM.2] + */ +BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags) +{ + BOOL16 retv; + DWORD lc; + + ReleaseThunkLock(&lc); + retv = sndPlaySoundA(lpszSoundName, uFlags); + RestoreThunkLock(lc); + + return retv; +} + +/* ################################################### + * # MISC # + * ################################################### + */ + +/************************************************************************** + * mmsystemGetVersion [MMSYSTEM.5] + * + */ +UINT16 WINAPI mmsystemGetVersion16(void) +{ + return mmsystemGetVersion(); +} + +/************************************************************************** + * DriverCallback [MMSYSTEM.31] + */ +BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev, + WORD wMsg, DWORD dwUser, DWORD dwParam1, + DWORD dwParam2) +{ + return DriverCallback(dwCallBack, uFlags, HDRVR_32(hDev), wMsg, dwUser, dwParam1, dwParam2); +} + +/************************************************************************** + * OutputDebugStr [MMSYSTEM.30] + */ +void WINAPI OutputDebugStr16(LPCSTR str) +{ + OutputDebugStringA( str ); +} + + +/* ################################################### + * # MIXER # + * ################################################### + */ + +/************************************************************************** + * Mixer devices. New to Win95 + */ + +/************************************************************************** + * mixerGetNumDevs [MMSYSTEM.800] + */ +UINT16 WINAPI mixerGetNumDevs16(void) +{ + return MMDRV_GetNum(MMDRV_MIXER); +} + +/************************************************************************** + * mixerGetDevCaps [MMSYSTEM.801] + */ +UINT16 WINAPI mixerGetDevCaps16(UINT16 uDeviceID, LPMIXERCAPS16 lpCaps, + UINT16 uSize) +{ + MIXERCAPSA micA; + UINT ret; + + if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + + ret = mixerGetDevCapsA(uDeviceID, &micA, sizeof(micA)); + if (ret == MMSYSERR_NOERROR) { + MIXERCAPS16 mic16; + mic16.wMid = micA.wMid; + mic16.wPid = micA.wPid; + mic16.vDriverVersion = micA.vDriverVersion; + strcpy(mic16.szPname, micA.szPname); + mic16.fdwSupport = micA.fdwSupport; + mic16.cDestinations = micA.cDestinations; + memcpy(lpCaps, &mic16, min(uSize, sizeof(mic16))); + } + return ret; +} + +/************************************************************************** + * mixerOpen [MMSYSTEM.802] + */ +UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix, UINT16 uDeviceID, DWORD dwCallback, + DWORD dwInstance, DWORD fdwOpen) +{ + HMIXER hmix; + UINT ret; + + ret = MIXER_Open(&hmix, uDeviceID, dwCallback, dwInstance, fdwOpen, FALSE); + if (lphmix) *lphmix = HMIXER_16(hmix); + return ret; +} + +/************************************************************************** + * mixerClose [MMSYSTEM.803] + */ +UINT16 WINAPI mixerClose16(HMIXER16 hMix) +{ + return mixerClose(HMIXER_32(hMix)); +} + +/************************************************************************** + * mixerGetID (MMSYSTEM.806) + */ +UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID) +{ + UINT xid; + UINT ret = mixerGetID(HMIXEROBJ_32(hmix), &xid, fdwID); + + if (lpid) + *lpid = xid; + return ret; +} + +/************************************************************************** + * mixerGetControlDetails [MMSYSTEM.808] + */ +UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix, + LPMIXERCONTROLDETAILS16 lpmcd, + DWORD fdwDetails) +{ + DWORD ret = MMSYSERR_NOTENABLED; + SEGPTR sppaDetails; + + TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails); + + if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd)) + return MMSYSERR_INVALPARAM; + + sppaDetails = (SEGPTR)lpmcd->paDetails; + lpmcd->paDetails = MapSL(sppaDetails); + ret = mixerGetControlDetailsA(HMIXEROBJ_32(hmix), + (LPMIXERCONTROLDETAILS)lpmcd, fdwDetails); + lpmcd->paDetails = (LPVOID)sppaDetails; + + return ret; +} + +/************************************************************************** + * mixerGetLineControls [MMSYSTEM.807] + */ +UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix, + LPMIXERLINECONTROLS16 lpmlc16, + DWORD fdwControls) +{ + MIXERLINECONTROLSA mlcA; + DWORD ret; + int i; + LPMIXERCONTROL16 lpmc16; + + TRACE("(%04x, %p, %08lx)\n", hmix, lpmlc16, fdwControls); + + if (lpmlc16 == NULL || lpmlc16->cbStruct != sizeof(*lpmlc16) || + lpmlc16->cbmxctrl != sizeof(MIXERCONTROL16)) + return MMSYSERR_INVALPARAM; + + mlcA.cbStruct = sizeof(mlcA); + mlcA.dwLineID = lpmlc16->dwLineID; + mlcA.u.dwControlID = lpmlc16->u.dwControlID; + mlcA.u.dwControlType = lpmlc16->u.dwControlType; + mlcA.cControls = lpmlc16->cControls; + mlcA.cbmxctrl = sizeof(MIXERCONTROLA); + mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0, + mlcA.cControls * mlcA.cbmxctrl); + + ret = mixerGetLineControlsA(HMIXEROBJ_32(hmix), &mlcA, fdwControls); + + if (ret == MMSYSERR_NOERROR) { + lpmlc16->dwLineID = mlcA.dwLineID; + lpmlc16->u.dwControlID = mlcA.u.dwControlID; + lpmlc16->u.dwControlType = mlcA.u.dwControlType; + lpmlc16->cControls = mlcA.cControls; + + lpmc16 = MapSL(lpmlc16->pamxctrl); + + for (i = 0; i < mlcA.cControls; i++) { + lpmc16[i].cbStruct = sizeof(MIXERCONTROL16); + lpmc16[i].dwControlID = mlcA.pamxctrl[i].dwControlID; + lpmc16[i].dwControlType = mlcA.pamxctrl[i].dwControlType; + lpmc16[i].fdwControl = mlcA.pamxctrl[i].fdwControl; + lpmc16[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems; + strcpy(lpmc16[i].szShortName, mlcA.pamxctrl[i].szShortName); + strcpy(lpmc16[i].szName, mlcA.pamxctrl[i].szName); + /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */ + memcpy(&lpmc16[i].Bounds, &mlcA.pamxctrl[i].Bounds, + sizeof(mlcA.pamxctrl[i].Bounds)); + /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */ + memcpy(&lpmc16[i].Metrics, &mlcA.pamxctrl[i].Metrics, + sizeof(mlcA.pamxctrl[i].Metrics)); + } + } + + HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl); + + return ret; +} + +/************************************************************************** + * mixerGetLineInfo [MMSYSTEM.805] + */ +UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16, + DWORD fdwInfo) +{ + MIXERLINEA mliA; + UINT ret; + + TRACE("(%04x, %p, %08lx)\n", hmix, lpmli16, fdwInfo); + + if (lpmli16 == NULL || lpmli16->cbStruct != sizeof(*lpmli16)) + return MMSYSERR_INVALPARAM; + + mliA.cbStruct = sizeof(mliA); + switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) { + case MIXER_GETLINEINFOF_COMPONENTTYPE: + mliA.dwComponentType = lpmli16->dwComponentType; + break; + case MIXER_GETLINEINFOF_DESTINATION: + mliA.dwDestination = lpmli16->dwDestination; + break; + case MIXER_GETLINEINFOF_LINEID: + mliA.dwLineID = lpmli16->dwLineID; + break; + case MIXER_GETLINEINFOF_SOURCE: + mliA.dwDestination = lpmli16->dwDestination; + mliA.dwSource = lpmli16->dwSource; + break; + case MIXER_GETLINEINFOF_TARGETTYPE: + mliA.Target.dwType = lpmli16->Target.dwType; + mliA.Target.wMid = lpmli16->Target.wMid; + mliA.Target.wPid = lpmli16->Target.wPid; + mliA.Target.vDriverVersion = lpmli16->Target.vDriverVersion; + strcpy(mliA.Target.szPname, lpmli16->Target.szPname); + break; + default: + FIXME("Unsupported fdwControls=0x%08lx\n", fdwInfo); + } + + ret = mixerGetLineInfoA(HMIXEROBJ_32(hmix), &mliA, fdwInfo); + + lpmli16->dwDestination = mliA.dwDestination; + lpmli16->dwSource = mliA.dwSource; + lpmli16->dwLineID = mliA.dwLineID; + lpmli16->fdwLine = mliA.fdwLine; + lpmli16->dwUser = mliA.dwUser; + lpmli16->dwComponentType = mliA.dwComponentType; + lpmli16->cChannels = mliA.cChannels; + lpmli16->cConnections = mliA.cConnections; + lpmli16->cControls = mliA.cControls; + strcpy(lpmli16->szShortName, mliA.szShortName); + strcpy(lpmli16->szName, mliA.szName); + lpmli16->Target.dwType = mliA.Target.dwType; + lpmli16->Target.dwDeviceID = mliA.Target.dwDeviceID; + lpmli16->Target.wMid = mliA.Target.wMid; + lpmli16->Target.wPid = mliA.Target.wPid; + lpmli16->Target.vDriverVersion = mliA.Target.vDriverVersion; + strcpy(lpmli16->Target.szPname, mliA.Target.szPname); + + return ret; +} + +/************************************************************************** + * mixerSetControlDetails [MMSYSTEM.809] + */ +UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix, + LPMIXERCONTROLDETAILS16 lpmcd, + DWORD fdwDetails) +{ + TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails); + return MMSYSERR_NOTENABLED; +} + +/************************************************************************** + * mixerMessage [MMSYSTEM.804] + */ +DWORD WINAPI mixerMessage16(HMIXER16 hmix, UINT16 uMsg, DWORD dwParam1, + DWORD dwParam2) +{ + return mixerMessage(HMIXER_32(hmix), uMsg, dwParam1, dwParam2); +} + +/************************************************************************** + * auxGetNumDevs [MMSYSTEM.350] + */ +UINT16 WINAPI auxGetNumDevs16(void) +{ + return MMDRV_GetNum(MMDRV_AUX); +} + +/* ################################################### + * # AUX # + * ################################################### + */ + +/************************************************************************** + * auxGetDevCaps [MMSYSTEM.351] + */ +UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID, LPAUXCAPS16 lpCaps, UINT16 uSize) +{ + AUXCAPSA acA; + UINT ret; + + if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + + ret = auxGetDevCapsA(uDeviceID, &acA, sizeof(acA)); + if (ret == MMSYSERR_NOERROR) { + AUXCAPS16 ac16; + ac16.wMid = acA.wMid; + ac16.wPid = acA.wPid; + ac16.vDriverVersion = acA.vDriverVersion; + strcpy(ac16.szPname, acA.szPname); + ac16.wTechnology = acA.wTechnology; + ac16.dwSupport = acA.dwSupport; + memcpy(lpCaps, &ac16, min(uSize, sizeof(ac16))); + } + return ret; +} + +/************************************************************************** + * auxGetVolume [MMSYSTEM.352] + */ +UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, LPDWORD lpdwVolume) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume); + + if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL) + return MMSYSERR_INVALHANDLE; + return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L, TRUE); +} + +/************************************************************************** + * auxSetVolume [MMSYSTEM.353] + */ +UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %lu) !\n", uDeviceID, dwVolume); + + if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL) + return MMSYSERR_INVALHANDLE; + return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE); +} + +/************************************************************************** + * auxOutMessage [MMSYSTEM.354] + */ +DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %04X, %08lX, %08lX)\n", uDeviceID, uMessage, dw1, dw2); + + switch (uMessage) { + case AUXDM_GETNUMDEVS: + case AUXDM_SETVOLUME: + /* no argument conversion needed */ + break; + case AUXDM_GETVOLUME: + return auxGetVolume16(uDeviceID, MapSL(dw1)); + case AUXDM_GETDEVCAPS: + return auxGetDevCaps16(uDeviceID, MapSL(dw1), dw2); + default: + TRACE("(%04x, %04x, %08lx, %08lx): unhandled message\n", + uDeviceID, uMessage, dw1, dw2); + break; + } + if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE); +} + +/* ################################################### + * # MCI # + * ################################################### + */ + +/************************************************************************** + * mciGetErrorString [MMSYSTEM.706] + */ +BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer, UINT16 uLength) +{ + return mciGetErrorStringA(wError, lpstrBuffer, uLength); +} + +/************************************************************************** + * mciDriverNotify [MMSYSTEM.711] + */ +BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus) +{ + TRACE("(%04X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus); + + return PostMessageA(HWND_32(hWndCallBack), MM_MCINOTIFY, wStatus, wDevID); +} + +/************************************************************************** + * mciGetDriverData [MMSYSTEM.708] + */ +DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID) +{ + return mciGetDriverData(uDeviceID); +} + +/************************************************************************** + * mciSetDriverData [MMSYSTEM.707] + */ +BOOL16 WINAPI mciSetDriverData16(UINT16 uDeviceID, DWORD data) +{ + return mciSetDriverData(uDeviceID, data); +} + +/************************************************************************** + * mciSendCommand [MMSYSTEM.701] + */ +DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2) +{ + DWORD dwRet; + + TRACE("(%04X, %s, %08lX, %08lX)\n", + wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2); + + dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, FALSE); + dwRet = MCI_CleanUp(dwRet, wMsg, (DWORD)MapSL(dwParam2)); + TRACE("=> %ld\n", dwRet); + return dwRet; +} + +/************************************************************************** + * mciGetDeviceID [MMSYSTEM.703] + */ +UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName) +{ + TRACE("(\"%s\")\n", lpstrName); + + return MCI_GetDriverFromString(lpstrName); +} + +/************************************************************************** + * mciSetYieldProc [MMSYSTEM.714] + */ +BOOL16 WINAPI mciSetYieldProc16(UINT16 uDeviceID, YIELDPROC16 fpYieldProc, DWORD dwYieldData) +{ + LPWINE_MCIDRIVER wmd; + + TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData); + + if (!(wmd = MCI_GetDriver(uDeviceID))) { + WARN("Bad uDeviceID\n"); + return FALSE; + } + + wmd->lpfnYieldProc = (YIELDPROC)fpYieldProc; + wmd->dwYieldData = dwYieldData; + wmd->bIs32 = FALSE; + + return TRUE; +} + +/************************************************************************** + * mciGetDeviceIDFromElementID [MMSYSTEM.715] + */ +UINT16 WINAPI mciGetDeviceIDFromElementID16(DWORD dwElementID, LPCSTR lpstrType) +{ + FIXME("(%lu, %s) stub\n", dwElementID, lpstrType); + return 0; +} + +/************************************************************************** + * mciGetYieldProc [MMSYSTEM.716] + */ +YIELDPROC16 WINAPI mciGetYieldProc16(UINT16 uDeviceID, DWORD* lpdwYieldData) +{ + LPWINE_MCIDRIVER wmd; + + TRACE("(%u, %p)\n", uDeviceID, lpdwYieldData); + + if (!(wmd = MCI_GetDriver(uDeviceID))) { + WARN("Bad uDeviceID\n"); + return NULL; + } + if (!wmd->lpfnYieldProc) { + WARN("No proc set\n"); + return NULL; + } + if (wmd->bIs32) { + WARN("Proc is 32 bit\n"); + return NULL; + } + return (YIELDPROC16)wmd->lpfnYieldProc; +} + +/************************************************************************** + * mciGetCreatorTask [MMSYSTEM.717] + */ +HTASK16 WINAPI mciGetCreatorTask16(UINT16 uDeviceID) +{ + LPWINE_MCIDRIVER wmd; + HTASK16 ret = 0; + + if ((wmd = MCI_GetDriver(uDeviceID))) + ret = HTASK_16(wmd->CreatorThread); + + TRACE("(%u) => %04x\n", uDeviceID, ret); + return ret; +} + +/************************************************************************** + * mciDriverYield [MMSYSTEM.710] + */ +UINT16 WINAPI mciDriverYield16(UINT16 uDeviceID) +{ + LPWINE_MCIDRIVER wmd; + UINT16 ret = 0; + + /* TRACE("(%04x)\n", uDeviceID); */ + + if (!(wmd = MCI_GetDriver(uDeviceID)) || !wmd->lpfnYieldProc || wmd->bIs32) { + UserYield16(); + } else { + ret = wmd->lpfnYieldProc(uDeviceID, wmd->dwYieldData); + } + + return ret; +} + +/* ################################################### + * # MIDI # + * ################################################### + */ + +/************************************************************************** + * midiOutGetNumDevs [MMSYSTEM.201] + */ +UINT16 WINAPI midiOutGetNumDevs16(void) +{ + return MMDRV_GetNum(MMDRV_MIDIOUT); +} + +/************************************************************************** + * midiOutGetDevCaps [MMSYSTEM.202] + */ +UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID, LPMIDIOUTCAPS16 lpCaps, + UINT16 uSize) +{ + MIDIOUTCAPSA mocA; + UINT ret; + + if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + + ret = midiOutGetDevCapsA(uDeviceID, &mocA, sizeof(mocA)); + if (ret == MMSYSERR_NOERROR) { + MIDIOUTCAPS16 moc16; + moc16.wMid = mocA.wMid; + moc16.wPid = mocA.wPid; + moc16.vDriverVersion = mocA.vDriverVersion; + strcpy(moc16.szPname, mocA.szPname); + moc16.wTechnology = mocA.wTechnology; + moc16.wVoices = mocA.wVoices; + moc16.wNotes = mocA.wNotes; + moc16.wChannelMask = mocA.wChannelMask; + moc16.dwSupport = mocA.dwSupport; + memcpy(lpCaps, &moc16, min(uSize, sizeof(moc16))); + } + return ret; + } + +/************************************************************************** + * midiOutGetErrorText [MMSYSTEM.203] + */ +UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize) +{ + return midiOutGetErrorTextA(uError, lpText, uSize); +} + +/************************************************************************** + * midiOutOpen [MMSYSTEM.204] + */ +UINT16 WINAPI midiOutOpen16(HMIDIOUT16* lphMidiOut, UINT16 uDeviceID, + DWORD dwCallback, DWORD dwInstance, DWORD dwFlags) +{ + HMIDIOUT hmo; + UINT ret; + + ret = MIDI_OutOpen(&hmo, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE); + + if (lphMidiOut != NULL) *lphMidiOut = HMIDIOUT_16(hmo); + return ret; +} + +/************************************************************************** + * midiOutClose [MMSYSTEM.205] + */ +UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut) +{ + return midiOutClose(HMIDIOUT_32(hMidiOut)); +} + +/************************************************************************** + * midiOutPrepareHeader [MMSYSTEM.206] + */ +UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */ + SEGPTR lpsegMidiOutHdr, /* [???] */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize); + + if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, MODM_PREPARE, lpsegMidiOutHdr, uSize, FALSE); +} + +/************************************************************************** + * midiOutUnprepareHeader [MMSYSTEM.207] + */ +UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */ + SEGPTR lpsegMidiOutHdr, /* [???] */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + LPMIDIHDR16 lpMidiOutHdr = MapSL(lpsegMidiOutHdr); + + TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize); + + if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) { + return MMSYSERR_NOERROR; + } + + if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, MODM_UNPREPARE, lpsegMidiOutHdr, uSize, FALSE); +} + +/************************************************************************** + * midiOutShortMsg [MMSYSTEM.208] + */ +UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg) +{ + return midiOutShortMsg(HMIDIOUT_32(hMidiOut), dwMsg); +} + +/************************************************************************** + * midiOutLongMsg [MMSYSTEM.209] + */ +UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut, /* [in] */ + LPMIDIHDR16 lpsegMidiOutHdr, /* [???] NOTE: SEGPTR */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize); + + if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpsegMidiOutHdr, uSize, FALSE); +} + +/************************************************************************** + * midiOutReset [MMSYSTEM.210] + */ +UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut) +{ + return midiOutReset(HMIDIOUT_32(hMidiOut)); +} + +/************************************************************************** + * midiOutGetVolume [MMSYSTEM.211] + */ +UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD* lpdwVolume) +{ + return midiOutGetVolume(HMIDIOUT_32(uDeviceID), lpdwVolume); +} + +/************************************************************************** + * midiOutSetVolume [MMSYSTEM.212] + */ +UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume) +{ + return midiOutSetVolume(HMIDIOUT_32(uDeviceID), dwVolume); +} + +/************************************************************************** + * midiOutCachePatches [MMSYSTEM.213] + */ +UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank, + WORD* lpwPatchArray, UINT16 uFlags) +{ + return midiOutCachePatches(HMIDIOUT_32(hMidiOut), uBank, lpwPatchArray, + uFlags); +} + +/************************************************************************** + * midiOutCacheDrumPatches [MMSYSTEM.214] + */ +UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch, + WORD* lpwKeyArray, UINT16 uFlags) +{ + return midiOutCacheDrumPatches(HMIDIOUT_32(hMidiOut), uPatch, lpwKeyArray, uFlags); +} + +/************************************************************************** + * midiOutGetID [MMSYSTEM.215] + */ +UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16* lpuDeviceID) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p)\n", hMidiOut, lpuDeviceID); + + if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM; + if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + *lpuDeviceID = wmld->uDeviceID; + return MMSYSERR_NOERROR; +} + +/************************************************************************** + * midiOutMessage [MMSYSTEM.216] + */ +DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage, + DWORD dwParam1, DWORD dwParam2) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiOut, uMessage, dwParam1, dwParam2); + + if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + switch (uMessage) { + case MODM_OPEN: + case MODM_CLOSE: + FIXME("can't handle OPEN or CLOSE message!\n"); + return MMSYSERR_NOTSUPPORTED; + + case MODM_GETVOLUME: + return midiOutGetVolume16(hMidiOut, MapSL(dwParam1)); + case MODM_LONGDATA: + return midiOutLongMsg16(hMidiOut, MapSL(dwParam1), dwParam2); + case MODM_PREPARE: + /* lpMidiOutHdr is still a segmented pointer for this function */ + return midiOutPrepareHeader16(hMidiOut, dwParam1, dwParam2); + case MODM_UNPREPARE: + return midiOutUnprepareHeader16(hMidiOut, dwParam1, dwParam2); + } + return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE); +} + +/************************************************************************** + * midiInGetNumDevs [MMSYSTEM.301] + */ +UINT16 WINAPI midiInGetNumDevs16(void) +{ + return MMDRV_GetNum(MMDRV_MIDIIN); +} + +/************************************************************************** + * midiInGetDevCaps [MMSYSTEM.302] + */ +UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID, LPMIDIINCAPS16 lpCaps, + UINT16 uSize) +{ + MIDIINCAPSA micA; + UINT ret; + + if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + + ret = midiInGetDevCapsA(uDeviceID, &micA, uSize); + if (ret == MMSYSERR_NOERROR) { + MIDIINCAPS16 mic16; + mic16.wMid = micA.wMid; + mic16.wPid = micA.wPid; + mic16.vDriverVersion = micA.vDriverVersion; + strcpy(mic16.szPname, micA.szPname); + mic16.dwSupport = micA.dwSupport; + memcpy(lpCaps, &mic16, min(uSize, sizeof(mic16))); + } + return ret; +} + +/************************************************************************** + * midiInGetErrorText [MMSYSTEM.303] + */ +UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize) +{ + return midiInGetErrorTextA(uError, lpText, uSize); +} + +/************************************************************************** + * midiInOpen [MMSYSTEM.304] + */ +UINT16 WINAPI midiInOpen16(HMIDIIN16* lphMidiIn, UINT16 uDeviceID, + DWORD dwCallback, DWORD dwInstance, DWORD dwFlags) +{ + HMIDIIN xhmid; + UINT ret; + + ret = MIDI_InOpen(&xhmid, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE); + + if (lphMidiIn) *lphMidiIn = HMIDIIN_16(xhmid); + return ret; +} + +/************************************************************************** + * midiInClose [MMSYSTEM.305] + */ +UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn) +{ + return midiInClose(HMIDIIN_32(hMidiIn)); +} + +/************************************************************************** + * midiInPrepareHeader [MMSYSTEM.306] + */ +UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn, /* [in] */ + SEGPTR lpsegMidiInHdr, /* [???] */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %08lx, %d)\n", hMidiIn, lpsegMidiInHdr, uSize); + + if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, MIDM_PREPARE, lpsegMidiInHdr, uSize, FALSE); +} + +/************************************************************************** + * midiInUnprepareHeader [MMSYSTEM.307] + */ +UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn, /* [in] */ + SEGPTR lpsegMidiInHdr, /* [???] */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + LPMIDIHDR16 lpMidiInHdr = MapSL(lpsegMidiInHdr); + + TRACE("(%04X, %08lx, %d)\n", hMidiIn, lpsegMidiInHdr, uSize); + + if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) { + return MMSYSERR_NOERROR; + } + + if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, MIDM_UNPREPARE, lpsegMidiInHdr, uSize, FALSE); +} + +/************************************************************************** + * midiInAddBuffer [MMSYSTEM.308] + */ +UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn, /* [in] */ + MIDIHDR16* lpsegMidiInHdr, /* [???] NOTE: SEGPTR */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p, %d)\n", hMidiIn, lpsegMidiInHdr, uSize); + + if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD_PTR)lpsegMidiInHdr, uSize, FALSE); +} + +/************************************************************************** + * midiInStart [MMSYSTEM.309] + */ +UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn) +{ + return midiInStart(HMIDIIN_32(hMidiIn)); +} + +/************************************************************************** + * midiInStop [MMSYSTEM.310] + */ +UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn) +{ + return midiInStop(HMIDIIN_32(hMidiIn)); +} + +/************************************************************************** + * midiInReset [MMSYSTEM.311] + */ +UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn) +{ + return midiInReset(HMIDIIN_32(hMidiIn)); +} + +/************************************************************************** + * midiInGetID [MMSYSTEM.312] + */ +UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID); + + if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM; + + if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, TRUE)) == NULL) + return MMSYSERR_INVALHANDLE; + + *lpuDeviceID = wmld->uDeviceID; + + return MMSYSERR_NOERROR; +} + +/************************************************************************** + * midiInMessage [MMSYSTEM.313] + */ +DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage, + DWORD dwParam1, DWORD dwParam2) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2); + + switch (uMessage) { + case MIDM_OPEN: + case MIDM_CLOSE: + FIXME("can't handle OPEN or CLOSE message!\n"); + return MMSYSERR_NOTSUPPORTED; + + case MIDM_GETDEVCAPS: + return midiInGetDevCaps16(hMidiIn, MapSL(dwParam1), dwParam2); + case MIDM_PREPARE: + return midiInPrepareHeader16(hMidiIn, dwParam1, dwParam2); + case MIDM_UNPREPARE: + return midiInUnprepareHeader16(hMidiIn, dwParam1, dwParam2); + case MIDM_ADDBUFFER: + return midiInAddBuffer16(hMidiIn, MapSL(dwParam1), dwParam2); + } + + if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE); +} + +/************************************************************************** + * midiStreamClose [MMSYSTEM.252] + */ +MMRESULT16 WINAPI midiStreamClose16(HMIDISTRM16 hMidiStrm) +{ + return midiStreamClose(HMIDISTRM_32(hMidiStrm)); +} + +/************************************************************************** + * midiStreamOpen [MMSYSTEM.251] + */ +MMRESULT16 WINAPI midiStreamOpen16(HMIDISTRM16* phMidiStrm, LPUINT16 devid, + DWORD cMidi, DWORD dwCallback, + DWORD dwInstance, DWORD fdwOpen) +{ + HMIDISTRM hMidiStrm32; + MMRESULT ret; + UINT devid32; + + if (!phMidiStrm || !devid) + return MMSYSERR_INVALPARAM; + devid32 = *devid; + ret = MIDI_StreamOpen(&hMidiStrm32, &devid32, cMidi, dwCallback, + dwInstance, fdwOpen, FALSE); + *phMidiStrm = HMIDISTRM_16(hMidiStrm32); + *devid = devid32; + return ret; +} + +/************************************************************************** + * midiStreamOut [MMSYSTEM.254] + */ +MMRESULT16 WINAPI midiStreamOut16(HMIDISTRM16 hMidiStrm, LPMIDIHDR16 lpMidiHdr, UINT16 cbMidiHdr) +{ + return midiStreamOut(HMIDISTRM_32(hMidiStrm), (LPMIDIHDR)lpMidiHdr, + cbMidiHdr); +} + +/************************************************************************** + * midiStreamPause [MMSYSTEM.255] + */ +MMRESULT16 WINAPI midiStreamPause16(HMIDISTRM16 hMidiStrm) +{ + return midiStreamPause(HMIDISTRM_32(hMidiStrm)); +} + +/************************************************************************** + * midiStreamPosition [MMSYSTEM.253] + */ +MMRESULT16 WINAPI midiStreamPosition16(HMIDISTRM16 hMidiStrm, LPMMTIME16 lpmmt16, UINT16 cbmmt) +{ + MMTIME mmt32; + MMRESULT ret; + + if (!lpmmt16) + return MMSYSERR_INVALPARAM; + MMSYSTEM_MMTIME16to32(&mmt32, lpmmt16); + ret = midiStreamPosition(HMIDISTRM_32(hMidiStrm), &mmt32, sizeof(MMTIME)); + MMSYSTEM_MMTIME32to16(lpmmt16, &mmt32); + return ret; +} + +/************************************************************************** + * midiStreamProperty [MMSYSTEM.250] + */ +MMRESULT16 WINAPI midiStreamProperty16(HMIDISTRM16 hMidiStrm, LPBYTE lpPropData, DWORD dwProperty) +{ + return midiStreamProperty(HMIDISTRM_32(hMidiStrm), lpPropData, dwProperty); +} + +/************************************************************************** + * midiStreamRestart [MMSYSTEM.256] + */ +MMRESULT16 WINAPI midiStreamRestart16(HMIDISTRM16 hMidiStrm) +{ + return midiStreamRestart(HMIDISTRM_32(hMidiStrm)); +} + +/************************************************************************** + * midiStreamStop [MMSYSTEM.257] + */ +MMRESULT16 WINAPI midiStreamStop16(HMIDISTRM16 hMidiStrm) +{ + return midiStreamStop(HMIDISTRM_32(hMidiStrm)); +} + +/* ################################################### + * # WAVE # + * ################################################### + */ + +/************************************************************************** + * waveOutGetNumDevs [MMSYSTEM.401] + */ +UINT16 WINAPI waveOutGetNumDevs16(void) +{ + return MMDRV_GetNum(MMDRV_WAVEOUT); +} + +/************************************************************************** + * waveOutGetDevCaps [MMSYSTEM.402] + */ +UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID, + LPWAVEOUTCAPS16 lpCaps, UINT16 uSize) +{ + WAVEOUTCAPSA wocA; + UINT ret; + TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize); + + if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + + ret = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(wocA)); + if (ret == MMSYSERR_NOERROR) { + WAVEOUTCAPS16 woc16; + woc16.wMid = wocA.wMid; + woc16.wPid = wocA.wPid; + woc16.vDriverVersion = wocA.vDriverVersion; + strcpy(woc16.szPname, wocA.szPname); + woc16.dwFormats = wocA.dwFormats; + woc16.wChannels = wocA.wChannels; + woc16.dwSupport = wocA.dwSupport; + memcpy(lpCaps, &woc16, min(uSize, sizeof(woc16))); + } + return ret; +} + +/************************************************************************** + * waveOutGetErrorText [MMSYSTEM.403] + */ +UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize) +{ + return waveOutGetErrorTextA(uError, lpText, uSize); +} + +/************************************************************************** + * waveOutOpen [MMSYSTEM.404] + */ +UINT16 WINAPI waveOutOpen16(HWAVEOUT16* lphWaveOut, UINT16 uDeviceID, + const LPWAVEFORMATEX lpFormat, DWORD dwCallback, + DWORD dwInstance, DWORD dwFlags) +{ + HANDLE hWaveOut; + UINT ret; + + /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly + * call the 32 bit version + * however, we need to promote correctly the wave mapper id + * (0xFFFFFFFF and not 0x0000FFFF) + */ + ret = WAVE_Open(&hWaveOut, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID, + MMDRV_WAVEOUT, lpFormat, dwCallback, dwInstance, dwFlags, FALSE); + + if (lphWaveOut != NULL) *lphWaveOut = HWAVEOUT_16(hWaveOut); + return ret; +} + +/************************************************************************** + * waveOutClose [MMSYSTEM.405] + */ +UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveOutClose(HWAVEOUT_32(hWaveOut)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveOutPrepareHeader [MMSYSTEM.406] + */ +UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */ + SEGPTR lpsegWaveOutHdr, /* [???] */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr); + + TRACE("(%04X, %08lx, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize); + + if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM; + + if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, WODM_PREPARE, lpsegWaveOutHdr, uSize, FALSE); +} + +/************************************************************************** + * waveOutUnprepareHeader [MMSYSTEM.407] + */ +UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */ + SEGPTR lpsegWaveOutHdr, /* [???] */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr); + + TRACE("(%04X, %08lx, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize); + + if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) { + return MMSYSERR_NOERROR; + } + + if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, WODM_UNPREPARE, lpsegWaveOutHdr, uSize, FALSE); +} + +/************************************************************************** + * waveOutWrite [MMSYSTEM.408] + */ +UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, /* [in] */ + LPWAVEHDR lpsegWaveOutHdr, /* [???] NOTE: SEGPTR */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize); + + if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, WODM_WRITE, (DWORD_PTR)lpsegWaveOutHdr, uSize, FALSE); +} + +/************************************************************************** + * waveOutBreakLoop [MMSYSTEM.419] + */ +UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut16) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveOutBreakLoop(HWAVEOUT_32(hWaveOut16)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveOutPause [MMSYSTEM.409] + */ +UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut16) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveOutPause(HWAVEOUT_32(hWaveOut16)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveOutReset [MMSYSTEM.411] + */ +UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut16) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveOutReset(HWAVEOUT_32(hWaveOut16)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveOutRestart [MMSYSTEM.410] + */ +UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut16) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveOutRestart(HWAVEOUT_32(hWaveOut16)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveOutGetPosition [MMSYSTEM.412] + */ +UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut, LPMMTIME16 lpTime, + UINT16 uSize) +{ + UINT ret; + MMTIME mmt; + + mmt.wType = lpTime->wType; + ret = waveOutGetPosition(HWAVEOUT_32(hWaveOut), &mmt, sizeof(mmt)); + MMSYSTEM_MMTIME32to16(lpTime, &mmt); + return ret; +} + +/************************************************************************** + * waveOutGetPitch [MMSYSTEM.413] + */ +UINT16 WINAPI waveOutGetPitch16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw) +{ + return waveOutGetPitch(HWAVEOUT_32(hWaveOut16), lpdw); +} + +/************************************************************************** + * waveOutSetPitch [MMSYSTEM.414] + */ +UINT16 WINAPI waveOutSetPitch16(HWAVEOUT16 hWaveOut16, DWORD dw) +{ + return waveOutSetPitch(HWAVEOUT_32(hWaveOut16), dw); +} + +/************************************************************************** + * waveOutGetPlaybackRate [MMSYSTEM.417] + */ +UINT16 WINAPI waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw) +{ + return waveOutGetPlaybackRate(HWAVEOUT_32(hWaveOut16), lpdw); +} + +/************************************************************************** + * waveOutSetPlaybackRate [MMSYSTEM.418] + */ +UINT16 WINAPI waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16, DWORD dw) +{ + return waveOutSetPlaybackRate(HWAVEOUT_32(hWaveOut16), dw); +} + +/************************************************************************** + * waveOutGetVolume [MMSYSTEM.415] + */ +UINT16 WINAPI waveOutGetVolume16(UINT16 devid, LPDWORD lpdw) +{ + return waveOutGetVolume(HWAVEOUT_32(devid), lpdw); +} + +/************************************************************************** + * waveOutSetVolume [MMSYSTEM.416] + */ +UINT16 WINAPI waveOutSetVolume16(UINT16 devid, DWORD dw) +{ + return waveOutSetVolume(HWAVEOUT_32(devid), dw); +} + +/************************************************************************** + * waveOutGetID [MMSYSTEM.420] + */ +UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16* lpuDeviceID) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p);\n", hWaveOut, lpuDeviceID); + + if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE; + + if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + *lpuDeviceID = wmld->uDeviceID; + return 0; +} + +/************************************************************************** + * waveOutMessage [MMSYSTEM.421] + */ +DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage, + DWORD dwParam1, DWORD dwParam2) +{ + LPWINE_MLD wmld; + + TRACE("(%04x, %u, %ld, %ld)\n", hWaveOut, uMessage, dwParam1, dwParam2); + + if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) { + if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, TRUE)) != NULL) { + if (uMessage == DRV_QUERYDRVENTRY || uMessage == DRV_QUERYDEVNODE) + dwParam1 = (DWORD)MapSL(dwParam1); + return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2); + } + return MMSYSERR_INVALHANDLE; + } + + /* from M$ KB */ + if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER)) + return MMSYSERR_INVALPARAM; + + return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE); +} + +/************************************************************************** + * waveInGetNumDevs [MMSYSTEM.501] + */ +UINT16 WINAPI waveInGetNumDevs16(void) +{ + return MMDRV_GetNum(MMDRV_WAVEIN); +} + +/************************************************************************** + * waveInGetDevCaps [MMSYSTEM.502] + */ +UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps, + UINT16 uSize) +{ + WAVEINCAPSA wicA; + UINT ret; + + if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + + ret = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(wicA)); + if (ret == MMSYSERR_NOERROR) { + WAVEINCAPS16 wic16; + wic16.wMid = wicA.wMid; + wic16.wPid = wicA.wPid; + wic16.vDriverVersion = wicA.vDriverVersion; + strcpy(wic16.szPname, wicA.szPname); + wic16.dwFormats = wicA.dwFormats; + wic16.wChannels = wicA.wChannels; + memcpy(lpCaps, &wic16, min(uSize, sizeof(wic16))); + } + return ret; +} + +/************************************************************************** + * waveInGetErrorText [MMSYSTEM.503] + */ +UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize) +{ + return waveInGetErrorTextA(uError, lpText, uSize); +} + +/************************************************************************** + * waveInOpen [MMSYSTEM.504] + */ +UINT16 WINAPI waveInOpen16(HWAVEIN16* lphWaveIn, UINT16 uDeviceID, + const LPWAVEFORMATEX lpFormat, DWORD dwCallback, + DWORD dwInstance, DWORD dwFlags) +{ + HANDLE hWaveIn; + UINT ret; + + /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly + * call the 32 bit version + * however, we need to promote correctly the wave mapper id + * (0xFFFFFFFF and not 0x0000FFFF) + */ + ret = WAVE_Open(&hWaveIn, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID, + MMDRV_WAVEIN, lpFormat, dwCallback, dwInstance, dwFlags, FALSE); + + if (lphWaveIn != NULL) *lphWaveIn = HWAVEIN_16(hWaveIn); + return ret; +} + +/************************************************************************** + * waveInClose [MMSYSTEM.505] + */ +UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveInClose(HWAVEIN_32(hWaveIn)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveInPrepareHeader [MMSYSTEM.506] + */ +UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn, /* [in] */ + SEGPTR lpsegWaveInHdr, /* [???] */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr); + UINT16 ret; + + TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize); + + if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE; + if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + lpWaveInHdr->dwBytesRecorded = 0; + + ret = MMDRV_Message(wmld, WIDM_PREPARE, lpsegWaveInHdr, uSize, FALSE); + return ret; +} + +/************************************************************************** + * waveInUnprepareHeader [MMSYSTEM.507] + */ +UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn, /* [in] */ + SEGPTR lpsegWaveInHdr, /* [???] */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr); + + TRACE("(%04X, %08lx, %u);\n", hWaveIn, lpsegWaveInHdr, uSize); + + if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM; + + if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) { + return MMSYSERR_NOERROR; + } + + if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, WIDM_UNPREPARE, lpsegWaveInHdr, uSize, FALSE); +} + +/************************************************************************** + * waveInAddBuffer [MMSYSTEM.508] + */ +UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn, /* [in] */ + WAVEHDR* lpsegWaveInHdr, /* [???] NOTE: SEGPTR */ + UINT16 uSize) /* [in] */ +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p, %u);\n", hWaveIn, lpsegWaveInHdr, uSize); + + if (lpsegWaveInHdr == NULL) return MMSYSERR_INVALPARAM; + if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD_PTR)lpsegWaveInHdr, uSize, FALSE); +} + +/************************************************************************** + * waveInReset [MMSYSTEM.511] + */ +UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn16) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveInReset(HWAVEIN_32(hWaveIn16)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveInStart [MMSYSTEM.509] + */ +UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn16) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveInStart(HWAVEIN_32(hWaveIn16)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveInStop [MMSYSTEM.510] + */ +UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn16) +{ + DWORD level; + UINT16 ret; + + ReleaseThunkLock(&level); + ret = waveInStop(HWAVEIN_32(hWaveIn16)); + RestoreThunkLock(level); + return ret; +} + +/************************************************************************** + * waveInGetPosition [MMSYSTEM.512] + */ +UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn, LPMMTIME16 lpTime, + UINT16 uSize) +{ + UINT ret; + MMTIME mmt; + + mmt.wType = lpTime->wType; + ret = waveInGetPosition(HWAVEIN_32(hWaveIn), &mmt, sizeof(mmt)); + MMSYSTEM_MMTIME32to16(lpTime, &mmt); + return ret; +} + +/************************************************************************** + * waveInGetID [MMSYSTEM.513] + */ +UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16* lpuDeviceID) +{ + LPWINE_MLD wmld; + + TRACE("(%04X, %p);\n", hWaveIn, lpuDeviceID); + + if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE; + + if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL) + return MMSYSERR_INVALHANDLE; + + *lpuDeviceID = wmld->uDeviceID; + return MMSYSERR_NOERROR; +} + +/************************************************************************** + * waveInMessage [MMSYSTEM.514] + */ +DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage, + DWORD dwParam1, DWORD dwParam2) +{ + LPWINE_MLD wmld; + + TRACE("(%04x, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2); + + if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL) { + if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, TRUE)) != NULL) { + if (uMessage == DRV_QUERYDRVENTRY || uMessage == DRV_QUERYDEVNODE) + dwParam1 = (DWORD)MapSL(dwParam1); + return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2); + } + return MMSYSERR_INVALHANDLE; + } + + /* from M$ KB */ + if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER)) + return MMSYSERR_INVALPARAM; + + return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE); +} + +/* ################################################### + * # TASK # + * ################################################### + */ + +/*#define USE_MM_TSK_WINE*/ + +/************************************************************************** + * mmTaskCreate [MMSYSTEM.900] + * + * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be + * called upon creation with dwPmt as parameter. + */ +HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD dwPmt) +{ + HINSTANCE16 ret; + HINSTANCE16 handle; + char cmdline[16]; + DWORD showCmd = 0x40002; + LOADPARAMS16 lp; + + TRACE("(%08lx, %p, %08lx);\n", spProc, lphMmTask, dwPmt); + /* This to work requires NE modules to be started with a binary command line + * which is not currently the case. A patch exists but has never been committed. + * A workaround would be to integrate code for mmtask.tsk into Wine, but + * this requires tremendous work (starting with patching tools/build to + * create NE executables (and not only DLLs) for builtins modules. + * EP 99/04/25 + */ + FIXME("This is currently broken. It will fail\n"); + + cmdline[0] = 0x0d; + *(LPDWORD)(cmdline + 1) = (DWORD)spProc; + *(LPDWORD)(cmdline + 5) = dwPmt; + *(LPDWORD)(cmdline + 9) = 0; + + lp.hEnvironment = 0; + lp.cmdLine = MapLS(cmdline); + lp.showCmd = MapLS(&showCmd); + lp.reserved = 0; + +#ifndef USE_MM_TSK_WINE + handle = LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp); +#else + handle = LoadModule16("mmtask.tsk", &lp); +#endif + if (handle < 32) { + ret = (handle) ? 1 : 2; + handle = 0; + } else { + ret = 0; + } + if (lphMmTask) + *lphMmTask = handle; + + UnMapLS( lp.cmdLine ); + UnMapLS( lp.showCmd ); + TRACE("=> 0x%04x/%d\n", handle, ret); + return ret; +} + +#ifdef USE_MM_TSK_WINE +/* C equivalent to mmtask.tsk binary content */ +void mmTaskEntryPoint16(LPSTR cmdLine, WORD di, WORD si) +{ + int len = cmdLine[0x80]; + + if (len / 2 == 6) { + void (*fpProc)(DWORD) = MapSL(*((DWORD*)(cmdLine + 1))); + DWORD dwPmt = *((DWORD*)(cmdLine + 5)); + +#if 0 + InitTask16(); /* FIXME: pmts / from context ? */ + InitApp(di); +#endif + if (SetMessageQueue16(0x40)) { + WaitEvent16(0); + if (HIWORD(fpProc)) { + OldYield16(); +/* EPP StackEnter16(); */ + (fpProc)(dwPmt); + } + } + } + OldYield16(); + OldYield16(); + OldYield16(); + ExitProcess(0); +} +#endif + +/************************************************************************** + * mmTaskBlock [MMSYSTEM.902] + */ +void WINAPI mmTaskBlock16(HINSTANCE16 WINE_UNUSED hInst) +{ + MSG msg; + + do { + GetMessageA(&msg, 0, 0, 0); + if (msg.hwnd) { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + } while (msg.message < 0x3A0); +} + +/************************************************************************** + * mmTaskSignal [MMSYSTEM.903] + */ +LRESULT WINAPI mmTaskSignal16(HTASK16 ht) +{ + TRACE("(%04x);\n", ht); + return PostThreadMessageW( HTASK_32(ht), WM_USER, 0, 0 ); +} + +/************************************************************************** + * mmGetCurrentTask [MMSYSTEM.904] + */ +HTASK16 WINAPI mmGetCurrentTask16(void) +{ + return GetCurrentTask(); +} + +/************************************************************************** + * mmTaskYield [MMSYSTEM.905] + */ +void WINAPI mmTaskYield16(void) +{ + MSG msg; + + if (PeekMessageA(&msg, 0, 0, 0, 0)) { + K32WOWYield16(); + } +} + +extern DWORD WINAPI GetProcessFlags(DWORD); + +/****************************************************************** + * WINMM_GetmmThread + * + * + */ +static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16 h) +{ + return (WINE_MMTHREAD*)MapSL( MAKESEGPTR(h, 0) ); +} + +void WINAPI WINE_mmThreadEntryPoint(DWORD); + +/************************************************************************** + * mmThreadCreate [MMSYSTEM.1120] + * + * undocumented + * Creates a MM thread, calling fpThreadAddr(dwPmt). + * dwFlags: + * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc + * bit.1 set means to open a VxD for this thread (unsupported) + */ +LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags) +{ + HANDLE16 hndl; + LRESULT ret; + + TRACE("(%p, %p, %08lx, %08lx)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags); + + hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT); + + if (hndl == 0) { + ret = 2; + } else { + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + +#if 0 + /* force mmtask routines even if mmthread is required */ + /* this will work only if the patch about binary cmd line and NE tasks + * is committed + */ + dwFlags |= 1; +#endif + + lpMMThd->dwSignature = WINE_MMTHREAD_CREATED; + lpMMThd->dwCounter = 0; + lpMMThd->hThread = 0; + lpMMThd->dwThreadID = 0; + lpMMThd->fpThread = (DWORD)fpThreadAddr; + lpMMThd->dwThreadPmt = dwPmt; + lpMMThd->dwSignalCount = 0; + lpMMThd->hEvent = 0; + lpMMThd->hVxD = 0; + lpMMThd->dwStatus = 0; + lpMMThd->dwFlags = dwFlags; + lpMMThd->hTask = 0; + + if ((dwFlags & 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) { + lpMMThd->hEvent = CreateEventA(0, 0, 1, 0); + + TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd); + if (lpMMThd->dwFlags & 2) { + /* as long as we don't support MM VxD in wine, we don't need + * to care about this flag + */ + /* FIXME("Don't know how to properly open VxD handles\n"); */ + /* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */ + } + + lpMMThd->hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)WINE_mmThreadEntryPoint, + (LPVOID)(DWORD)hndl, CREATE_SUSPENDED, &lpMMThd->dwThreadID); + if (lpMMThd->hThread == 0) { + WARN("Couldn't create thread\n"); + /* clean-up(VxDhandle...); devicedirectio... */ + if (lpMMThd->hEvent != 0) + CloseHandle(lpMMThd->hEvent); + ret = 2; + } else { + TRACE("Got a nice thread hndl=%p id=0x%08lx\n", lpMMThd->hThread, lpMMThd->dwThreadID); + ret = 0; + } + } else { + /* get WINE_mmThreadEntryPoint() + * 2047 is its ordinal in mmsystem.spec + */ + FARPROC16 fp = GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR)2047); + + TRACE("farproc seg=0x%08lx lin=%p\n", (DWORD)fp, MapSL((SEGPTR)fp)); + + ret = (fp == 0) ? 2 : mmTaskCreate16((DWORD)fp, 0, hndl); + } + + if (ret == 0) { + if (lpMMThd->hThread && !ResumeThread(lpMMThd->hThread)) + WARN("Couldn't resume thread\n"); + + while (lpMMThd->dwStatus != 0x10) { /* test also HIWORD of dwStatus */ + UserYield16(); + } + } + } + + if (ret != 0) { + GlobalFree16(hndl); + hndl = 0; + } + + if (lpHndl) + *lpHndl = hndl; + + TRACE("ok => %ld\n", ret); + return ret; +} + +/************************************************************************** + * mmThreadSignal [MMSYSTEM.1121] + */ +void WINAPI mmThreadSignal16(HANDLE16 hndl) +{ + TRACE("(%04x)!\n", hndl); + + if (hndl) { + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + + lpMMThd->dwCounter++; + if (lpMMThd->hThread != 0) { + InterlockedIncrement(&lpMMThd->dwSignalCount); + SetEvent(lpMMThd->hEvent); + } else { + mmTaskSignal16(lpMMThd->hTask); + } + lpMMThd->dwCounter--; + } +} + +static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd) +{ + MSG msg; + DWORD ret; + + if (lpMMThd->dwThreadID != GetCurrentThreadId()) + ERR("Not called by thread itself\n"); + + for (;;) { + ResetEvent(lpMMThd->hEvent); + if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0) + break; + InterlockedIncrement(&lpMMThd->dwSignalCount); + + TRACE("S1\n"); + + ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT); + switch (ret) { + case WAIT_OBJECT_0: /* Event */ + TRACE("S2.1\n"); + break; + case WAIT_OBJECT_0 + 1: /* Msg */ + TRACE("S2.2\n"); + if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + break; + default: + WARN("S2.x unsupported ret val 0x%08lx\n", ret); + } + TRACE("S3\n"); + } +} + +/************************************************************************** + * mmThreadBlock [MMSYSTEM.1122] + */ +void WINAPI mmThreadBlock16(HANDLE16 hndl) +{ + TRACE("(%04x)!\n", hndl); + + if (hndl) { + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + + if (lpMMThd->hThread != 0) { + DWORD lc; + + ReleaseThunkLock(&lc); + MMSYSTEM_ThreadBlock(lpMMThd); + RestoreThunkLock(lc); + } else { + mmTaskBlock16(lpMMThd->hTask); + } + } + TRACE("done\n"); +} + +/************************************************************************** + * mmThreadIsCurrent [MMSYSTEM.1123] + */ +BOOL16 WINAPI mmThreadIsCurrent16(HANDLE16 hndl) +{ + BOOL16 ret = FALSE; + + TRACE("(%04x)!\n", hndl); + + if (hndl && mmThreadIsValid16(hndl)) { + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + ret = (GetCurrentThreadId() == lpMMThd->dwThreadID); + } + TRACE("=> %d\n", ret); + return ret; +} + +/************************************************************************** + * mmThreadIsValid [MMSYSTEM.1124] + */ +BOOL16 WINAPI mmThreadIsValid16(HANDLE16 hndl) +{ + BOOL16 ret = FALSE; + + TRACE("(%04x)!\n", hndl); + + if (hndl) { + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + + if (!IsBadWritePtr(lpMMThd, sizeof(WINE_MMTHREAD)) && + lpMMThd->dwSignature == WINE_MMTHREAD_CREATED && + IsTask16(lpMMThd->hTask)) { + lpMMThd->dwCounter++; + if (lpMMThd->hThread != 0) { + DWORD dwThreadRet; + if (GetExitCodeThread(lpMMThd->hThread, &dwThreadRet) && + dwThreadRet == STATUS_PENDING) { + ret = TRUE; + } + } else { + ret = TRUE; + } + lpMMThd->dwCounter--; + } + } + TRACE("=> %d\n", ret); + return ret; +} + +/************************************************************************** + * mmThreadGetTask [MMSYSTEM.1125] + */ +HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl) +{ + HANDLE16 ret = 0; + + TRACE("(%04x)\n", hndl); + + if (mmThreadIsValid16(hndl)) { + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + ret = lpMMThd->hTask; + } + return ret; +} + +/************************************************************************** + * __wine_mmThreadEntryPoint (MMSYSTEM.2047) + */ +void WINAPI WINE_mmThreadEntryPoint(DWORD _pmt) +{ + HANDLE16 hndl = (HANDLE16)_pmt; + WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl); + + TRACE("(%04x %p)\n", hndl, lpMMThd); + + lpMMThd->hTask = LOWORD(GetCurrentTask()); + TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask); + lpMMThd->dwStatus = 0x10; + MMSYSTEM_ThreadBlock(lpMMThd); + TRACE("[20-%p]\n", lpMMThd->hThread); + lpMMThd->dwStatus = 0x20; + if (lpMMThd->fpThread) { + WOWCallback16(lpMMThd->fpThread, lpMMThd->dwThreadPmt); + } + lpMMThd->dwStatus = 0x30; + TRACE("[30-%p]\n", lpMMThd->hThread); + while (lpMMThd->dwCounter) { + Sleep(1); + /* K32WOWYield16();*/ + } + TRACE("[XX-%p]\n", lpMMThd->hThread); + /* paranoia */ + lpMMThd->dwSignature = WINE_MMTHREAD_DELETED; + /* close lpMMThread->hVxD directIO */ + if (lpMMThd->hEvent) + CloseHandle(lpMMThd->hEvent); + GlobalFree16(hndl); + TRACE("done\n"); +} + +typedef BOOL16 (WINAPI *MMCPLCALLBACK)(HWND, LPCSTR, LPCSTR, LPCSTR); + +/************************************************************************** + * mmShowMMCPLPropertySheet [MMSYSTEM.1150] + */ +BOOL16 WINAPI mmShowMMCPLPropertySheet16(HWND hWnd, LPCSTR lpStrDevice, + LPCSTR lpStrTab, LPCSTR lpStrTitle) +{ + HANDLE hndl; + BOOL16 ret = FALSE; + + TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd, lpStrDevice, lpStrTab, lpStrTitle); + + hndl = LoadLibraryA("MMSYS.CPL"); + if (hndl != 0) { + MMCPLCALLBACK fp = (MMCPLCALLBACK)GetProcAddress(hndl, "ShowMMCPLPropertySheet"); + if (fp != NULL) { + DWORD lc; + ReleaseThunkLock(&lc); + ret = (fp)(hWnd, lpStrDevice, lpStrTab, lpStrTitle); + RestoreThunkLock(lc); + } + FreeLibrary(hndl); + } + + return ret; +} + +/************************************************************************** + * StackEnter [MMSYSTEM.32] + */ +void WINAPI StackEnter16(void) +{ +#ifdef __i386__ + /* mmsystem.dll from Win 95 does only this: so does Wine */ + __asm__("stc"); +#endif +} + +/************************************************************************** + * StackLeave [MMSYSTEM.33] + */ +void WINAPI StackLeave16(void) +{ +#ifdef __i386__ + /* mmsystem.dll from Win 95 does only this: so does Wine */ + __asm__("stc"); +#endif +} + +/************************************************************************** + * WMMMidiRunOnce [MMSYSTEM.8] + */ +void WINAPI WMMMidiRunOnce16(void) +{ + FIXME("(), stub!\n"); +} + +/* ################################################### + * # DRIVER # + * ################################################### + */ + +/************************************************************************** + * DRIVER_MapMsg32To16 [internal] + * + * Map a 32 bit driver message to a 16 bit driver message. + */ +static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2) +{ + WINMM_MapType ret = WINMM_MAP_MSGERROR; + + switch (wMsg) { + case DRV_LOAD: + case DRV_ENABLE: + case DRV_DISABLE: + case DRV_FREE: + case DRV_QUERYCONFIGURE: + case DRV_REMOVE: + case DRV_EXITSESSION: + case DRV_EXITAPPLICATION: + case DRV_POWER: + case DRV_CLOSE: /* should be 0/0 */ + case DRV_OPEN: /* pass through */ + /* lParam1 and lParam2 are not used */ + ret = WINMM_MAP_OK; + break; + case DRV_CONFIGURE: + case DRV_INSTALL: + /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used, + * lParam2 is a pointer to DRVCONFIGINFO + */ + if (*lParam2) { + LPDRVCONFIGINFO16 dci16 = HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16) ); + LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2); + + if (dci16) { + LPSTR str1; + INT len; + dci16->dwDCISize = sizeof(DRVCONFIGINFO16); + + if (dci32->lpszDCISectionName) { + len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, NULL, 0, NULL, NULL ); + str1 = HeapAlloc( GetProcessHeap(), 0, len ); + if (str1) { + WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, str1, len, NULL, NULL ); + dci16->lpszDCISectionName = MapLS( str1 ); + } else { + return WINMM_MAP_NOMEM; + } + } else { + dci16->lpszDCISectionName = 0L; + } + if (dci32->lpszDCIAliasName) { + len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, NULL, 0, NULL, NULL ); + str1 = HeapAlloc( GetProcessHeap(), 0, len ); + if (str1) { + WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, str1, len, NULL, NULL ); + dci16->lpszDCIAliasName = MapLS( str1 ); + } else { + return WINMM_MAP_NOMEM; + } + } else { + dci16->lpszDCISectionName = 0L; + } + } else { + return WINMM_MAP_NOMEM; + } + *lParam2 = MapLS( dci16 ); + ret = WINMM_MAP_OKMEM; + } else { + ret = WINMM_MAP_OK; + } + break; + default: + if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) { + FIXME("Unknown message 0x%04x\n", wMsg); + } + ret = WINMM_MAP_OK; + } + return ret; +} + +/************************************************************************** + * DRIVER_UnMapMsg32To16 [internal] + * + * UnMap a 32 bit driver message to a 16 bit driver message. + */ +static WINMM_MapType DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2) +{ + WINMM_MapType ret = WINMM_MAP_MSGERROR; + + switch (wMsg) { + case DRV_LOAD: + case DRV_ENABLE: + case DRV_DISABLE: + case DRV_FREE: + case DRV_QUERYCONFIGURE: + case DRV_REMOVE: + case DRV_EXITSESSION: + case DRV_EXITAPPLICATION: + case DRV_POWER: + case DRV_OPEN: + case DRV_CLOSE: + /* lParam1 and lParam2 are not used */ + break; + case DRV_CONFIGURE: + case DRV_INSTALL: + /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */ + if (lParam2) { + LPDRVCONFIGINFO16 dci16 = MapSL(lParam2); + HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCISectionName) ); + HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCIAliasName) ); + UnMapLS( lParam2 ); + UnMapLS( dci16->lpszDCISectionName ); + UnMapLS( dci16->lpszDCIAliasName ); + HeapFree( GetProcessHeap(), 0, dci16 ); + } + ret = WINMM_MAP_OK; + break; + default: + if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) { + FIXME("Unknown message 0x%04x\n", wMsg); + } + ret = WINMM_MAP_OK; + } + return ret; +} + +/************************************************************************** + * DRIVER_TryOpenDriver16 [internal] + * + * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName. + */ +static LPWINE_DRIVER DRIVER_OpenDriver16(LPCSTR fn, LPCSTR sn, LPARAM lParam2) +{ + LPWINE_DRIVER lpDrv = NULL; + LPCSTR cause = 0; + + TRACE("(%s, %08lX);\n", debugstr_a(sn), lParam2); + + lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER)); + if (lpDrv == NULL) {cause = "OOM"; goto exit;} + + /* FIXME: shall we do some black magic here on sn ? + * drivers32 => drivers + * mci32 => mci + * ... + */ + lpDrv->d.d16.hDriver16 = OpenDriver16(fn, sn, lParam2); + if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;} + lpDrv->dwFlags = WINE_GDF_16BIT; + + TRACE("=> %p\n", lpDrv); + return lpDrv; + exit: + HeapFree(GetProcessHeap(), 0, lpDrv); + TRACE("Unable to load 16 bit module %s: %s\n", debugstr_a(fn), cause); + return NULL; +} + +/****************************************************************** + * DRIVER_SendMessage16 + * + * + */ +static LRESULT DRIVER_SendMessage16(HDRVR16 hDrv16, UINT msg, + LPARAM lParam1, LPARAM lParam2) +{ + LRESULT ret = 0; + WINMM_MapType map; + + TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n", + hDrv16, msg, lParam1, lParam2); + + switch (map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) { + case WINMM_MAP_OKMEM: + case WINMM_MAP_OK: + ret = SendDriverMessage16(hDrv16, msg, lParam1, lParam2); + if (map == WINMM_MAP_OKMEM) + DRIVER_UnMapMsg32To16(msg, lParam1, lParam2); + default: + break; + } + return ret; +} + +/****************************************************************** + * DRIVER_CloseDriver16 + * + * + */ +static LRESULT DRIVER_CloseDriver16(HDRVR16 hDrv16, LPARAM lParam1, LPARAM lParam2) +{ + return CloseDriver16(hDrv16, lParam1, lParam2); +} + +/************************************************************************** + * DrvOpen [MMSYSTEM.1100] + */ +HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam) +{ + return OpenDriver16(lpDriverName, lpSectionName, lParam); +} + +/************************************************************************** + * DrvClose [MMSYSTEM.1101] + */ +LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2) +{ + return CloseDriver16(hDrv, lParam1, lParam2); +} + +/************************************************************************** + * DrvSendMessage [MMSYSTEM.1102] + */ +LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1, + LPARAM lParam2) +{ + return SendDriverMessage16(hDrv, msg, lParam1, lParam2); +} + +/************************************************************************** + * DrvGetModuleHandle [MMSYSTEM.1103] + */ +HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv) +{ + return GetDriverModuleHandle16(hDrv); +} + +/************************************************************************** + * DrvDefDriverProc [MMSYSTEM.1104] + */ +LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg, + DWORD dwParam1, DWORD dwParam2) +{ + return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2); +} + +/************************************************************************** + * DriverProc [MMSYSTEM.6] + */ +LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg, + DWORD dwParam1, DWORD dwParam2) +{ + TRACE("dwDevID=%08lx hDrv=%04x wMsg=%04x dwParam1=%08lx dwParam2=%08lx\n", + dwDevID, hDrv, wMsg, dwParam1, dwParam2); + + return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2); +} + +/* ################################################### + * # TIME # + * ################################################### + */ + +/****************************************************************** + * MMSYSTEM_MMTIME32to16 + * + * + */ +void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32) +{ + mmt16->wType = mmt32->wType; + /* layout of rest is the same for 32/16, + * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding + */ + memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u)); +} + +/****************************************************************** + * MMSYSTEM_MMTIME16to32 + * + * + */ +void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16) +{ + mmt32->wType = mmt16->wType; + /* layout of rest is the same for 32/16, + * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding + */ + memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u)); +} + +/************************************************************************** + * timeGetSystemTime [MMSYSTEM.601] + */ +MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize) +{ + TRACE("(%p, %u);\n", lpTime, wSize); + + if (wSize >= sizeof(*lpTime)) { + lpTime->wType = TIME_MS; + TIME_MMTimeStart(); + lpTime->u.ms = WINMM_SysTimeMS; + + TRACE("=> %lu\n", lpTime->u.ms); + } + + return 0; +} + +/************************************************************************** + * timeSetEvent [MMSYSTEM.602] + */ +MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc, + DWORD dwUser, UINT16 wFlags) +{ + if (wFlags & WINE_TIMER_IS32) + WARN("Unknown windows flag... wine internally used.. ooch\n"); + + return TIME_SetEventInternal(wDelay, wResol, (LPTIMECALLBACK)lpFunc, + dwUser, wFlags & ~WINE_TIMER_IS32); +} + +/************************************************************************** + * timeKillEvent [MMSYSTEM.603] + */ +MMRESULT16 WINAPI timeKillEvent16(UINT16 wID) +{ + return timeKillEvent(wID); +} + +/************************************************************************** + * timeGetDevCaps [MMSYSTEM.604] + */ +MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize) +{ + TIMECAPS caps; + MMRESULT ret; + TRACE("(%p, %u) !\n", lpCaps, wSize); + + if (lpCaps == NULL) return MMSYSERR_INVALPARAM; + + ret = timeGetDevCaps(&caps, sizeof(caps)); + if (ret == MMSYSERR_NOERROR) { + TIMECAPS16 tc16; + tc16.wPeriodMin = caps.wPeriodMin; + tc16.wPeriodMax = caps.wPeriodMax; + memcpy(lpCaps, &tc16, min(wSize, sizeof(tc16))); + } + return ret; +} + +/************************************************************************** + * timeBeginPeriod [MMSYSTEM.605] + */ +MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod) +{ + TRACE("(%u) !\n", wPeriod); + + return timeBeginPeriod(wPeriod); +} + +/************************************************************************** + * timeEndPeriod [MMSYSTEM.606] + */ +MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod) +{ + TRACE("(%u) !\n", wPeriod); + + return timeEndPeriod(wPeriod); +} + +/************************************************************************** + * mciSendString [MMSYSTEM.702] + */ +DWORD WINAPI mciSendString16(LPCSTR lpstrCommand, LPSTR lpstrRet, + UINT16 uRetLen, HWND16 hwndCallback) +{ + return mciSendStringA(lpstrCommand, lpstrRet, uRetLen, HWND_32(hwndCallback)); +} + +/************************************************************************** + * mciLoadCommandResource [MMSYSTEM.705] + */ +UINT16 WINAPI mciLoadCommandResource16(HINSTANCE16 hInst, LPCSTR resname, UINT16 type) +{ + HRSRC16 res; + HGLOBAL16 handle; + void *ptr; + + if (!(res = FindResource16( hInst, resname, (LPSTR)RT_RCDATA))) return MCI_NO_COMMAND_TABLE; + if (!(handle = LoadResource16( hInst, res ))) return MCI_NO_COMMAND_TABLE; + ptr = LockResource16(handle); + return MCI_SetCommandTable(ptr, type); + /* FIXME: FreeResource */ +} + +/************************************************************************** + * mciFreeCommandResource [MMSYSTEM.713] + */ +BOOL16 WINAPI mciFreeCommandResource16(UINT16 uTable) +{ + TRACE("(%04x)!\n", uTable); + + return mciFreeCommandResource(uTable); +} + +/* ################################################### + * # MMIO # + * ################################################### + */ + +/**************************************************************** + * MMIO_Map32To16 [INTERNAL] + */ +static LRESULT MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2) +{ + switch (wMsg) { + case MMIOM_CLOSE: + case MMIOM_SEEK: + /* nothing to do */ + break; + case MMIOM_OPEN: + case MMIOM_READ: + case MMIOM_WRITE: + case MMIOM_WRITEFLUSH: + *lp1 = MapLS( (void *)*lp1 ); + break; + case MMIOM_RENAME: + *lp1 = MapLS( (void *)*lp1 ); + *lp2 = MapLS( (void *)*lp2 ); + break; + default: + if (wMsg < MMIOM_USER) + TRACE("Not a mappable message (%ld)\n", wMsg); + } + return MMSYSERR_NOERROR; +} + +/**************************************************************** + * MMIO_UnMap32To16 [INTERNAL] + */ +static LRESULT MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2, + LPARAM lp1, LPARAM lp2) +{ + switch (wMsg) { + case MMIOM_CLOSE: + case MMIOM_SEEK: + /* nothing to do */ + break; + case MMIOM_OPEN: + case MMIOM_READ: + case MMIOM_WRITE: + case MMIOM_WRITEFLUSH: + UnMapLS( lp1 ); + break; + case MMIOM_RENAME: + UnMapLS( lp1 ); + UnMapLS( lp2 ); + break; + default: + if (wMsg < MMIOM_USER) + TRACE("Not a mappable message (%ld)\n", wMsg); + } + return MMSYSERR_NOERROR; +} + +/****************************************************************** + * MMIO_Callback16 + * + * + */ +static LRESULT MMIO_Callback16(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage, + LPARAM lParam1, LPARAM lParam2) +{ + LRESULT result; + MMIOINFO16 mmioInfo16; + SEGPTR segmmioInfo16; + LPARAM lp1 = lParam1, lp2 = lParam2; + WORD args[7]; + + memset(&mmioInfo16, 0, sizeof(MMIOINFO16)); + mmioInfo16.lDiskOffset = lpmmioinfo->lDiskOffset; + mmioInfo16.adwInfo[0] = lpmmioinfo->adwInfo[0]; + mmioInfo16.adwInfo[1] = lpmmioinfo->adwInfo[1]; + mmioInfo16.adwInfo[2] = lpmmioinfo->adwInfo[2]; + mmioInfo16.adwInfo[3] = lpmmioinfo->adwInfo[3]; + /* map (lParam1, lParam2) into (lp1, lp2) 32=>16 */ + if ((result = MMIO_Map32To16(uMessage, &lp1, &lp2)) != MMSYSERR_NOERROR) + return result; + + segmmioInfo16 = MapLS(&mmioInfo16); + args[6] = HIWORD(segmmioInfo16); + args[5] = LOWORD(segmmioInfo16); + args[4] = uMessage; + args[3] = HIWORD(lp1); + args[2] = LOWORD(lp1); + args[1] = HIWORD(lp2); + args[0] = LOWORD(lp2); + WOWCallback16Ex( cb16, WCB16_PASCAL, sizeof(args), args, &result ); + UnMapLS(segmmioInfo16); + MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2); + + lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset; + lpmmioinfo->adwInfo[0] = mmioInfo16.adwInfo[0]; + lpmmioinfo->adwInfo[1] = mmioInfo16.adwInfo[1]; + lpmmioinfo->adwInfo[2] = mmioInfo16.adwInfo[2]; + lpmmioinfo->adwInfo[3] = mmioInfo16.adwInfo[3]; + + return result; +} + +/****************************************************************** + * MMIO_ResetSegmentedData + * + */ +static LRESULT MMIO_SetSegmentedBuffer(HMMIO hmmio, SEGPTR ptr, BOOL release) +{ + LPWINE_MMIO wm; + + if ((wm = MMIO_Get(hmmio)) == NULL) + return MMSYSERR_INVALHANDLE; + if (release) UnMapLS(wm->segBuffer16); + wm->segBuffer16 = ptr; + return MMSYSERR_NOERROR; +} + +/************************************************************************** + * mmioOpen [MMSYSTEM.1210] + */ +HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16, + DWORD dwOpenFlags) +{ + HMMIO ret; + + if (lpmmioinfo16) { + MMIOINFO mmioinfo; + + memset(&mmioinfo, 0, sizeof(mmioinfo)); + + mmioinfo.dwFlags = lpmmioinfo16->dwFlags; + mmioinfo.fccIOProc = lpmmioinfo16->fccIOProc; + mmioinfo.pIOProc = (LPMMIOPROC)lpmmioinfo16->pIOProc; + mmioinfo.cchBuffer = lpmmioinfo16->cchBuffer; + mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo16->pchBuffer); + mmioinfo.adwInfo[0] = lpmmioinfo16->adwInfo[0]; + /* if we don't have a file name, it's likely a passed open file descriptor */ + if (!szFileName) + mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]); + mmioinfo.adwInfo[1] = lpmmioinfo16->adwInfo[1]; + mmioinfo.adwInfo[2] = lpmmioinfo16->adwInfo[2]; + mmioinfo.adwInfo[3] = lpmmioinfo16->adwInfo[3]; + + ret = MMIO_Open(szFileName, &mmioinfo, dwOpenFlags, MMIO_PROC_16); + MMIO_SetSegmentedBuffer(mmioinfo.hmmio, (SEGPTR)lpmmioinfo16->pchBuffer, FALSE); + + lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet; + lpmmioinfo16->hmmio = HMMIO_16(mmioinfo.hmmio); + } else { + ret = MMIO_Open(szFileName, NULL, dwOpenFlags, MMIO_PROC_32A); + } + return HMMIO_16(ret); +} + +/************************************************************************** + * mmioClose [MMSYSTEM.1211] + */ +MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags) +{ + MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), (SEGPTR)NULL, TRUE); + return mmioClose(HMMIO_32(hmmio), uFlags); +} + +/************************************************************************** + * mmioRead [MMSYSTEM.1212] + */ +LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch) +{ + return mmioRead(HMMIO_32(hmmio), pch, cch); +} + +/************************************************************************** + * mmioWrite [MMSYSTEM.1213] + */ +LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch) +{ + return mmioWrite(HMMIO_32(hmmio),pch,cch); +} + +/************************************************************************** + * mmioSeek [MMSYSTEM.1214] + */ +LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin) +{ + return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin); +} + +/************************************************************************** + * mmioGetInfo [MMSYSTEM.1215] + */ +MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags) +{ + MMIOINFO mmioinfo; + MMRESULT ret; + LPWINE_MMIO wm; + + TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags); + + if ((wm = MMIO_Get(HMMIO_32(hmmio))) == NULL) + return MMSYSERR_INVALHANDLE; + + ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags); + if (ret != MMSYSERR_NOERROR) return ret; + + lpmmioinfo->dwFlags = mmioinfo.dwFlags; + lpmmioinfo->fccIOProc = mmioinfo.fccIOProc; + lpmmioinfo->pIOProc = (wm->ioProc->type == MMIO_PROC_16) ? + (LPMMIOPROC16)wm->ioProc->pIOProc : NULL; + lpmmioinfo->wErrorRet = mmioinfo.wErrorRet; + lpmmioinfo->hTask = HTASK_16(mmioinfo.hTask); + lpmmioinfo->cchBuffer = mmioinfo.cchBuffer; + lpmmioinfo->pchBuffer = (void*)wm->segBuffer16; + lpmmioinfo->pchNext = (void*)(wm->segBuffer16 + (mmioinfo.pchNext - mmioinfo.pchBuffer)); + lpmmioinfo->pchEndRead = (void*)(wm->segBuffer16 + (mmioinfo.pchEndRead - mmioinfo.pchBuffer)); + lpmmioinfo->pchEndWrite = (void*)(wm->segBuffer16 + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer)); + lpmmioinfo->lBufOffset = mmioinfo.lBufOffset; + lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset; + lpmmioinfo->adwInfo[0] = mmioinfo.adwInfo[0]; + lpmmioinfo->adwInfo[1] = mmioinfo.adwInfo[1]; + lpmmioinfo->adwInfo[2] = mmioinfo.adwInfo[2]; + lpmmioinfo->adwInfo[3] = mmioinfo.adwInfo[3]; + lpmmioinfo->dwReserved1 = 0; + lpmmioinfo->dwReserved2 = 0; + lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio); + + return MMSYSERR_NOERROR; +} + +/************************************************************************** + * mmioSetInfo [MMSYSTEM.1216] + */ +MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags) +{ + MMIOINFO mmioinfo; + MMRESULT ret; + + TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags); + + ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0); + if (ret != MMSYSERR_NOERROR) return ret; + + /* check if seg and lin buffers are the same */ + if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer || + mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer)) + return MMSYSERR_INVALPARAM; + + /* check pointers coherence */ + if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer || + lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer || + lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer || + lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer || + lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer || + lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer) + return MMSYSERR_INVALPARAM; + + mmioinfo.pchNext = mmioinfo.pchBuffer + (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer); + mmioinfo.pchEndRead = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead - lpmmioinfo->pchBuffer); + mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer); + + return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags); +} + +/************************************************************************** + * mmioSetBuffer [MMSYSTEM.1217] + */ +MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, LPSTR pchBuffer, + LONG cchBuffer, UINT16 uFlags) +{ + MMRESULT ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL((DWORD)pchBuffer), + cchBuffer, uFlags); + + if (ret == MMSYSERR_NOERROR) + MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), (DWORD)pchBuffer, TRUE); + else + UnMapLS((DWORD)pchBuffer); + return ret; +} + +/************************************************************************** + * mmioFlush [MMSYSTEM.1218] + */ +MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags) +{ + return mmioFlush(HMMIO_32(hmmio), uFlags); +} + +/*********************************************************************** + * mmioAdvance [MMSYSTEM.1219] + */ +MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags) +{ + MMIOINFO mmioinfo; + LRESULT ret; + + /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which + * fields to init + */ + if (lpmmioinfo) + { + mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer); + mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext); + mmioinfo.dwFlags = lpmmioinfo->dwFlags; + mmioinfo.lBufOffset = lpmmioinfo->lBufOffset; + ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags); + } + else + ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags); + + if (ret != MMSYSERR_NOERROR) return ret; + + if (lpmmioinfo) + { + lpmmioinfo->dwFlags = mmioinfo.dwFlags; + lpmmioinfo->pchNext = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer)); + lpmmioinfo->pchEndRead = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer)); + lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer)); + lpmmioinfo->lBufOffset = mmioinfo.lBufOffset; + lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset; + } + + return MMSYSERR_NOERROR; +} + +/************************************************************************** + * mmioStringToFOURCC [MMSYSTEM.1220] + */ +FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags) +{ + return mmioStringToFOURCCA(sz, uFlags); +} + +/************************************************************************** + * mmioInstallIOProc [MMSYSTEM.1221] + */ +LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc, + DWORD dwFlags) +{ + return (LPMMIOPROC16)MMIO_InstallIOProc(fccIOProc, (LPMMIOPROC)pIOProc, + dwFlags, MMIO_PROC_16); +} + +/************************************************************************** + * mmioSendMessage [MMSYSTEM.1222] + */ +LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage, + LPARAM lParam1, LPARAM lParam2) +{ + return MMIO_SendMessage(HMMIO_32(hmmio), uMessage, + lParam1, lParam2, MMIO_PROC_16); +} + +/************************************************************************** + * mmioDescend [MMSYSTEM.1223] + */ +MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck, + const MMCKINFO* lpckParent, UINT16 uFlags) +{ + return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags); +} + +/************************************************************************** + * mmioAscend [MMSYSTEM.1224] + */ +MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags) +{ + return mmioAscend(HMMIO_32(hmmio),lpck,uFlags); +} + +/************************************************************************** + * mmioCreateChunk [MMSYSTEM.1225] + */ +MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags) +{ + return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags); +} + +/************************************************************************** + * mmioRename [MMSYSTEM.1226] + */ +MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName, + MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags) +{ + BOOL inst = FALSE; + MMRESULT ret; + MMIOINFO mmioinfo; + + if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL && + lpmmioinfo->fccIOProc == 0) { + FIXME("Can't handle this case yet\n"); + return MMSYSERR_ERROR; + } + + /* this is a bit hacky, but it'll work if we get a fourCC code or nothing. + * but a non installed ioproc without a fourcc won't do + */ + if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) { + MMIO_InstallIOProc(lpmmioinfo->fccIOProc, (LPMMIOPROC)lpmmioinfo->pIOProc, + MMIO_INSTALLPROC, MMIO_PROC_16); + inst = TRUE; + } + memset(&mmioinfo, 0, sizeof(mmioinfo)); + mmioinfo.fccIOProc = lpmmioinfo->fccIOProc; + ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags); + if (inst) { + MMIO_InstallIOProc(lpmmioinfo->fccIOProc, NULL, + MMIO_REMOVEPROC, MMIO_PROC_16); + } + return ret; +} + +/* ################################################### + * # JOYSTICK # + * ################################################### + */ + +/************************************************************************** + * joyGetNumDevs [MMSYSTEM.101] + */ +UINT16 WINAPI joyGetNumDevs16(void) +{ + return joyGetNumDevs(); +} + +/************************************************************************** + * joyGetDevCaps [MMSYSTEM.102] + */ +MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize) +{ + JOYCAPSA jca; + MMRESULT ret = joyGetDevCapsA(wID, &jca, sizeof(jca)); + + if (ret != JOYERR_NOERROR) return ret; + lpCaps->wMid = jca.wMid; + lpCaps->wPid = jca.wPid; + strcpy(lpCaps->szPname, jca.szPname); + lpCaps->wXmin = jca.wXmin; + lpCaps->wXmax = jca.wXmax; + lpCaps->wYmin = jca.wYmin; + lpCaps->wYmax = jca.wYmax; + lpCaps->wZmin = jca.wZmin; + lpCaps->wZmax = jca.wZmax; + lpCaps->wNumButtons = jca.wNumButtons; + lpCaps->wPeriodMin = jca.wPeriodMin; + lpCaps->wPeriodMax = jca.wPeriodMax; + + if (wSize >= sizeof(JOYCAPS16)) { /* Win95 extensions ? */ + lpCaps->wRmin = jca.wRmin; + lpCaps->wRmax = jca.wRmax; + lpCaps->wUmin = jca.wUmin; + lpCaps->wUmax = jca.wUmax; + lpCaps->wVmin = jca.wVmin; + lpCaps->wVmax = jca.wVmax; + lpCaps->wCaps = jca.wCaps; + lpCaps->wMaxAxes = jca.wMaxAxes; + lpCaps->wNumAxes = jca.wNumAxes; + lpCaps->wMaxButtons = jca.wMaxButtons; + strcpy(lpCaps->szRegKey, jca.szRegKey); + strcpy(lpCaps->szOEMVxD, jca.szOEMVxD); + } + + return ret; +} + +/************************************************************************** + * joyGetPosEx [MMSYSTEM.110] + */ +MMRESULT16 WINAPI joyGetPosEx16(UINT16 wID, LPJOYINFOEX lpInfo) +{ + return joyGetPosEx(wID, lpInfo); +} + +/************************************************************************** + * joyGetPos [MMSYSTEM.103] + */ +MMRESULT16 WINAPI joyGetPos16(UINT16 wID, LPJOYINFO16 lpInfo) +{ + JOYINFO ji; + MMRESULT ret; + + TRACE("(%d, %p);\n", wID, lpInfo); + + if ((ret = joyGetPos(wID, &ji)) == JOYERR_NOERROR) { + lpInfo->wXpos = ji.wXpos; + lpInfo->wYpos = ji.wYpos; + lpInfo->wZpos = ji.wZpos; + lpInfo->wButtons = ji.wButtons; + } + return ret; +} + +/************************************************************************** + * joyGetThreshold [MMSYSTEM.104] + */ +MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold) +{ + UINT t; + MMRESULT ret; + + ret = joyGetThreshold(wID, &t); + if (ret == JOYERR_NOERROR) + *lpThreshold = t; + return ret; +} + +/************************************************************************** + * joyReleaseCapture [MMSYSTEM.105] + */ +MMRESULT16 WINAPI joyReleaseCapture16(UINT16 wID) +{ + return joyReleaseCapture(wID); +} + +/************************************************************************** + * joySetCapture [MMSYSTEM.106] + */ +MMRESULT16 WINAPI joySetCapture16(HWND16 hWnd, UINT16 wID, UINT16 wPeriod, BOOL16 bChanged) +{ + return joySetCapture16(hWnd, wID, wPeriod, bChanged); +} + +/************************************************************************** + * joySetThreshold [MMSYSTEM.107] + */ +MMRESULT16 WINAPI joySetThreshold16(UINT16 wID, UINT16 wThreshold) +{ + return joySetThreshold16(wID,wThreshold); +} + +/************************************************************************** + * joySetCalibration [MMSYSTEM.109] + */ +MMRESULT16 WINAPI joySetCalibration16(UINT16 wID) +{ + FIXME("(%04X): stub.\n", wID); + return JOYERR_NOCANDO; +} diff --git a/reactos/lib/winmm/mmsystem.spec b/reactos/lib/winmm/mmsystem.spec new file mode 100644 index 00000000000..e260dd03a8f --- /dev/null +++ b/reactos/lib/winmm/mmsystem.spec @@ -0,0 +1,176 @@ +#1 pascal MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP +2 pascal sndPlaySound(ptr word) sndPlaySound16 +3 pascal PlaySound(ptr word long) PlaySound16 +5 pascal mmsystemGetVersion() mmsystemGetVersion16 +6 pascal DriverProc(long word word long long) DriverProc16 +8 pascal WMMMidiRunOnce() WMMMidiRunOnce16 +30 pascal -ret16 OutputDebugStr(str) OutputDebugStr16 +31 pascal DriverCallback(long word word word long long long) DriverCallback16 +32 pascal StackEnter() StackEnter16 +33 pascal StackLeave() StackLeave16 +34 stub MMDRVINSTALL +101 pascal joyGetNumDevs() joyGetNumDevs16 +102 pascal joyGetDevCaps(word ptr word) joyGetDevCaps16 +103 pascal joyGetPos(word ptr) joyGetPos16 +104 pascal joyGetThreshold(word ptr) joyGetThreshold16 +105 pascal joyReleaseCapture(word) joyReleaseCapture16 +106 pascal joySetCapture(word word word word) joySetCapture16 +107 pascal joySetThreshold(word word) joySetThreshold16 +109 pascal joySetCalibration(word) joySetCalibration16 +110 pascal joyGetPosEx(word ptr) joyGetPosEx16 +111 stub JOYCONFIGCHANGED +201 pascal midiOutGetNumDevs() midiOutGetNumDevs16 +202 pascal midiOutGetDevCaps(word ptr word) midiOutGetDevCaps16 +203 pascal midiOutGetErrorText(word ptr word) midiOutGetErrorText16 +204 pascal midiOutOpen(ptr word long long long) midiOutOpen16 +205 pascal midiOutClose(word) midiOutClose16 +206 pascal midiOutPrepareHeader(word segptr word) midiOutPrepareHeader16 +207 pascal midiOutUnprepareHeader(word segptr word) midiOutUnprepareHeader16 +208 pascal midiOutShortMsg(word long) midiOutShortMsg16 +209 pascal midiOutLongMsg(word segptr word) midiOutLongMsg16 +210 pascal midiOutReset(word) midiOutReset16 +211 pascal midiOutGetVolume(word ptr) midiOutGetVolume16 +212 pascal midiOutSetVolume(word long) midiOutSetVolume16 +213 pascal midiOutCachePatches(word word ptr word) midiOutCachePatches16 +214 pascal midiOutCacheDrumPatches(word word ptr word) midiOutCacheDrumPatches16 +215 pascal midiOutGetID(word ptr) midiOutGetID16 +216 pascal midiOutMessage(word word long long) midiOutMessage16 +250 pascal midiStreamProperty(word ptr long) midiStreamProperty16 +251 pascal midiStreamOpen(ptr ptr long long long long) midiStreamOpen16 +252 pascal midiStreamClose(word) midiStreamClose16 +253 pascal midiStreamPosition(word ptr word) midiStreamPosition16 +254 pascal midiStreamOut(word ptr word) midiStreamOut16 +255 pascal midiStreamPause(word) midiStreamPause16 +256 pascal midiStreamRestart(word) midiStreamRestart16 +257 pascal midiStreamStop(word) midiStreamStop16 +301 pascal midiInGetNumDevs() midiInGetNumDevs16 +302 pascal midiInGetDevCaps(word ptr word) midiInGetDevCaps16 +303 pascal midiInGetErrorText(word ptr word) midiInGetErrorText16 +304 pascal midiInOpen(ptr word long long long) midiInOpen16 +305 pascal midiInClose(word) midiInClose16 +306 pascal midiInPrepareHeader(word segptr word) midiInPrepareHeader16 +307 pascal midiInUnprepareHeader(word segptr word) midiInUnprepareHeader16 +308 pascal midiInAddBuffer(word segptr word) midiInAddBuffer16 +309 pascal midiInStart(word) midiInStart16 +310 pascal midiInStop(word) midiInStop16 +311 pascal midiInReset(word) midiInReset16 +312 pascal midiInGetID(word ptr) midiInGetID16 +313 pascal midiInMessage(word word long long) midiInMessage16 +350 pascal auxGetNumDevs() auxGetNumDevs16 +351 pascal auxGetDevCaps(word ptr word) auxGetDevCaps16 +352 pascal auxGetVolume(word ptr) auxGetVolume16 +353 pascal auxSetVolume(word long) auxSetVolume16 +354 pascal auxOutMessage(word word long long) auxOutMessage16 +401 pascal waveOutGetNumDevs() waveOutGetNumDevs16 +402 pascal waveOutGetDevCaps(word ptr word) waveOutGetDevCaps16 +403 pascal waveOutGetErrorText(word ptr word) waveOutGetErrorText16 +404 pascal waveOutOpen(ptr word ptr long long long) waveOutOpen16 +405 pascal waveOutClose(word) waveOutClose16 +406 pascal waveOutPrepareHeader(word segptr word) waveOutPrepareHeader16 +407 pascal waveOutUnprepareHeader(word segptr word) waveOutUnprepareHeader16 +408 pascal waveOutWrite(word segptr word) waveOutWrite16 +409 pascal waveOutPause(word) waveOutPause16 +410 pascal waveOutRestart(word) waveOutRestart16 +411 pascal waveOutReset(word) waveOutReset16 +412 pascal waveOutGetPosition(word ptr word) waveOutGetPosition16 +413 pascal waveOutGetPitch(word ptr) waveOutGetPitch16 +414 pascal waveOutSetPitch(word long) waveOutSetPitch16 +415 pascal waveOutGetVolume(word ptr) waveOutGetVolume16 +416 pascal waveOutSetVolume(word long) waveOutSetVolume16 +417 pascal waveOutGetPlaybackRate(word ptr) waveOutGetPlaybackRate16 +418 pascal waveOutSetPlaybackRate(word long) waveOutSetPlaybackRate16 +419 pascal waveOutBreakLoop(word) waveOutBreakLoop16 +420 pascal waveOutGetID(word ptr) waveOutGetID16 +421 pascal waveOutMessage(word word long long) waveOutMessage16 +501 pascal waveInGetNumDevs() waveInGetNumDevs16 +502 pascal waveInGetDevCaps(word ptr word) waveInGetDevCaps16 +503 pascal waveInGetErrorText(word ptr word) waveInGetErrorText16 +504 pascal waveInOpen(ptr word ptr long long long) waveInOpen16 +505 pascal waveInClose(word) waveInClose16 +506 pascal waveInPrepareHeader(word segptr word) waveInPrepareHeader16 +507 pascal waveInUnprepareHeader(word segptr word) waveInUnprepareHeader16 +508 pascal waveInAddBuffer(word segptr word) waveInAddBuffer16 +509 pascal waveInStart(word) waveInStart16 +510 pascal waveInStop(word) waveInStop16 +511 pascal waveInReset(word) waveInReset16 +512 pascal waveInGetPosition(word ptr word) waveInGetPosition16 +513 pascal waveInGetID(word ptr) waveInGetID16 +514 pascal waveInMessage(word word long long) waveInMessage16 +601 pascal timeGetSystemTime(ptr word) timeGetSystemTime16 +602 pascal timeSetEvent(word word segptr long word) timeSetEvent16 +603 pascal timeKillEvent(word) timeKillEvent16 +604 pascal timeGetDevCaps(ptr word) timeGetDevCaps16 +605 pascal timeBeginPeriod(word) timeBeginPeriod16 +606 pascal timeEndPeriod(word) timeEndPeriod16 +607 pascal timeGetTime() timeGetTime +701 pascal mciSendCommand(word word long long) mciSendCommand16 +702 pascal mciSendString(str ptr word word) mciSendString16 +703 pascal mciGetDeviceID(ptr) mciGetDeviceID16 +705 pascal mciLoadCommandResource(word str word) mciLoadCommandResource16 +706 pascal mciGetErrorString(long ptr word) mciGetErrorString16 +707 pascal mciSetDriverData(word long) mciSetDriverData16 +708 pascal mciGetDriverData(word) mciGetDriverData16 +710 pascal mciDriverYield(word) mciDriverYield16 +711 pascal mciDriverNotify(word word word) mciDriverNotify16 +712 pascal mciExecute(ptr) mciExecute +713 pascal mciFreeCommandResource(word) mciFreeCommandResource16 +714 pascal mciSetYieldProc(word ptr long) mciSetYieldProc16 +715 pascal mciGetDeviceIDFromElementID(long ptr) mciGetDeviceIDFromElementID16 +716 pascal mciGetYieldProc(word ptr) mciGetYieldProc16 +717 pascal mciGetCreatorTask(word) mciGetCreatorTask16 +800 pascal mixerGetNumDevs() mixerGetNumDevs16 +801 pascal mixerGetDevCaps(word ptr word) mixerGetDevCaps16 +802 pascal mixerOpen(ptr word long long long) mixerOpen16 +803 pascal mixerClose(word) mixerClose16 +804 pascal mixerMessage(word word long long) mixerMessage16 +805 pascal mixerGetLineInfo(word ptr long) mixerGetLineInfo16 +806 pascal mixerGetID(word ptr long) mixerGetID16 +807 pascal mixerGetLineControls(word ptr long) mixerGetLineControls16 +808 pascal mixerGetControlDetails(word ptr long) mixerGetControlDetails16 +809 pascal mixerSetControlDetails(word ptr long) mixerSetControlDetails16 +900 pascal mmTaskCreate(long ptr long) mmTaskCreate16 +902 pascal mmTaskBlock(word) mmTaskBlock16 +903 pascal mmTaskSignal(word) mmTaskSignal16 +904 pascal -ret16 mmGetCurrentTask() mmGetCurrentTask16 +905 pascal mmTaskYield() mmTaskYield16 +1100 pascal DrvOpen(str str long) DrvOpen16 +1101 pascal DrvClose(word long long) DrvClose16 +1102 pascal DrvSendMessage(word word long long) DrvSendMessage16 +1103 pascal DrvGetModuleHandle(word) DrvGetModuleHandle16 +1104 pascal DrvDefDriverProc(long word word long long) DrvDefDriverProc16 +1120 pascal mmThreadCreate(segptr ptr long long) mmThreadCreate16 +1121 pascal mmThreadSignal(word) mmThreadSignal16 +1122 pascal mmThreadBlock(word) mmThreadBlock16 +1123 pascal mmThreadIsCurrent(word) mmThreadIsCurrent16 +1124 pascal mmThreadIsValid(word) mmThreadIsValid16 +1125 pascal mmThreadGetTask(word) mmThreadGetTask16 +1150 pascal mmShowMMCPLPropertySheet(word str str str) mmShowMMCPLPropertySheet16 + +1210 pascal mmioOpen(str ptr long) mmioOpen16 +1211 pascal mmioClose(word word) mmioClose16 +1212 pascal mmioRead(word ptr long) mmioRead16 +1213 pascal mmioWrite(word ptr long) mmioWrite16 +1214 pascal mmioSeek(word long word) mmioSeek16 +1215 pascal mmioGetInfo(word ptr word) mmioGetInfo16 +1216 pascal mmioSetInfo(word ptr word) mmioSetInfo16 +1217 pascal mmioSetBuffer(word segptr long word) mmioSetBuffer16 +1218 pascal mmioFlush(word word) mmioFlush16 +1219 pascal mmioAdvance(word ptr word) mmioAdvance16 +1220 pascal mmioStringToFOURCC(str word) mmioStringToFOURCC16 +1221 pascal mmioInstallIOProc(long ptr long) mmioInstallIOProc16 +1222 pascal mmioSendMessage(word word long long) mmioSendMessage16 +1223 pascal mmioDescend(word ptr ptr word) mmioDescend16 +1224 pascal mmioAscend(word ptr word) mmioAscend16 +1225 pascal mmioCreateChunk(word ptr word) mmioCreateChunk16 +1226 pascal mmioRename(ptr ptr ptr long) mmioRename16 + +#2000 stub WINMMF_THUNKDATA16 +#2001 stub RING3_DEVLOADER +#2002 stub WINMMTILEBUFFER +#2003 stub WINMMUNTILEBUFFER +#2005 stub MCIGETTHUNKTABLE +#2006 stub WINMMSL_THUNKDATA16 + +2046 pascal DllEntryPoint(long word word word long word) MMSYSTEM_LibMain +# these are Wine only exported functions. Is there another way to do it ? +2047 pascal __wine_mmThreadEntryPoint(long) WINE_mmThreadEntryPoint diff --git a/reactos/lib/winmm/playsound.c b/reactos/lib/winmm/playsound.c index 6854c65b78d..e2e928b8dc8 100644 --- a/reactos/lib/winmm/playsound.c +++ b/reactos/lib/winmm/playsound.c @@ -190,6 +190,7 @@ static void PlaySound_Free(WINE_PLAYSOUND* wps) if (WINMM_IData->lpPlaySound == NULL) SetEvent(WINMM_IData->psLastEvent); LeaveCriticalSection(&WINMM_IData->cs); if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound); + if (wps->hThread) CloseHandle(wps->hThread); HeapFree(GetProcessHeap(), 0, wps); } @@ -456,9 +457,12 @@ BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSound, BO if (fdwSound & SND_ASYNC) { DWORD id; + HANDLE handle; wps->bLoop = (fdwSound & SND_LOOP) ? TRUE : FALSE; - if (CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id) != 0) + if ((handle = CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id)) != 0) { + wps->hThread = handle; return TRUE; + } } else return proc_PlaySound(wps); diff --git a/reactos/lib/winmm/sound.spec b/reactos/lib/winmm/sound.spec new file mode 100644 index 00000000000..586af4064f3 --- /dev/null +++ b/reactos/lib/winmm/sound.spec @@ -0,0 +1,18 @@ +1 pascal -ret16 OpenSound() OpenSound16 +2 pascal -ret16 CloseSound() CloseSound16 +3 pascal -ret16 SetVoiceQueueSize(word word) SetVoiceQueueSize16 +4 pascal -ret16 SetVoiceNote(word word word word) SetVoiceNote16 +5 pascal -ret16 SetVoiceAccent(word word word word word) SetVoiceAccent16 +6 pascal -ret16 SetVoiceEnvelope(word word word) SetVoiceEnvelope16 +7 pascal -ret16 SetSoundNoise(word word) SetSoundNoise16 +8 pascal -ret16 SetVoiceSound(word long word) SetVoiceSound16 +9 pascal -ret16 StartSound() StartSound16 +10 pascal -ret16 StopSound() StopSound16 +11 pascal -ret16 WaitSoundState(word) WaitSoundState16 +12 pascal -ret16 SyncAllVoices() SyncAllVoices16 +13 pascal -ret16 CountVoiceNotes(word) CountVoiceNotes16 +14 pascal GetThresholdEvent() GetThresholdEvent16 +15 pascal -ret16 GetThresholdStatus() GetThresholdStatus16 +16 pascal -ret16 SetVoiceThreshold(word word) SetVoiceThreshold16 +17 pascal -ret16 DoBeep() DoBeep16 +18 stub MYOPENSOUND # W1.1, W2.0 diff --git a/reactos/lib/winmm/sound16.c b/reactos/lib/winmm/sound16.c new file mode 100644 index 00000000000..46306d8b1f0 --- /dev/null +++ b/reactos/lib/winmm/sound16.c @@ -0,0 +1,184 @@ +/* + * 16-bit sound support + * + * Copyright Robert J. Amstadt, 1993 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "windef.h" +#include "winbase.h" +#include "wine/windef16.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(sound); + +/*********************************************************************** + * OpenSound (SOUND.1) + */ +INT16 WINAPI OpenSound16(void) +{ + FIXME("(void): stub\n"); + return -1; +} + +/*********************************************************************** + * CloseSound (SOUND.2) + */ +void WINAPI CloseSound16(void) +{ + FIXME("(void): stub\n"); +} + +/*********************************************************************** + * SetVoiceQueueSize (SOUND.3) + */ +INT16 WINAPI SetVoiceQueueSize16(INT16 nVoice, INT16 nBytes) +{ + FIXME("(%d,%d): stub\n",nVoice,nBytes); + return 0; +} + +/*********************************************************************** + * SetVoiceNote (SOUND.4) + */ +INT16 WINAPI SetVoiceNote16(INT16 nVoice, INT16 nValue, INT16 nLength, + INT16 nCdots) +{ + FIXME("(%d,%d,%d,%d): stub\n",nVoice,nValue,nLength,nCdots); + return 0; +} + +/*********************************************************************** + * SetVoiceAccent (SOUND.5) + */ +INT16 WINAPI SetVoiceAccent16(INT16 nVoice, INT16 nTempo, INT16 nVolume, + INT16 nMode, INT16 nPitch) +{ + FIXME("(%d,%d,%d,%d,%d): stub\n", nVoice, nTempo, + nVolume, nMode, nPitch); + return 0; +} + +/*********************************************************************** + * SetVoiceEnvelope (SOUND.6) + */ +INT16 WINAPI SetVoiceEnvelope16(INT16 nVoice, INT16 nShape, INT16 nRepeat) +{ + FIXME("(%d,%d,%d): stub\n",nVoice,nShape,nRepeat); + return 0; +} + +/*********************************************************************** + * SetSoundNoise (SOUND.7) + */ +INT16 WINAPI SetSoundNoise16(INT16 nSource, INT16 nDuration) +{ + FIXME("(%d,%d): stub\n",nSource,nDuration); + return 0; +} + +/*********************************************************************** + * SetVoiceSound (SOUND.8) + */ +INT16 WINAPI SetVoiceSound16(INT16 nVoice, DWORD lFrequency, INT16 nDuration) +{ + FIXME("(%d, %ld, %d): stub\n",nVoice,lFrequency, nDuration); + return 0; +} + +/*********************************************************************** + * StartSound (SOUND.9) + */ +INT16 WINAPI StartSound16(void) +{ + return 0; +} + +/*********************************************************************** + * StopSound (SOUND.10) + */ +INT16 WINAPI StopSound16(void) +{ + return 0; +} + +/*********************************************************************** + * WaitSoundState (SOUND.11) + */ +INT16 WINAPI WaitSoundState16(INT16 x) +{ + FIXME("(%d): stub\n", x); + return 0; +} + +/*********************************************************************** + * SyncAllVoices (SOUND.12) + */ +INT16 WINAPI SyncAllVoices16(void) +{ + FIXME("(void): stub\n"); + return 0; +} + +/*********************************************************************** + * CountVoiceNotes (SOUND.13) + */ +INT16 WINAPI CountVoiceNotes16(INT16 x) +{ + FIXME("(%d): stub\n", x); + return 0; +} + +/*********************************************************************** + * GetThresholdEvent (SOUND.14) + */ +LPINT16 WINAPI GetThresholdEvent16(void) +{ + FIXME("(void): stub\n"); + return NULL; +} + +/*********************************************************************** + * GetThresholdStatus (SOUND.15) + */ +INT16 WINAPI GetThresholdStatus16(void) +{ + FIXME("(void): stub\n"); + return 0; +} + +/*********************************************************************** + * SetVoiceThreshold (SOUND.16) + */ +INT16 WINAPI SetVoiceThreshold16(INT16 a, INT16 b) +{ + FIXME("(%d,%d): stub\n", a, b); + return 0; +} + +/*********************************************************************** + * DoBeep (SOUND.17) + */ +void WINAPI DoBeep16(void) +{ + FIXME("(void): stub!\n"); +} + + + + diff --git a/reactos/lib/winmm/time.c b/reactos/lib/winmm/time.c index de6091871f4..ae2446172ed 100644 --- a/reactos/lib/winmm/time.c +++ b/reactos/lib/winmm/time.c @@ -42,6 +42,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(mmtime); +static HANDLE TIME_hMMTimer; +static LPWINE_TIMERENTRY TIME_TimersList; +static HANDLE TIME_hKillEvent; +DWORD WINMM_SysTimeMS; + /* * FIXME * We're using "1" as the mininum resolution to the timer, @@ -90,15 +95,18 @@ static void TIME_TriggerCallBack(LPWINE_TIMERENTRY lpTimer) */ static void CALLBACK TIME_MMSysTimeCallback(LPWINE_MM_IDATA iData) { - LPWINE_TIMERENTRY lpTimer, lpNextTimer; - DWORD delta = GetTickCount() - iData->mmSysTimeMS; +static int nSizeLpTimers; +static LPWINE_TIMERENTRY lpTimers; + + LPWINE_TIMERENTRY timer, *ptimer, *next_ptimer; + DWORD delta = GetTickCount() - WINMM_SysTimeMS; int idx; TRACE("Time delta: %ld\n", delta); while (delta >= MMSYSTIME_MININTERVAL) { delta -= MMSYSTIME_MININTERVAL; - iData->mmSysTimeMS += MMSYSTIME_MININTERVAL; + WINMM_SysTimeMS += MMSYSTIME_MININTERVAL; /* since timeSetEvent() and timeKillEvent() can be called * from 16 bit code, there are cases where win16 lock is @@ -109,48 +117,52 @@ static void CALLBACK TIME_MMSysTimeCallback(LPWINE_MM_IDATA iData) * situation). * To cope with that, we just copy the WINE_TIMERENTRY struct * that need to trigger the callback, and call it without the - * mm timer crit sect locked. The bad side of this - * implementation is that, in some cases, the callback may be - * invoked *after* a timer has been destroyed... - * EPP 99/07/13 + * mm timer crit sect locked. + * the hKillTimeEvent is used to mark the section where we + * handle the callbacks so we can do synchronous kills. + * EPP 99/07/13, updated 04/01/10 */ idx = 0; EnterCriticalSection(&iData->cs); - for (lpTimer = iData->lpTimerList; lpTimer != NULL; ) { - lpNextTimer = lpTimer->lpNext; - if (lpTimer->uCurTime < MMSYSTIME_MININTERVAL) { + for (ptimer = &TIME_TimersList; *ptimer != NULL; ) { + timer = *ptimer; + next_ptimer = &timer->lpNext; + if (timer->uCurTime < MMSYSTIME_MININTERVAL) { /* since lpTimer->wDelay is >= MININTERVAL, wCurTime value * shall be correct (>= 0) */ - lpTimer->uCurTime += lpTimer->wDelay - MMSYSTIME_MININTERVAL; - if (lpTimer->lpFunc) { - if (idx == iData->nSizeLpTimers) { - if (iData->lpTimers) - iData->lpTimers = (LPWINE_TIMERENTRY) - HeapReAlloc(GetProcessHeap(), 0, - iData->lpTimers, - ++iData->nSizeLpTimers * sizeof(WINE_TIMERENTRY)); + timer->uCurTime += timer->wDelay - MMSYSTIME_MININTERVAL; + if (timer->lpFunc) { + if (idx == nSizeLpTimers) { + if (lpTimers) + lpTimers = (LPWINE_TIMERENTRY) + HeapReAlloc(GetProcessHeap(), 0, lpTimers, + ++nSizeLpTimers * sizeof(WINE_TIMERENTRY)); else - iData->lpTimers = (LPWINE_TIMERENTRY) + lpTimers = (LPWINE_TIMERENTRY) HeapAlloc(GetProcessHeap(), 0, - ++iData->nSizeLpTimers * sizeof(WINE_TIMERENTRY)); + ++nSizeLpTimers * sizeof(WINE_TIMERENTRY)); } - iData->lpTimers[idx++] = *lpTimer; + lpTimers[idx++] = *timer; } /* TIME_ONESHOT is defined as 0 */ - if (!(lpTimer->wFlags & TIME_PERIODIC)) - timeKillEvent(lpTimer->wTimerID); + if (!(timer->wFlags & TIME_PERIODIC)) + { + /* unlink timer from timers list */ + *ptimer = *next_ptimer; + HeapFree(GetProcessHeap(), 0, timer); + } } else { - lpTimer->uCurTime -= MMSYSTIME_MININTERVAL; + timer->uCurTime -= MMSYSTIME_MININTERVAL; } - lpTimer = lpNextTimer; + ptimer = next_ptimer; } + if (TIME_hKillEvent) ResetEvent(TIME_hKillEvent); LeaveCriticalSection(&iData->cs); - while (idx > 0) { - TIME_TriggerCallBack(&iData->lpTimers[--idx]); - } + while (idx > 0) TIME_TriggerCallBack(&lpTimers[--idx]); + if (TIME_hKillEvent) SetEvent(TIME_hKillEvent); } } @@ -160,12 +172,13 @@ static void CALLBACK TIME_MMSysTimeCallback(LPWINE_MM_IDATA iData) static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg) { LPWINE_MM_IDATA iData = (LPWINE_MM_IDATA)arg; - volatile HANDLE *pActive = (volatile HANDLE *)&iData->hMMTimer; + volatile HANDLE *pActive = (volatile HANDLE *)&TIME_hMMTimer; DWORD last_time, cur_time; #ifndef __REACTOS__ usleep(MMSYSTIME_STDINTERVAL * 1000); #endif /* __REACTOS__ */ + last_time = GetTickCount(); while (*pActive) { TIME_MMSysTimeCallback(iData); @@ -188,10 +201,10 @@ void TIME_MMTimeStart(void) * mm timers are active, but this would require to keep mmSysTimeMS up-to-date * without being incremented within the service thread callback. */ - if (!WINMM_IData->hMMTimer) { - WINMM_IData->mmSysTimeMS = GetTickCount(); - WINMM_IData->lpTimerList = NULL; - WINMM_IData->hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, WINMM_IData, 0, NULL); + if (!TIME_hMMTimer) { + WINMM_SysTimeMS = GetTickCount(); + TIME_TimersList = NULL; + TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, WINMM_IData, 0, NULL); } } @@ -200,9 +213,10 @@ void TIME_MMTimeStart(void) */ void TIME_MMTimeStop(void) { - if (WINMM_IData->hMMTimer) { - HANDLE hMMTimer = WINMM_IData->hMMTimer; - WINMM_IData->hMMTimer = 0; + /* FIXME: in the worst case, we're going to wait 65 seconds here :-( */ + if (TIME_hMMTimer) { + HANDLE hMMTimer = TIME_hMMTimer; + TIME_hMMTimer = 0; WaitForSingleObject(hMMTimer, INFINITE); CloseHandle(hMMTimer); } @@ -218,7 +232,7 @@ MMRESULT WINAPI timeGetSystemTime(LPMMTIME lpTime, UINT wSize) if (wSize >= sizeof(*lpTime)) { TIME_MMTimeStart(); lpTime->wType = TIME_MS; - lpTime->u.ms = WINMM_IData->mmSysTimeMS; + lpTime->u.ms = WINMM_SysTimeMS; TRACE("=> %lu\n", lpTime->u.ms); } @@ -256,12 +270,15 @@ WORD TIME_SetEventInternal(UINT wDelay, UINT wResol, EnterCriticalSection(&WINMM_IData->cs); - for (lpTimer = WINMM_IData->lpTimerList; lpTimer != NULL; lpTimer = lpTimer->lpNext) { + if ((wFlags & TIME_KILL_SYNCHRONOUS) && !TIME_hKillEvent) + TIME_hKillEvent = CreateEventW(NULL, TRUE, TRUE, NULL); + + for (lpTimer = TIME_TimersList; lpTimer != NULL; lpTimer = lpTimer->lpNext) { wNewID = max(wNewID, lpTimer->wTimerID); } - lpNewTimer->lpNext = WINMM_IData->lpTimerList; - WINMM_IData->lpTimerList = lpNewTimer; + lpNewTimer->lpNext = TIME_TimersList; + TIME_TimersList = lpNewTimer; lpNewTimer->wTimerID = wNewID + 1; LeaveCriticalSection(&WINMM_IData->cs); @@ -275,7 +292,7 @@ WORD TIME_SetEventInternal(UINT wDelay, UINT wResol, * timeSetEvent [WINMM.@] */ MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc, - DWORD dwUser, UINT wFlags) + DWORD_PTR dwUser, UINT wFlags) { if (wFlags & WINE_TIMER_IS32) WARN("Unknown windows flag... wine internally used.. ooch\n"); @@ -289,31 +306,30 @@ MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc, */ MMRESULT WINAPI timeKillEvent(UINT wID) { - LPWINE_TIMERENTRY* lpTimer; - MMRESULT ret = MMSYSERR_INVALPARAM; + LPWINE_TIMERENTRY lpSelf = NULL, *lpTimer; TRACE("(%u)\n", wID); EnterCriticalSection(&WINMM_IData->cs); /* remove WINE_TIMERENTRY from list */ - for (lpTimer = &WINMM_IData->lpTimerList; *lpTimer; lpTimer = &(*lpTimer)->lpNext) { + for (lpTimer = &TIME_TimersList; *lpTimer; lpTimer = &(*lpTimer)->lpNext) { if (wID == (*lpTimer)->wTimerID) { + lpSelf = *lpTimer; + /* unlink timer of id 'wID' */ + *lpTimer = (*lpTimer)->lpNext; break; } } LeaveCriticalSection(&WINMM_IData->cs); - if (*lpTimer) { - LPWINE_TIMERENTRY lpTemp = *lpTimer; - - /* unlink timer of id 'wID' */ - *lpTimer = (*lpTimer)->lpNext; - HeapFree(GetProcessHeap(), 0, lpTemp); - ret = TIMERR_NOERROR; - } else { - WARN("wID=%u is not a valid timer ID\n", wID); + if (!lpSelf) + { + WARN("wID=%u is not a valid timer ID\n", wID); + return MMSYSERR_INVALPARAM; } - - return ret; + if (lpSelf->wFlags & TIME_KILL_SYNCHRONOUS) + WaitForSingleObject(TIME_hKillEvent, INFINITE); + HeapFree(GetProcessHeap(), 0, lpSelf); + return TIMERR_NOERROR; } /************************************************************************** @@ -365,5 +381,5 @@ DWORD WINAPI timeGetTime(void) if (pFnReleaseThunkLock) pFnReleaseThunkLock(&count); TIME_MMTimeStart(); if (pFnRestoreThunkLock) pFnRestoreThunkLock(count); - return WINMM_IData->mmSysTimeMS; + return WINMM_SysTimeMS; } diff --git a/reactos/lib/winmm/winemm.h b/reactos/lib/winmm/winemm.h index 14de7f75423..1447cd1ba4d 100644 --- a/reactos/lib/winmm/winemm.h +++ b/reactos/lib/winmm/winemm.h @@ -22,10 +22,6 @@ ***************************************************************************** */ -#include "config.h" -#include "wine/port.h" -#include "wine/debug.h" - #include #include "windef.h" @@ -74,7 +70,7 @@ 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_msgFunc32 fnMessage32; /* pointer to function */ WINEMM_msgFunc16 fnMessage16; } u; } WINE_MM_DRIVER_PART; @@ -197,6 +193,7 @@ typedef struct tagWINE_PLAYSOUND { LPCWSTR pszSound; HMODULE hMod; DWORD fdwSound; + HANDLE hThread; struct tagWINE_PLAYSOUND* lpNext; } WINE_PLAYSOUND, *LPWINE_PLAYSOUND; @@ -205,12 +202,6 @@ typedef struct tagWINE_MM_IDATA { HANDLE hWinMM32Instance; HANDLE hWinMM16Instance; CRITICAL_SECTION cs; - /* mm timer part */ - HANDLE hMMTimer; - DWORD mmSysTimeMS; - LPWINE_TIMERENTRY lpTimerList; - int nSizeLpTimers; - LPWINE_TIMERENTRY lpTimers; /* mci part */ LPWINE_MCIDRIVER lpMciDrvs; /* low level drivers (unused yet) */ @@ -246,7 +237,7 @@ 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); +DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2, BOOL bFrom32); UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1, DWORD dwParam2); BOOL MMDRV_Is32(unsigned int); void MMDRV_InstallMap(unsigned int, MMDRV_MAPFUNC, MMDRV_UNMAPFUNC, @@ -294,6 +285,7 @@ void TIME_MMTimeStop(void); /* Global variables */ extern LPWINE_MM_IDATA WINMM_IData; +extern DWORD WINMM_SysTimeMS; /* pointers to 16 bit functions (if sibling MMSYSTEM.DLL is loaded * NULL otherwise diff --git a/reactos/lib/winmm/winemm16.h b/reactos/lib/winmm/winemm16.h new file mode 100644 index 00000000000..3bb1780fecf --- /dev/null +++ b/reactos/lib/winmm/winemm16.h @@ -0,0 +1,59 @@ +/* -*- tab-width: 8; c-basic-offset: 4 -*- */ + +/***************************************************************************** + * Copyright 1998, Luiz Otavio L. Zorzella + * 1999, Eric Pouech + * + * Purpose: multimedia declarations (internal to WINMM & MMSYSTEM DLLs) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + ***************************************************************************** + */ +#include "winemm.h" +#include "wine/mmsystem16.h" +#include "wownt32.h" + +/* mmsystem (16 bit files) only functions */ +void MMDRV_Init16(void); +void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16); +void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32); + +typedef LONG (*MCIPROC16)(DWORD, HDRVR16, WORD, DWORD, DWORD); + +/* HANDLE16 -> HANDLE conversions */ +#define HDRVR_32(h16) ((HDRVR)(ULONG_PTR)(h16)) +#define HMIDI_32(h16) ((HMIDI)(ULONG_PTR)(h16)) +#define HMIDIIN_32(h16) ((HMIDIIN)(ULONG_PTR)(h16)) +#define HMIDIOUT_32(h16) ((HMIDIOUT)(ULONG_PTR)(h16)) +#define HMIDISTRM_32(h16) ((HMIDISTRM)(ULONG_PTR)(h16)) +#define HMIXER_32(h16) ((HMIXER)(ULONG_PTR)(h16)) +#define HMIXEROBJ_32(h16) ((HMIXEROBJ)(ULONG_PTR)(h16)) +#define HMMIO_32(h16) ((HMMIO)(ULONG_PTR)(h16)) +#define HWAVE_32(h16) ((HWAVE)(ULONG_PTR)(h16)) +#define HWAVEIN_32(h16) ((HWAVEIN)(ULONG_PTR)(h16)) +#define HWAVEOUT_32(h16) ((HWAVEOUT)(ULONG_PTR)(h16)) + +/* HANDLE -> HANDLE16 conversions */ +#define HDRVR_16(h32) (LOWORD(h32)) +#define HMIDI_16(h32) (LOWORD(h32)) +#define HMIDIIN_16(h32) (LOWORD(h32)) +#define HMIDIOUT_16(h32) (LOWORD(h32)) +#define HMIDISTRM_16(h32) (LOWORD(h32)) +#define HMIXER_16(h32) (LOWORD(h32)) +#define HMIXEROBJ_16(h32) (LOWORD(h32)) +#define HMMIO_16(h32) (LOWORD(h32)) +#define HWAVE_16(h32) (LOWORD(h32)) +#define HWAVEIN_16(h32) (LOWORD(h32)) +#define HWAVEOUT_16(h32) (LOWORD(h32)) diff --git a/reactos/lib/winmm/winmm.c b/reactos/lib/winmm/winmm.c index f8b8e74dd82..7fe006fd468 100644 --- a/reactos/lib/winmm/winmm.c +++ b/reactos/lib/winmm/winmm.c @@ -28,15 +28,11 @@ * 99/9 added support for loadable low level drivers */ -#include "config.h" -#include "wine/port.h" - #include #include #define NONAMELESSUNION #define NONAMELESSSTRUCT -#define NOGDI #include "windef.h" #include "winbase.h" #include "mmsystem.h" @@ -45,7 +41,7 @@ #include "winreg.h" #include "winternl.h" #include "winemm.h" -//#include "wownt32.h" +#include "wownt32.h" #include "wine/debug.h" @@ -129,10 +125,12 @@ BOOL WINMM_CheckForMMSystem(void) loaded = -1; if (h) { +#ifndef __REACTOS__ pGetModuleHandle16 = (void*)GetProcAddress(h, "GetModuleHandle16"); pLoadLibrary16 = (void*)GetProcAddress(h, "LoadLibrary16"); if (pGetModuleHandle16 && pLoadLibrary16 && (pGetModuleHandle16("MMSYSTEM.DLL") || pLoadLibrary16("MMSYSTEM.DLL"))) +#endif /* __REACTOS__ */ loaded = 1; } } @@ -236,7 +234,7 @@ UINT WINAPI mixerGetNumDevs(void) /************************************************************************** * mixerGetDevCapsA [WINMM.@] */ -UINT WINAPI mixerGetDevCapsA(UINT uDeviceID, LPMIXERCAPSA lpCaps, UINT uSize) +UINT WINAPI mixerGetDevCapsA(UINT_PTR uDeviceID, LPMIXERCAPSA lpCaps, UINT uSize) { LPWINE_MLD wmld; @@ -245,13 +243,13 @@ UINT WINAPI mixerGetDevCapsA(UINT uDeviceID, LPMIXERCAPSA lpCaps, UINT uSize) if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIXER, TRUE)) == NULL) return MMSYSERR_BADDEVICEID; - return MMDRV_Message(wmld, MXDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE); + return MMDRV_Message(wmld, MXDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize, TRUE); } /************************************************************************** * mixerGetDevCapsW [WINMM.@] */ -UINT WINAPI mixerGetDevCapsW(UINT uDeviceID, LPMIXERCAPSW lpCaps, UINT uSize) +UINT WINAPI mixerGetDevCapsW(UINT_PTR uDeviceID, LPMIXERCAPSW lpCaps, UINT uSize) { MIXERCAPSA micA; UINT ret = mixerGetDevCapsA(uDeviceID, &micA, sizeof(micA)); @@ -270,8 +268,8 @@ UINT WINAPI mixerGetDevCapsW(UINT uDeviceID, LPMIXERCAPSW lpCaps, UINT uSize) return ret; } -UINT MIXER_Open(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback, - DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32) +UINT MIXER_Open(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback, + DWORD_PTR dwInstance, DWORD fdwOpen, BOOL bFrom32) { HANDLE hMix; LPWINE_MLD wmld; @@ -304,8 +302,8 @@ UINT MIXER_Open(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback, /************************************************************************** * mixerOpen [WINMM.@] */ -UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback, - DWORD dwInstance, DWORD fdwOpen) +UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback, + DWORD_PTR dwInstance, DWORD fdwOpen) { return MIXER_Open(lphMix, uDeviceID, dwCallback, dwInstance, fdwOpen, TRUE); } @@ -363,7 +361,7 @@ UINT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA if (lpmcdA == NULL || lpmcdA->cbStruct != sizeof(*lpmcdA)) return MMSYSERR_INVALPARAM; - return MMDRV_Message(&lpwm->mld, MXDM_GETCONTROLDETAILS, (DWORD)lpmcdA, + return MMDRV_Message(&lpwm->mld, MXDM_GETCONTROLDETAILS, (DWORD_PTR)lpmcdA, fdwDetails, TRUE); } @@ -441,7 +439,7 @@ UINT WINAPI mixerGetLineControlsA(HMIXEROBJ hmix, LPMIXERLINECONTROLSA lpmlcA, if (lpmlcA == NULL || lpmlcA->cbStruct != sizeof(*lpmlcA)) return MMSYSERR_INVALPARAM; - return MMDRV_Message(&lpwm->mld, MXDM_GETLINECONTROLS, (DWORD)lpmlcA, + return MMDRV_Message(&lpwm->mld, MXDM_GETLINECONTROLS, (DWORD_PTR)lpmlcA, fdwControls, TRUE); } @@ -518,7 +516,7 @@ UINT WINAPI mixerGetLineInfoA(HMIXEROBJ hmix, LPMIXERLINEA lpmliW, DWORD fdwInfo if ((lpwm = MIXER_GetDev(hmix, fdwInfo)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(&lpwm->mld, MXDM_GETLINEINFO, (DWORD)lpmliW, + return MMDRV_Message(&lpwm->mld, MXDM_GETLINEINFO, (DWORD_PTR)lpmliW, fdwInfo, TRUE); } @@ -601,14 +599,14 @@ UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA, if ((lpwm = MIXER_GetDev(hmix, fdwDetails)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(&lpwm->mld, MXDM_SETCONTROLDETAILS, (DWORD)lpmcdA, + return MMDRV_Message(&lpwm->mld, MXDM_SETCONTROLDETAILS, (DWORD_PTR)lpmcdA, fdwDetails, TRUE); } /************************************************************************** * mixerMessage [WINMM.@] */ -UINT WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD dwParam1, DWORD dwParam2) +UINT WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { LPWINE_MLD wmld; @@ -632,7 +630,7 @@ UINT WINAPI auxGetNumDevs(void) /************************************************************************** * auxGetDevCapsW [WINMM.@] */ -UINT WINAPI auxGetDevCapsW(UINT uDeviceID, LPAUXCAPSW lpCaps, UINT uSize) +UINT WINAPI auxGetDevCapsW(UINT_PTR uDeviceID, LPAUXCAPSW lpCaps, UINT uSize) { AUXCAPSA acA; UINT ret = auxGetDevCapsA(uDeviceID, &acA, sizeof(acA)); @@ -654,7 +652,7 @@ UINT WINAPI auxGetDevCapsW(UINT uDeviceID, LPAUXCAPSW lpCaps, UINT uSize) /************************************************************************** * auxGetDevCapsA [WINMM.@] */ -UINT WINAPI auxGetDevCapsA(UINT uDeviceID, LPAUXCAPSA lpCaps, UINT uSize) +UINT WINAPI auxGetDevCapsA(UINT_PTR uDeviceID, LPAUXCAPSA lpCaps, UINT uSize) { LPWINE_MLD wmld; @@ -664,7 +662,7 @@ UINT WINAPI auxGetDevCapsA(UINT uDeviceID, LPAUXCAPSA lpCaps, UINT uSize) if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_AUX, TRUE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE); + return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize, TRUE); } /************************************************************************** @@ -678,7 +676,7 @@ UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD* lpdwVolume) if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_AUX, TRUE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE); + return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L, TRUE); } /************************************************************************** @@ -698,7 +696,7 @@ UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume) /************************************************************************** * auxOutMessage [WINMM.@] */ -UINT WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2) +UINT WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD_PTR dw1, DWORD_PTR dw2) { LPWINE_MLD wmld; @@ -711,20 +709,19 @@ UINT WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2) /************************************************************************** * mciGetErrorStringW [WINMM.@] */ -BOOL WINAPI mciGetErrorStringW(DWORD wError, LPWSTR lpstrBuffer, UINT uLength) +BOOL WINAPI mciGetErrorStringW(MCIERROR wError, LPWSTR lpstrBuffer, UINT uLength) { - LPSTR bufstr = HeapAlloc(GetProcessHeap(), 0, uLength); - BOOL ret = mciGetErrorStringA(wError, bufstr, uLength); + char bufstr[MAXERRORLENGTH]; + BOOL ret = mciGetErrorStringA(wError, bufstr, MAXERRORLENGTH); MultiByteToWideChar( CP_ACP, 0, bufstr, -1, lpstrBuffer, uLength ); - HeapFree(GetProcessHeap(), 0, bufstr); return ret; } /************************************************************************** * mciGetErrorStringA [WINMM.@] */ -BOOL WINAPI mciGetErrorStringA(DWORD dwError, LPSTR lpstrBuffer, UINT uLength) +BOOL WINAPI mciGetErrorStringA(MCIERROR dwError, LPSTR lpstrBuffer, UINT uLength) { BOOL ret = FALSE; @@ -742,18 +739,17 @@ BOOL WINAPI mciGetErrorStringA(DWORD dwError, LPSTR lpstrBuffer, UINT uLength) /************************************************************************** * mciDriverNotify [WINMM.@] */ -BOOL WINAPI mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus) +BOOL WINAPI mciDriverNotify(HWND hWndCallBack, MCIDEVICEID wDevID, UINT wStatus) { - TRACE("(%p, %04x, %04X)\n", hWndCallBack, wDevID, wStatus); - return PostMessageA(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID); + return PostMessageW(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID); } /************************************************************************** * mciGetDriverData [WINMM.@] */ -DWORD WINAPI mciGetDriverData(UINT uDeviceID) +DWORD WINAPI mciGetDriverData(MCIDEVICEID uDeviceID) { LPWINE_MCIDRIVER wmd; @@ -772,7 +768,7 @@ DWORD WINAPI mciGetDriverData(UINT uDeviceID) /************************************************************************** * mciSetDriverData [WINMM.@] */ -BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD data) +BOOL WINAPI mciSetDriverData(MCIDEVICEID uDeviceID, DWORD data) { LPWINE_MCIDRIVER wmd; @@ -792,7 +788,7 @@ BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD data) /************************************************************************** * mciSendCommandA [WINMM.@] */ -DWORD WINAPI mciSendCommandA(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2) +DWORD WINAPI mciSendCommandA(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { DWORD dwRet; @@ -805,14 +801,233 @@ DWORD WINAPI mciSendCommandA(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwPar return dwRet; } +inline static LPSTR strdupWtoA( LPCWSTR str ) +{ + LPSTR ret; + INT len; + + if (!str) return NULL; + len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL ); + ret = HeapAlloc( GetProcessHeap(), 0, len ); + if(ret) WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL ); + return ret; +} + +static int MCI_MapMsgWtoA(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2) +{ + switch(msg) + { + case MCI_CLOSE: + case MCI_PLAY: + case MCI_SEEK: + case MCI_STOP: + case MCI_PAUSE: + case MCI_GETDEVCAPS: + case MCI_SPIN: + case MCI_SET: + case MCI_STEP: + case MCI_RECORD: + case MCI_BREAK: + case MCI_SOUND: + case MCI_STATUS: + case MCI_CUE: + case MCI_REALIZE: + case MCI_PUT: + case MCI_WHERE: + case MCI_FREEZE: + case MCI_UNFREEZE: + case MCI_CUT: + case MCI_COPY: + case MCI_PASTE: + case MCI_UPDATE: + case MCI_RESUME: + case MCI_DELETE: + return 0; + + case MCI_OPEN: + { + MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)*dwParam2; + MCI_OPEN_PARMSA *mci_openA; + DWORD_PTR *ptr; + + ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_openA) + sizeof(DWORD_PTR)); + if (!ptr) return -1; + + *ptr++ = *dwParam2; /* save the previous pointer */ + *dwParam2 = (DWORD_PTR)ptr; + mci_openA = (MCI_OPEN_PARMSA *)ptr; + + if (dwParam1 & MCI_NOTIFY) + mci_openA->dwCallback = mci_openW->dwCallback; + + if (dwParam1 & MCI_OPEN_TYPE) + { + if (dwParam1 & MCI_OPEN_TYPE_ID) + mci_openA->lpstrDeviceType = (LPSTR)mci_openW->lpstrDeviceType; + else + mci_openA->lpstrDeviceType = strdupWtoA(mci_openW->lpstrDeviceType); + } + if (dwParam1 & MCI_OPEN_ELEMENT) + { + if (dwParam1 & MCI_OPEN_ELEMENT_ID) + mci_openA->lpstrElementName = (LPSTR)mci_openW->lpstrElementName; + else + mci_openA->lpstrElementName = strdupWtoA(mci_openW->lpstrElementName); + } + if (dwParam1 & MCI_OPEN_ALIAS) + mci_openA->lpstrAlias = strdupWtoA(mci_openW->lpstrAlias); + } + return 1; + + case MCI_WINDOW: + if (dwParam1 & MCI_ANIM_WINDOW_TEXT) + { + MCI_ANIM_WINDOW_PARMSW *mci_windowW = (MCI_ANIM_WINDOW_PARMSW *)*dwParam2; + MCI_ANIM_WINDOW_PARMSA *mci_windowA; + + mci_windowA = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_windowA)); + if (!mci_windowA) return -1; + + *dwParam2 = (DWORD_PTR)mci_windowA; + + mci_windowA->lpstrText = strdupWtoA(mci_windowW->lpstrText); + + if (dwParam1 & MCI_NOTIFY) + mci_windowA->dwCallback = mci_windowW->dwCallback; + if (dwParam1 & MCI_ANIM_WINDOW_HWND) + mci_windowA->hWnd = mci_windowW->hWnd; + if (dwParam1 & MCI_ANIM_WINDOW_STATE) + mci_windowA->nCmdShow = mci_windowW->nCmdShow; + + return 1; + } + return 0; + + case MCI_SYSINFO: + { + MCI_SYSINFO_PARMSW *mci_sysinfoW = (MCI_SYSINFO_PARMSW *)*dwParam2; + MCI_SYSINFO_PARMSA *mci_sysinfoA; + DWORD_PTR *ptr; + + ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_sysinfoA) + sizeof(DWORD_PTR)); + if (!ptr) return -1; + + *ptr++ = *dwParam2; /* save the previous pointer */ + *dwParam2 = (DWORD_PTR)ptr; + mci_sysinfoA = (MCI_SYSINFO_PARMSA *)ptr; + + if (dwParam1 & MCI_NOTIFY) + mci_sysinfoA->dwCallback = mci_sysinfoW->dwCallback; + + mci_sysinfoA->dwRetSize = mci_sysinfoW->dwRetSize; /* FIXME */ + mci_sysinfoA->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mci_sysinfoA->dwRetSize); + + return 1; + } + + case MCI_INFO: + case MCI_SAVE: + case MCI_LOAD: + case MCI_ESCAPE: + default: + FIXME("Message 0x%04x needs translation\n", msg); + return -1; + } + return 0; +} + +static DWORD MCI_UnmapMsgWtoA(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2, + DWORD result) +{ + switch(msg) + { + case MCI_OPEN: + { + DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1; + MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)*ptr; + MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA *)(ptr + 1); + + mci_openW->wDeviceID = mci_openA->wDeviceID; + + if (dwParam1 & MCI_OPEN_TYPE) + { + if (!(dwParam1 & MCI_OPEN_TYPE_ID)) + HeapFree(GetProcessHeap(), 0, mci_openA->lpstrDeviceType); + } + if (dwParam1 & MCI_OPEN_ELEMENT) + { + if (!(dwParam1 & MCI_OPEN_ELEMENT_ID)) + HeapFree(GetProcessHeap(), 0, mci_openA->lpstrElementName); + } + if (dwParam1 & MCI_OPEN_ALIAS) + HeapFree(GetProcessHeap(), 0, mci_openA->lpstrAlias); + HeapFree(GetProcessHeap(), 0, ptr); + } + break; + + case MCI_WINDOW: + if (dwParam1 & MCI_ANIM_WINDOW_TEXT) + { + MCI_ANIM_WINDOW_PARMSA *mci_windowA = (MCI_ANIM_WINDOW_PARMSA *)dwParam2; + + HeapFree(GetProcessHeap(), 0, (void *)mci_windowA->lpstrText); + HeapFree(GetProcessHeap(), 0, mci_windowA); + } + break; + + case MCI_SYSINFO: + { + DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1; + MCI_SYSINFO_PARMSW *mci_sysinfoW = (MCI_SYSINFO_PARMSW *)*ptr; + MCI_SYSINFO_PARMSA *mci_sysinfoA = (MCI_SYSINFO_PARMSA *)(ptr + 1); + + if (!result) + { + mci_sysinfoW->dwNumber = mci_sysinfoA->dwNumber; + mci_sysinfoW->wDeviceType = mci_sysinfoA->wDeviceType; + MultiByteToWideChar(CP_ACP, 0, + mci_sysinfoA->lpstrReturn, mci_sysinfoA->dwRetSize, + mci_sysinfoW->lpstrReturn, mci_sysinfoW->dwRetSize); + } + + HeapFree(GetProcessHeap(), 0, mci_sysinfoA->lpstrReturn); + HeapFree(GetProcessHeap(), 0, ptr); + } + break; + + default: + FIXME("Message 0x%04x needs unmapping\n", msg); + break; + } + + return result; +} + + /************************************************************************** * mciSendCommandW [WINMM.@] + * + * FIXME: we should do the things other way around, but since our + * MM subsystem is not unicode aware... */ -DWORD WINAPI mciSendCommandW(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2) +DWORD WINAPI mciSendCommandW(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { - FIXME("(%08x, %s, %08lx, %08lx): stub\n", + DWORD ret; + int mapped; + + TRACE("(%08x, %s, %08lx, %08lx)\n", wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2); - return MCIERR_UNSUPPORTED_FUNCTION; + + mapped = MCI_MapMsgWtoA(wMsg, dwParam1, &dwParam2); + if (mapped == -1) + { + FIXME("message %04x mapping failed\n", wMsg); + return MMSYSERR_NOMEM; + } + ret = mciSendCommandA(wDevID, wMsg, dwParam1, dwParam2); + if (mapped) + MCI_UnmapMsgWtoA(wMsg, dwParam1, dwParam2, ret); + return ret; } /************************************************************************** @@ -850,18 +1065,15 @@ UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data) INT16 ret; TRACE("(0x%04x, 0x%08lx)\n", wDevID, data); -#ifndef __REACTOS__ + if ((HIWORD(data) != 0 && HWND_16(GetActiveWindow()) != HIWORD(data)) || (GetAsyncKeyState(LOWORD(data)) & 1) == 0) { MyUserYield(); ret = 0; - } else -#endif - { + } else { MSG msg; - - msg.hwnd = HIWORD(data); - //msg.hwnd = HWND_32(HIWORD(data)); + + msg.hwnd = HWND_32(HIWORD(data)); while (!PeekMessageA(&msg, msg.hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)); ret = -1; } @@ -871,7 +1083,7 @@ UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data) /************************************************************************** * mciSetYieldProc [WINMM.@] */ -BOOL WINAPI mciSetYieldProc(UINT uDeviceID, YIELDPROC fpYieldProc, DWORD dwYieldData) +BOOL WINAPI mciSetYieldProc(MCIDEVICEID uDeviceID, YIELDPROC fpYieldProc, DWORD dwYieldData) { LPWINE_MCIDRIVER wmd; @@ -904,7 +1116,7 @@ UINT WINAPI mciGetDeviceIDFromElementIDW(DWORD dwElementID, LPCWSTR lpstrType) /************************************************************************** * mciGetYieldProc [WINMM.@] */ -YIELDPROC WINAPI mciGetYieldProc(UINT uDeviceID, DWORD* lpdwYieldData) +YIELDPROC WINAPI mciGetYieldProc(MCIDEVICEID uDeviceID, DWORD* lpdwYieldData) { LPWINE_MCIDRIVER wmd; @@ -928,7 +1140,7 @@ YIELDPROC WINAPI mciGetYieldProc(UINT uDeviceID, DWORD* lpdwYieldData) /************************************************************************** * mciGetCreatorTask [WINMM.@] */ -HTASK WINAPI mciGetCreatorTask(UINT uDeviceID) +HTASK WINAPI mciGetCreatorTask(MCIDEVICEID uDeviceID) { LPWINE_MCIDRIVER wmd; HTASK ret = 0; @@ -942,7 +1154,7 @@ HTASK WINAPI mciGetCreatorTask(UINT uDeviceID) /************************************************************************** * mciDriverYield [WINMM.@] */ -UINT WINAPI mciDriverYield(UINT uDeviceID) +UINT WINAPI mciDriverYield(MCIDEVICEID uDeviceID) { LPWINE_MCIDRIVER wmd; UINT ret = 0; @@ -969,7 +1181,7 @@ UINT WINAPI midiOutGetNumDevs(void) /************************************************************************** * midiOutGetDevCapsW [WINMM.@] */ -UINT WINAPI midiOutGetDevCapsW(UINT uDeviceID, LPMIDIOUTCAPSW lpCaps, +UINT WINAPI midiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW lpCaps, UINT uSize) { MIDIOUTCAPSA mocA; @@ -995,7 +1207,7 @@ UINT WINAPI midiOutGetDevCapsW(UINT uDeviceID, LPMIDIOUTCAPSW lpCaps, /************************************************************************** * midiOutGetDevCapsA [WINMM.@] */ -UINT WINAPI midiOutGetDevCapsA(UINT uDeviceID, LPMIDIOUTCAPSA lpCaps, +UINT WINAPI midiOutGetDevCapsA(UINT_PTR uDeviceID, LPMIDIOUTCAPSA lpCaps, UINT uSize) { LPWINE_MLD wmld; @@ -1007,7 +1219,7 @@ UINT WINAPI midiOutGetDevCapsA(UINT uDeviceID, LPMIDIOUTCAPSA lpCaps, if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MODM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE); + return MMDRV_Message(wmld, MODM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize, TRUE); } /************************************************************************** @@ -1088,8 +1300,8 @@ static LPWINE_MIDI MIDI_OutAlloc(HMIDIOUT* lphMidiOut, LPDWORD lpdwCallback, return lpwm; } -UINT MIDI_OutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, DWORD dwCallback, - DWORD dwInstance, DWORD dwFlags, BOOL bFrom32) +UINT MIDI_OutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback, + DWORD_PTR dwInstance, DWORD dwFlags, BOOL bFrom32) { HMIDIOUT hMidiOut; LPWINE_MIDI lpwm; @@ -1124,8 +1336,8 @@ UINT MIDI_OutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, DWORD dwCallback, /************************************************************************** * midiOutOpen [WINMM.@] */ -UINT WINAPI midiOutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, - DWORD dwCallback, DWORD dwInstance, DWORD dwFlags) +UINT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, + DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags) { return MIDI_OutOpen(lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags, TRUE); } @@ -1162,7 +1374,7 @@ UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut, if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MODM_PREPARE, (DWORD)lpMidiOutHdr, uSize, TRUE); + return MMDRV_Message(wmld, MODM_PREPARE, (DWORD_PTR)lpMidiOutHdr, uSize, TRUE); } /************************************************************************** @@ -1182,7 +1394,7 @@ UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut, if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpMidiOutHdr, uSize, TRUE); + return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD_PTR)lpMidiOutHdr, uSize, TRUE); } /************************************************************************** @@ -1213,7 +1425,7 @@ UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut, if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD)lpMidiOutHdr, uSize, TRUE); + return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr, uSize, TRUE); } /************************************************************************** @@ -1243,7 +1455,7 @@ UINT WINAPI midiOutGetVolume(HMIDIOUT hMidiOut, DWORD* lpdwVolume) if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MODM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE); + return MMDRV_Message(wmld, MODM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L, TRUE); } /************************************************************************** @@ -1303,7 +1515,7 @@ UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT* lpuDeviceID) * midiOutMessage [WINMM.@] */ UINT WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage, - DWORD dwParam1, DWORD dwParam2) + DWORD_PTR dwParam1, DWORD_PTR dwParam2) { LPWINE_MLD wmld; @@ -1341,7 +1553,7 @@ UINT WINAPI midiInGetNumDevs(void) /************************************************************************** * midiInGetDevCapsW [WINMM.@] */ -UINT WINAPI midiInGetDevCapsW(UINT uDeviceID, LPMIDIINCAPSW lpCaps, UINT uSize) +UINT WINAPI midiInGetDevCapsW(UINT_PTR uDeviceID, LPMIDIINCAPSW lpCaps, UINT uSize) { MIDIINCAPSA micA; UINT ret = midiInGetDevCapsA(uDeviceID, &micA, uSize); @@ -1362,7 +1574,7 @@ UINT WINAPI midiInGetDevCapsW(UINT uDeviceID, LPMIDIINCAPSW lpCaps, UINT uSize) /************************************************************************** * midiInGetDevCapsA [WINMM.@] */ -UINT WINAPI midiInGetDevCapsA(UINT uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize) +UINT WINAPI midiInGetDevCapsA(UINT_PTR uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize) { LPWINE_MLD wmld; @@ -1373,7 +1585,7 @@ UINT WINAPI midiInGetDevCapsA(UINT uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize) if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIDIIN, TRUE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MIDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE); + return MMDRV_Message(wmld, MIDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize, TRUE); } /************************************************************************** @@ -1472,7 +1684,7 @@ UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn, if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD)lpMidiInHdr, uSize, TRUE); + return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD_PTR)lpMidiInHdr, uSize, TRUE); } /************************************************************************** @@ -1492,7 +1704,7 @@ UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn, if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpMidiInHdr, uSize, TRUE); + return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD_PTR)lpMidiInHdr, uSize, TRUE); } /************************************************************************** @@ -1508,7 +1720,7 @@ UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn, if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD)lpMidiInHdr, uSize, TRUE); + return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD_PTR)lpMidiInHdr, uSize, TRUE); } /************************************************************************** @@ -1579,7 +1791,7 @@ UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT* lpuDeviceID) * midiInMessage [WINMM.@] */ UINT WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage, - DWORD dwParam1, DWORD dwParam2) + DWORD_PTR dwParam1, DWORD_PTR dwParam2) { LPWINE_MLD wmld; @@ -2269,7 +2481,7 @@ UINT WINAPI waveOutGetNumDevs(void) /************************************************************************** * waveOutGetDevCapsA [WINMM.@] */ -UINT WINAPI waveOutGetDevCapsA(UINT uDeviceID, LPWAVEOUTCAPSA lpCaps, +UINT WINAPI waveOutGetDevCapsA(UINT_PTR uDeviceID, LPWAVEOUTCAPSA lpCaps, UINT uSize) { LPWINE_MLD wmld; @@ -2281,14 +2493,14 @@ UINT WINAPI waveOutGetDevCapsA(UINT uDeviceID, LPWAVEOUTCAPSA lpCaps, if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEOUT, TRUE)) == NULL) return MMSYSERR_BADDEVICEID; - return MMDRV_Message(wmld, WODM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE); + return MMDRV_Message(wmld, WODM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize, TRUE); } /************************************************************************** * waveOutGetDevCapsW [WINMM.@] */ -UINT WINAPI waveOutGetDevCapsW(UINT uDeviceID, LPWAVEOUTCAPSW lpCaps, +UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, UINT uSize) { WAVEOUTCAPSA wocA; @@ -2359,9 +2571,9 @@ UINT WINAPI waveOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize) * waveOutOpen [WINMM.@] * All the args/structs have the same layout as the win16 equivalents */ -UINT WINAPI waveOutOpen(HWAVEOUT* lphWaveOut, UINT uDeviceID, - const LPWAVEFORMATEX lpFormat, DWORD dwCallback, - DWORD dwInstance, DWORD dwFlags) +UINT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, + const LPWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, + DWORD_PTR dwInstance, DWORD dwFlags) { return WAVE_Open((HANDLE*)lphWaveOut, uDeviceID, MMDRV_WAVEOUT, lpFormat, dwCallback, dwInstance, dwFlags, TRUE); @@ -2402,7 +2614,7 @@ UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WODM_PREPARE, (DWORD)lpWaveOutHdr, uSize, TRUE); + return MMDRV_Message(wmld, WODM_PREPARE, (DWORD_PTR)lpWaveOutHdr, uSize, TRUE); } /************************************************************************** @@ -2422,7 +2634,7 @@ UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpWaveOutHdr, uSize, TRUE); + return MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD_PTR)lpWaveOutHdr, uSize, TRUE); } /************************************************************************** @@ -2438,7 +2650,7 @@ UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WODM_WRITE, (DWORD)lpWaveOutHdr, uSize, TRUE); + return MMDRV_Message(wmld, WODM_WRITE, (DWORD_PTR)lpWaveOutHdr, uSize, TRUE); } /************************************************************************** @@ -2510,7 +2722,7 @@ UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime, if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WODM_GETPOS, (DWORD)lpTime, uSize, TRUE); + return MMDRV_Message(wmld, WODM_GETPOS, (DWORD_PTR)lpTime, uSize, TRUE); } /************************************************************************** @@ -2524,7 +2736,7 @@ UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, LPDWORD lpdw) if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WODM_GETPITCH, (DWORD)lpdw, 0L, TRUE); + return MMDRV_Message(wmld, WODM_GETPITCH, (DWORD_PTR)lpdw, 0L, TRUE); } /************************************************************************** @@ -2552,7 +2764,7 @@ UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, LPDWORD lpdw) if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WODM_GETPLAYBACKRATE, (DWORD)lpdw, 0L, TRUE); + return MMDRV_Message(wmld, WODM_GETPLAYBACKRATE, (DWORD_PTR)lpdw, 0L, TRUE); } /************************************************************************** @@ -2581,7 +2793,7 @@ UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw) if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WODM_GETVOLUME, (DWORD)lpdw, 0L, TRUE); + return MMDRV_Message(wmld, WODM_GETVOLUME, (DWORD_PTR)lpdw, 0L, TRUE); } /************************************************************************** @@ -2621,7 +2833,7 @@ UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT* lpuDeviceID) * waveOutMessage [WINMM.@] */ UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, - DWORD dwParam1, DWORD dwParam2) + DWORD_PTR dwParam1, DWORD_PTR dwParam2) { LPWINE_MLD wmld; @@ -2652,7 +2864,7 @@ UINT WINAPI waveInGetNumDevs(void) /************************************************************************** * waveInGetDevCapsW [WINMM.@] */ -UINT WINAPI waveInGetDevCapsW(UINT uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize) +UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize) { WAVEINCAPSA wicA; UINT ret = waveInGetDevCapsA(uDeviceID, &wicA, uSize); @@ -2674,7 +2886,7 @@ UINT WINAPI waveInGetDevCapsW(UINT uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize) /************************************************************************** * waveInGetDevCapsA [WINMM.@] */ -UINT WINAPI waveInGetDevCapsA(UINT uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize) +UINT WINAPI waveInGetDevCapsA(UINT_PTR uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize) { LPWINE_MLD wmld; @@ -2685,7 +2897,7 @@ UINT WINAPI waveInGetDevCapsA(UINT uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize) if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEIN, TRUE)) == NULL) return MMSYSERR_BADDEVICEID; - return MMDRV_Message(wmld, WIDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE); + return MMDRV_Message(wmld, WIDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize, TRUE); } /************************************************************************** @@ -2755,7 +2967,7 @@ UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr, lpWaveInHdr->dwBytesRecorded = 0; - return MMDRV_Message(wmld, WIDM_PREPARE, (DWORD)lpWaveInHdr, uSize, TRUE); + return MMDRV_Message(wmld, WIDM_PREPARE, (DWORD_PTR)lpWaveInHdr, uSize, TRUE); } /************************************************************************** @@ -2776,7 +2988,7 @@ UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr, if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpWaveInHdr, uSize, TRUE); + return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD_PTR)lpWaveInHdr, uSize, TRUE); } /************************************************************************** @@ -2793,7 +3005,7 @@ UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD)lpWaveInHdr, uSize, TRUE); + return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD_PTR)lpWaveInHdr, uSize, TRUE); } /************************************************************************** @@ -2854,7 +3066,7 @@ UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime, if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; - return MMDRV_Message(wmld, WIDM_GETPOS, (DWORD)lpTime, uSize, TRUE); + return MMDRV_Message(wmld, WIDM_GETPOS, (DWORD_PTR)lpTime, uSize, TRUE); } /************************************************************************** @@ -2879,7 +3091,7 @@ UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT* lpuDeviceID) * waveInMessage [WINMM.@] */ UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, - DWORD dwParam1, DWORD dwParam2) + DWORD_PTR dwParam1, DWORD_PTR dwParam2) { LPWINE_MLD wmld; diff --git a/reactos/lib/winmm/winmm.def b/reactos/lib/winmm/winmm.def deleted file mode 100644 index 945525a5acb..00000000000 --- a/reactos/lib/winmm/winmm.def +++ /dev/null @@ -1,181 +0,0 @@ -; File generated automatically from winmm.spec; do not edit! - -LIBRARY winmm.dll - -EXPORTS -PlaySoundA@12 @18 -CloseDriver@12 @2 -DefDriverProc@20 @5 -DriverCallback@28 @6 -;DrvClose@12=CloseDriver@12 @7 -;DrvDefDriverProc@20=DefDriverProc@20 @8 -;DrvGetModuleHandle@4=GetDriverModuleHandle@4 @9 -;DrvOpen@12=OpenDriverW@12 @10 -;DrvOpenA@12=OpenDriverA@12 @11 -;DrvSendMessage@16=SendDriverMessage@16 @12 -GetDriverFlags@4 @13 -GetDriverModuleHandle@4 @14 -;OpenDriver@12=OpenDriverW@12 @15 -OpenDriverA@12 @16 -;PlaySound@12=PlaySoundA@12 @17 -PlaySoundW@12 @19 -SendDriverMessage@16 @20 -auxGetDevCapsA@12 @21 -auxGetDevCapsW@12 @22 -auxGetNumDevs@0 @23 -auxGetVolume@8 @24 -auxOutMessage@16 @25 -auxSetVolume@8 @26 -joyGetDevCapsA@12 @28 -joyGetDevCapsW@12 @29 -joyGetNumDevs@0 @30 -joyGetPos@8 @31 -joyGetPosEx@8 @32 -joyGetThreshold@8 @33 -joyReleaseCapture@4 @34 -joySetCapture@16 @35 -joySetThreshold@8 @36 -mciDriverNotify@12 @37 -mciDriverYield@4 @38 -mciExecute@4 @39 -mciFreeCommandResource@4 @40 -mciGetCreatorTask@4 @41 -mciGetDeviceIDA@4 @42 -mciGetDeviceIDFromElementIDW@8 @43 -mciGetDeviceIDW@4 @44 -mciGetDriverData@4 @45 -mciGetErrorStringA@12 @46 -mciGetErrorStringW@12 @47 -mciGetYieldProc@8 @48 -mciLoadCommandResource@12 @49 -mciSendCommandA@16 @50 -mciSendCommandW@16 @51 -mciSendStringA@16 @52 -mciSendStringW@16 @53 -mciSetDriverData@8 @54 -mciSetYieldProc@12 @55 -midiInAddBuffer@12 @58 -midiInClose@4 @59 -midiInGetDevCapsA@12 @60 -midiInGetDevCapsW@12 @61 -midiInGetErrorTextA@12 @62 -midiInGetErrorTextW@12 @63 -midiInGetID@8 @64 -midiInGetNumDevs@0 @65 -midiInMessage@16 @66 -midiInOpen@20 @67 -midiInPrepareHeader@12 @68 -midiInReset@4 @69 -midiInStart@4 @70 -midiInStop@4 @71 -midiInUnprepareHeader@12 @72 -midiOutCacheDrumPatches@16 @73 -midiOutCachePatches@16 @74 -midiOutClose@4 @75 -midiOutGetDevCapsA@12 @76 -midiOutGetDevCapsW@12 @77 -midiOutGetErrorTextA@12 @78 -midiOutGetErrorTextW@12 @79 -midiOutGetID@8 @80 -midiOutGetNumDevs@0 @81 -midiOutGetVolume@8 @82 -midiOutLongMsg@12 @83 -midiOutMessage@16 @84 -midiOutOpen@20 @85 -midiOutPrepareHeader@12 @86 -midiOutReset@4 @87 -midiOutSetVolume@8 @88 -midiOutShortMsg@8 @89 -midiOutUnprepareHeader@12 @90 -midiStreamClose@4 @91 -midiStreamOpen@24 @92 -midiStreamOut@12 @93 -midiStreamPause@4 @94 -midiStreamPosition@12 @95 -midiStreamProperty@12 @96 -midiStreamRestart@4 @97 -midiStreamStop@4 @98 -mixerClose@4 @99 -mixerGetControlDetailsA@12 @100 -mixerGetControlDetailsW@12 @101 -mixerGetDevCapsA@12 @102 -mixerGetDevCapsW@12 @103 -mixerGetID@12 @104 -mixerGetLineControlsA@12 @105 -mixerGetLineControlsW@12 @106 -mixerGetLineInfoA@12 @107 -mixerGetLineInfoW@12 @108 -mixerGetNumDevs@0 @109 -mixerMessage@16 @110 -mixerOpen@20 @111 -mixerSetControlDetails@12 @112 -mmioAdvance@12 @113 -mmioAscend@12 @114 -mmioClose@8 @115 -mmioCreateChunk@12 @116 -mmioDescend@16 @117 -mmioFlush@8 @118 -mmioGetInfo@12 @119 -mmioInstallIOProcA@12 @121 -mmioInstallIOProcW@12 @122 -mmioOpenA@12 @123 -mmioOpenW@12 @124 -mmioRead@12 @125 -mmioRenameA@16 @126 -mmioRenameW@16 @127 -mmioSeek@12 @128 -mmioSendMessage@16 @129 -mmioSetBuffer@16 @130 -mmioSetInfo@12 @131 -mmioStringToFOURCCA@8 @132 -mmioStringToFOURCCW@8 @133 -mmioWrite@12 @134 -mmsystemGetVersion@0 @135 -sndPlaySoundA@8 @136 -sndPlaySoundW@8 @137 -timeBeginPeriod@4 @138 -timeEndPeriod@4 @139 -timeGetDevCaps@8 @140 -timeGetSystemTime@8 @141 -timeGetTime@0 @142 -timeKillEvent@4 @143 -timeSetEvent@20 @144 -waveInAddBuffer@12 @145 -waveInClose@4 @146 -waveInGetDevCapsA@12 @147 -waveInGetDevCapsW@12 @148 -waveInGetErrorTextA@12 @149 -waveInGetErrorTextW@12 @150 -waveInGetID@8 @151 -waveInGetNumDevs@0 @152 -waveInGetPosition@12 @153 -waveInMessage@16 @154 -waveInOpen@24 @155 -waveInPrepareHeader@12 @156 -waveInReset@4 @157 -waveInStart@4 @158 -waveInStop@4 @159 -waveInUnprepareHeader@12 @160 -waveOutBreakLoop@4 @161 -waveOutClose@4 @162 -waveOutGetDevCapsA@12 @163 -waveOutGetDevCapsW@12 @164 -waveOutGetErrorTextA@12 @165 -waveOutGetErrorTextW@12 @166 -waveOutGetID@8 @167 -waveOutGetNumDevs@0 @168 -waveOutGetPitch@8 @169 -waveOutGetPlaybackRate@8 @170 -waveOutGetPosition@12 @171 -waveOutGetVolume@8 @172 -waveOutMessage@16 @173 -waveOutOpen@24 @174 -waveOutPause@4 @175 -waveOutPrepareHeader@12 @176 -waveOutReset@4 @177 -waveOutRestart@4 @178 -waveOutSetPitch@8 @179 -waveOutSetPlaybackRate@8 @180 -waveOutSetVolume@8 @181 -waveOutUnprepareHeader@12 @182 -waveOutWrite@12 @183 diff --git a/reactos/lib/winmm/winmm.edf b/reactos/lib/winmm/winmm.edf deleted file mode 100644 index deeb8fbd075..00000000000 --- a/reactos/lib/winmm/winmm.edf +++ /dev/null @@ -1,181 +0,0 @@ -; File generated automatically from winmm.spec; do not edit! - -LIBRARY winmm.dll - -EXPORTS -PlaySoundA=PlaySoundA@12 @18 -CloseDriver=CloseDriver@12 @2 -DefDriverProc=DefDriverProc@20 @5 -DriverCallback=DriverCallback@28 @6 -DrvClose=CloseDriver@12 @7 -DrvDefDriverProc=DefDriverProc@20 @8 -DrvGetModuleHandle=GetDriverModuleHandle@4 @9 -DrvOpen=OpenDriverW@12 @10 -DrvOpenA=OpenDriverA@12 @11 -DrvSendMessage=SendDriverMessage@16 @12 -GetDriverFlags=GetDriverFlags@4 @13 -GetDriverModuleHandle=GetDriverModuleHandle@4 @14 -OpenDriver=OpenDriverW@12 @15 -OpenDriverA=OpenDriverA@12 @16 -PlaySound=PlaySoundA@12 @17 -PlaySoundW=PlaySoundW@12 @19 -SendDriverMessage=SendDriverMessage@16 @20 -auxGetDevCapsA=auxGetDevCapsA@12 @21 -auxGetDevCapsW=auxGetDevCapsW@12 @22 -auxGetNumDevs=auxGetNumDevs@0 @23 -auxGetVolume=auxGetVolume@8 @24 -auxOutMessage=auxOutMessage@16 @25 -auxSetVolume=auxSetVolume@8 @26 -joyGetDevCapsA=joyGetDevCapsA@12 @28 -joyGetDevCapsW=joyGetDevCapsW@12 @29 -joyGetNumDevs=joyGetNumDevs@0 @30 -joyGetPos=joyGetPos@8 @31 -joyGetPosEx=joyGetPosEx@8 @32 -joyGetThreshold=joyGetThreshold@8 @33 -joyReleaseCapture=joyReleaseCapture@4 @34 -joySetCapture=joySetCapture@16 @35 -joySetThreshold=joySetThreshold@8 @36 -mciDriverNotify=mciDriverNotify@12 @37 -mciDriverYield=mciDriverYield@4 @38 -mciExecute=mciExecute@4 @39 -mciFreeCommandResource=mciFreeCommandResource@4 @40 -mciGetCreatorTask=mciGetCreatorTask@4 @41 -mciGetDeviceIDA=mciGetDeviceIDA@4 @42 -mciGetDeviceIDFromElementIDW=mciGetDeviceIDFromElementIDW@8 @43 -mciGetDeviceIDW=mciGetDeviceIDW@4 @44 -mciGetDriverData=mciGetDriverData@4 @45 -mciGetErrorStringA=mciGetErrorStringA@12 @46 -mciGetErrorStringW=mciGetErrorStringW@12 @47 -mciGetYieldProc=mciGetYieldProc@8 @48 -mciLoadCommandResource=mciLoadCommandResource@12 @49 -mciSendCommandA=mciSendCommandA@16 @50 -mciSendCommandW=mciSendCommandW@16 @51 -mciSendStringA=mciSendStringA@16 @52 -mciSendStringW=mciSendStringW@16 @53 -mciSetDriverData=mciSetDriverData@8 @54 -mciSetYieldProc=mciSetYieldProc@12 @55 -midiInAddBuffer=midiInAddBuffer@12 @58 -midiInClose=midiInClose@4 @59 -midiInGetDevCapsA=midiInGetDevCapsA@12 @60 -midiInGetDevCapsW=midiInGetDevCapsW@12 @61 -midiInGetErrorTextA=midiInGetErrorTextA@12 @62 -midiInGetErrorTextW=midiInGetErrorTextW@12 @63 -midiInGetID=midiInGetID@8 @64 -midiInGetNumDevs=midiInGetNumDevs@0 @65 -midiInMessage=midiInMessage@16 @66 -midiInOpen=midiInOpen@20 @67 -midiInPrepareHeader=midiInPrepareHeader@12 @68 -midiInReset=midiInReset@4 @69 -midiInStart=midiInStart@4 @70 -midiInStop=midiInStop@4 @71 -midiInUnprepareHeader=midiInUnprepareHeader@12 @72 -midiOutCacheDrumPatches=midiOutCacheDrumPatches@16 @73 -midiOutCachePatches=midiOutCachePatches@16 @74 -midiOutClose=midiOutClose@4 @75 -midiOutGetDevCapsA=midiOutGetDevCapsA@12 @76 -midiOutGetDevCapsW=midiOutGetDevCapsW@12 @77 -midiOutGetErrorTextA=midiOutGetErrorTextA@12 @78 -midiOutGetErrorTextW=midiOutGetErrorTextW@12 @79 -midiOutGetID=midiOutGetID@8 @80 -midiOutGetNumDevs=midiOutGetNumDevs@0 @81 -midiOutGetVolume=midiOutGetVolume@8 @82 -midiOutLongMsg=midiOutLongMsg@12 @83 -midiOutMessage=midiOutMessage@16 @84 -midiOutOpen=midiOutOpen@20 @85 -midiOutPrepareHeader=midiOutPrepareHeader@12 @86 -midiOutReset=midiOutReset@4 @87 -midiOutSetVolume=midiOutSetVolume@8 @88 -midiOutShortMsg=midiOutShortMsg@8 @89 -midiOutUnprepareHeader=midiOutUnprepareHeader@12 @90 -midiStreamClose=midiStreamClose@4 @91 -midiStreamOpen=midiStreamOpen@24 @92 -midiStreamOut=midiStreamOut@12 @93 -midiStreamPause=midiStreamPause@4 @94 -midiStreamPosition=midiStreamPosition@12 @95 -midiStreamProperty=midiStreamProperty@12 @96 -midiStreamRestart=midiStreamRestart@4 @97 -midiStreamStop=midiStreamStop@4 @98 -mixerClose=mixerClose@4 @99 -mixerGetControlDetailsA=mixerGetControlDetailsA@12 @100 -mixerGetControlDetailsW=mixerGetControlDetailsW@12 @101 -mixerGetDevCapsA=mixerGetDevCapsA@12 @102 -mixerGetDevCapsW=mixerGetDevCapsW@12 @103 -mixerGetID=mixerGetID@12 @104 -mixerGetLineControlsA=mixerGetLineControlsA@12 @105 -mixerGetLineControlsW=mixerGetLineControlsW@12 @106 -mixerGetLineInfoA=mixerGetLineInfoA@12 @107 -mixerGetLineInfoW=mixerGetLineInfoW@12 @108 -mixerGetNumDevs=mixerGetNumDevs@0 @109 -mixerMessage=mixerMessage@16 @110 -mixerOpen=mixerOpen@20 @111 -mixerSetControlDetails=mixerSetControlDetails@12 @112 -mmioAdvance=mmioAdvance@12 @113 -mmioAscend=mmioAscend@12 @114 -mmioClose=mmioClose@8 @115 -mmioCreateChunk=mmioCreateChunk@12 @116 -mmioDescend=mmioDescend@16 @117 -mmioFlush=mmioFlush@8 @118 -mmioGetInfo=mmioGetInfo@12 @119 -mmioInstallIOProcA=mmioInstallIOProcA@12 @121 -mmioInstallIOProcW=mmioInstallIOProcW@12 @122 -mmioOpenA=mmioOpenA@12 @123 -mmioOpenW=mmioOpenW@12 @124 -mmioRead=mmioRead@12 @125 -mmioRenameA=mmioRenameA@16 @126 -mmioRenameW=mmioRenameW@16 @127 -mmioSeek=mmioSeek@12 @128 -mmioSendMessage=mmioSendMessage@16 @129 -mmioSetBuffer=mmioSetBuffer@16 @130 -mmioSetInfo=mmioSetInfo@12 @131 -mmioStringToFOURCCA=mmioStringToFOURCCA@8 @132 -mmioStringToFOURCCW=mmioStringToFOURCCW@8 @133 -mmioWrite=mmioWrite@12 @134 -mmsystemGetVersion=mmsystemGetVersion@0 @135 -sndPlaySoundA=sndPlaySoundA@8 @136 -sndPlaySoundW=sndPlaySoundW@8 @137 -timeBeginPeriod=timeBeginPeriod@4 @138 -timeEndPeriod=timeEndPeriod@4 @139 -timeGetDevCaps=timeGetDevCaps@8 @140 -timeGetSystemTime=timeGetSystemTime@8 @141 -timeGetTime=timeGetTime@0 @142 -timeKillEvent=timeKillEvent@4 @143 -timeSetEvent=timeSetEvent@20 @144 -waveInAddBuffer=waveInAddBuffer@12 @145 -waveInClose=waveInClose@4 @146 -waveInGetDevCapsA=waveInGetDevCapsA@12 @147 -waveInGetDevCapsW=waveInGetDevCapsW@12 @148 -waveInGetErrorTextA=waveInGetErrorTextA@12 @149 -waveInGetErrorTextW=waveInGetErrorTextW@12 @150 -waveInGetID=waveInGetID@8 @151 -waveInGetNumDevs=waveInGetNumDevs@0 @152 -waveInGetPosition=waveInGetPosition@12 @153 -waveInMessage=waveInMessage@16 @154 -waveInOpen=waveInOpen@24 @155 -waveInPrepareHeader=waveInPrepareHeader@12 @156 -waveInReset=waveInReset@4 @157 -waveInStart=waveInStart@4 @158 -waveInStop=waveInStop@4 @159 -waveInUnprepareHeader=waveInUnprepareHeader@12 @160 -waveOutBreakLoop=waveOutBreakLoop@4 @161 -waveOutClose=waveOutClose@4 @162 -waveOutGetDevCapsA=waveOutGetDevCapsA@12 @163 -waveOutGetDevCapsW=waveOutGetDevCapsW@12 @164 -waveOutGetErrorTextA=waveOutGetErrorTextA@12 @165 -waveOutGetErrorTextW=waveOutGetErrorTextW@12 @166 -waveOutGetID=waveOutGetID@8 @167 -waveOutGetNumDevs=waveOutGetNumDevs@0 @168 -waveOutGetPitch=waveOutGetPitch@8 @169 -waveOutGetPlaybackRate=waveOutGetPlaybackRate@8 @170 -waveOutGetPosition=waveOutGetPosition@12 @171 -waveOutGetVolume=waveOutGetVolume@8 @172 -waveOutMessage=waveOutMessage@16 @173 -waveOutOpen=waveOutOpen@24 @174 -waveOutPause=waveOutPause@4 @175 -waveOutPrepareHeader=waveOutPrepareHeader@12 @176 -waveOutReset=waveOutReset@4 @177 -waveOutRestart=waveOutRestart@4 @178 -waveOutSetPitch=waveOutSetPitch@8 @179 -waveOutSetPlaybackRate=waveOutSetPlaybackRate@8 @180 -waveOutSetVolume=waveOutSetVolume@8 @181 -waveOutUnprepareHeader=waveOutUnprepareHeader@12 @182 -waveOutWrite=waveOutWrite@12 @183 diff --git a/reactos/lib/winmm/winmm.spec b/reactos/lib/winmm/winmm.spec new file mode 100644 index 00000000000..dc13c46b537 --- /dev/null +++ b/reactos/lib/winmm/winmm.spec @@ -0,0 +1,187 @@ +# ordinal exports +1 stdcall @(ptr long long) PlaySoundA +3 stub @ +4 stub @ + +@ stdcall PlaySoundA(ptr long long) +@ stdcall CloseDriver(long long long) +@ stdcall DefDriverProc(long long long long long) +@ stdcall DriverCallback(long long long long long long long) +@ stdcall DrvClose(long long long) CloseDriver +@ stdcall DrvDefDriverProc(long long long long long) DefDriverProc +@ stdcall DrvGetModuleHandle(long) GetDriverModuleHandle +@ stdcall DrvOpen(wstr wstr long) OpenDriverW +@ stdcall DrvOpenA(str str long) OpenDriverA +@ stdcall DrvSendMessage(long long long long) SendDriverMessage +@ stdcall GetDriverFlags(long) +@ stdcall GetDriverModuleHandle(long) +@ stdcall OpenDriver(wstr wstr long) OpenDriverW +@ stdcall OpenDriverA(str str long) +@ stdcall PlaySound(ptr long long) PlaySoundA +@ stdcall PlaySoundW(ptr long long) +@ stdcall SendDriverMessage(long long long long) +@ stdcall auxGetDevCapsA(long ptr long) +@ stdcall auxGetDevCapsW(long ptr long) +@ stdcall auxGetNumDevs() +@ stdcall auxGetVolume(long ptr) +@ stdcall auxOutMessage(long long long long) +@ stdcall auxSetVolume(long long) +@ stub joyConfigChanged +@ stdcall joyGetDevCapsA(long ptr long) +@ stdcall joyGetDevCapsW(long ptr long) +@ stdcall joyGetNumDevs() +@ stdcall joyGetPos(long ptr) +@ stdcall joyGetPosEx(long ptr) +@ stdcall joyGetThreshold(long ptr) +@ stdcall joyReleaseCapture(long) +@ stdcall joySetCapture(long long long long) +@ stdcall joySetThreshold(long long) +@ stdcall mciDriverNotify(long long long) +@ stdcall mciDriverYield(long) +@ stdcall mciExecute(str) +@ stdcall mciFreeCommandResource(long) +@ stdcall mciGetCreatorTask(long) +@ stdcall mciGetDeviceIDA(str) +@ stdcall mciGetDeviceIDFromElementIDW(long str) +@ stdcall mciGetDeviceIDW(str) +@ stdcall mciGetDriverData(long) +@ stdcall mciGetErrorStringA(long ptr long) +@ stdcall mciGetErrorStringW(long ptr long) +@ stdcall mciGetYieldProc(long ptr) +@ stdcall mciLoadCommandResource(long wstr long) +@ stdcall mciSendCommandA(long long long long) +@ stdcall mciSendCommandW(long long long long) +@ stdcall mciSendStringA(str ptr long long) +@ stdcall mciSendStringW(wstr ptr long long) +@ stdcall mciSetDriverData(long long) +@ stdcall mciSetYieldProc(long ptr long) +@ stub midiConnect +@ stub midiDisconnect +@ stdcall midiInAddBuffer(long ptr long) +@ stdcall midiInClose(long) +@ stdcall midiInGetDevCapsA(long ptr long) +@ stdcall midiInGetDevCapsW(long ptr long) +@ stdcall midiInGetErrorTextA(long ptr long) +@ stdcall midiInGetErrorTextW(long ptr long) +@ stdcall midiInGetID(long ptr) +@ stdcall midiInGetNumDevs() +@ stdcall midiInMessage(long long long long) +@ stdcall midiInOpen(ptr long long long long) +@ stdcall midiInPrepareHeader(long ptr long) +@ stdcall midiInReset(long) +@ stdcall midiInStart(long) +@ stdcall midiInStop(long) +@ stdcall midiInUnprepareHeader(long ptr long) +@ stdcall midiOutCacheDrumPatches(long long ptr long) +@ stdcall midiOutCachePatches(long long ptr long) +@ stdcall midiOutClose(long) +@ stdcall midiOutGetDevCapsA(long ptr long) +@ stdcall midiOutGetDevCapsW(long ptr long) +@ stdcall midiOutGetErrorTextA(long ptr long) +@ stdcall midiOutGetErrorTextW(long ptr long) +@ stdcall midiOutGetID(long ptr) +@ stdcall midiOutGetNumDevs() +@ stdcall midiOutGetVolume(long ptr) +@ stdcall midiOutLongMsg(long ptr long) +@ stdcall midiOutMessage(long long long long) +@ stdcall midiOutOpen(ptr long long long long) +@ stdcall midiOutPrepareHeader(long ptr long) +@ stdcall midiOutReset(long) +@ stdcall midiOutSetVolume(long ptr) +@ stdcall midiOutShortMsg(long long) +@ stdcall midiOutUnprepareHeader(long ptr long) +@ stdcall midiStreamClose(long) +@ stdcall midiStreamOpen(ptr ptr long long long long) +@ stdcall midiStreamOut(long ptr long) +@ stdcall midiStreamPause(long) +@ stdcall midiStreamPosition(long ptr long) +@ stdcall midiStreamProperty(long ptr long) +@ stdcall midiStreamRestart(long) +@ stdcall midiStreamStop(long) +@ stdcall mixerClose(long) +@ stdcall mixerGetControlDetailsA(long ptr long) +@ stdcall mixerGetControlDetailsW(long ptr long) +@ stdcall mixerGetDevCapsA(long ptr long) +@ stdcall mixerGetDevCapsW(long ptr long) +@ stdcall mixerGetID(long ptr long) +@ stdcall mixerGetLineControlsA(long ptr long) +@ stdcall mixerGetLineControlsW(long ptr long) +@ stdcall mixerGetLineInfoA(long ptr long) +@ stdcall mixerGetLineInfoW(long ptr long) +@ stdcall mixerGetNumDevs() +@ stdcall mixerMessage(long long long long) +@ stdcall mixerOpen(ptr long long long long) +@ stdcall mixerSetControlDetails(long ptr long) +@ stdcall mmioAdvance(long ptr long) +@ stdcall mmioAscend(long ptr long) +@ stdcall mmioClose(long long) +@ stdcall mmioCreateChunk(long ptr long) +@ stdcall mmioDescend(long ptr ptr long) +@ stdcall mmioFlush(long long) +@ stdcall mmioGetInfo(long ptr long) +@ stub mmioInstallIOProc16 +@ stdcall mmioInstallIOProcA(long ptr long) +@ stdcall mmioInstallIOProcW(long ptr long) +@ stdcall mmioOpenA(str ptr long) +@ stdcall mmioOpenW(wstr ptr long) +@ stdcall mmioRead(long ptr long) +@ stdcall mmioRenameA(str str ptr long) +@ stdcall mmioRenameW(wstr wstr ptr long) +@ stdcall mmioSeek(long long long) +@ stdcall mmioSendMessage(long long long long) +@ stdcall mmioSetBuffer(long ptr long long) +@ stdcall mmioSetInfo(long ptr long) +@ stdcall mmioStringToFOURCCA(str long) +@ stdcall mmioStringToFOURCCW(wstr long) +@ stdcall mmioWrite(long ptr long) +@ stdcall mmsystemGetVersion() +@ stdcall sndPlaySoundA(ptr long) +@ stdcall sndPlaySoundW(ptr long) +@ stdcall timeBeginPeriod(long) +@ stdcall timeEndPeriod(long) +@ stdcall timeGetDevCaps(ptr long) +@ stdcall timeGetSystemTime(ptr long) +@ stdcall timeGetTime() +@ stdcall timeKillEvent(long) +@ stdcall timeSetEvent(long long ptr long long) +@ stdcall waveInAddBuffer(long ptr long) +@ stdcall waveInClose(long) +@ stdcall waveInGetDevCapsA(long ptr long) +@ stdcall waveInGetDevCapsW(long ptr long) +@ stdcall waveInGetErrorTextA(long ptr long) +@ stdcall waveInGetErrorTextW(long ptr long) +@ stdcall waveInGetID(long ptr) +@ stdcall waveInGetNumDevs() +@ stdcall waveInGetPosition(long ptr long) +@ stdcall waveInMessage(long long long long) +@ stdcall waveInOpen(ptr long ptr long long long) +@ stdcall waveInPrepareHeader(long ptr long) +@ stdcall waveInReset(long) +@ stdcall waveInStart(long) +@ stdcall waveInStop(long) +@ stdcall waveInUnprepareHeader(long ptr long) +@ stdcall waveOutBreakLoop(long) +@ stdcall waveOutClose(long) +@ stdcall waveOutGetDevCapsA(long ptr long) +@ stdcall waveOutGetDevCapsW(long ptr long) +@ stdcall waveOutGetErrorTextA(long ptr long) +@ stdcall waveOutGetErrorTextW(long ptr long) +@ stdcall waveOutGetID(long ptr) +@ stdcall waveOutGetNumDevs() +@ stdcall waveOutGetPitch(long ptr) +@ stdcall waveOutGetPlaybackRate(long ptr) +@ stdcall waveOutGetPosition(long ptr long) +@ stdcall waveOutGetVolume(long ptr) +@ stdcall waveOutMessage(long long long long) +@ stdcall waveOutOpen(ptr long ptr long long long) +@ stdcall waveOutPause(long) +@ stdcall waveOutPrepareHeader(long ptr long) +@ stdcall waveOutReset(long) +@ stdcall waveOutRestart(long) +@ stdcall waveOutSetPitch(long long) +@ stdcall waveOutSetPlaybackRate(long long) +@ stdcall waveOutSetVolume(long long) +@ stdcall waveOutUnprepareHeader(long ptr long) +@ stdcall waveOutWrite(long ptr long) +@ stub winmmf_ThunkData32 +@ stub winmmsl_ThunkData32