Author: tfaber
Date: Thu Mar 26 09:53:23 2015
New Revision: 66900
URL:
http://svn.reactos.org/svn/reactos?rev=66900&view=rev
Log:
[WINMM]
- Apply Wine commit b1d9d43a (winmm: Don't mask out SND_ALIAS_ID or SND_FILENAME in
sndPlaySound.) by Andrew Eikum. Fixes crash in winmm_winetest:wave
- Import WINMM_CheckCallback from Wine and use it, various cleanups (commits cb77f9a2,
06d6dd3e, e6a501bb, a311dff7 by Jörg Höhle). In particular, accepting a NULL callback in
DriverCallback fixes the crash in winmm_winetest:wave.
CORE-9401 #resolve
Modified:
trunk/reactos/dll/win32/winmm/driver.c
trunk/reactos/dll/win32/winmm/playsound.c
trunk/reactos/dll/win32/winmm/winemm.h
trunk/reactos/dll/win32/winmm/winmm.c
Modified: trunk/reactos/dll/win32/winmm/driver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/winmm/driver.c?r…
==============================================================================
--- trunk/reactos/dll/win32/winmm/driver.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/winmm/driver.c [iso-8859-1] Thu Mar 26 09:53:23 2015
@@ -569,36 +569,49 @@
}
/**************************************************************************
+ * DRIVER_getCallback [internal]
+ */
+static const char* DRIVER_getCallback(DWORD uFlags)
+{
+ switch(uFlags & DCB_TYPEMASK) {
+ case DCB_NULL: return "null";
+ case DCB_WINDOW: return "window";
+ case DCB_TASK: return "task";
+ case DCB_EVENT: return "event";
+ case DCB_FUNCTION: return "32bit function";
+ default: return "UNKNOWN";
+ }
+}
+
+/**************************************************************************
* DriverCallback [WINMM.@]
*/
BOOL WINAPI DriverCallback(DWORD_PTR dwCallBack, DWORD uFlags, HDRVR hDev,
DWORD wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1,
DWORD_PTR dwParam2)
{
- TRACE("(%08lX, %04X, %p, %04X, %08lX, %08lX, %08lX)\n",
- dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
+ BOOL ret = FALSE;
+ TRACE("(%08lX, %s %04X, %p, %04X, %08lX, %08lX, %08lX)\n",
+ dwCallBack, DRIVER_getCallback(uFlags), uFlags, hDev, wMsg, dwUser, dwParam1,
dwParam2);
+ if (!dwCallBack)
+ return ret;
switch (uFlags & DCB_TYPEMASK) {
case DCB_NULL:
- TRACE("Null !\n");
- if (dwCallBack)
- WARN("uFlags=%04X has null DCB value, but dwCallBack=%08lX is not null
!\n", uFlags, dwCallBack);
- break;
+ /* Native returns FALSE = no notification, not TRUE */
+ return ret;
case DCB_WINDOW:
- TRACE("Window(%04lX) handle=%p!\n", dwCallBack, hDev);
- PostMessageA((HWND)dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
+ ret = PostMessageA((HWND)dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
break;
case DCB_TASK: /* aka DCB_THREAD */
- TRACE("Task(%04lx) !\n", dwCallBack);
- PostThreadMessageA(dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
+ ret = PostThreadMessageA(dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
break;
case DCB_FUNCTION:
- TRACE("Function (32 bit) !\n");
((LPDRVCALLBACK)dwCallBack)(hDev, wMsg, dwUser, dwParam1, dwParam2);
+ ret = TRUE;
break;
case DCB_EVENT:
- TRACE("Event(%08lx) !\n", dwCallBack);
- SetEvent((HANDLE)dwCallBack);
+ ret = SetEvent((HANDLE)dwCallBack);
break;
#if 0
/* FIXME: for now only usable in mmsystem.dll16
@@ -630,8 +643,11 @@
WARN("Unknown callback type %d\n", uFlags & DCB_TYPEMASK);
return FALSE;
}
- TRACE("Done\n");
- return TRUE;
+ if (ret)
+ TRACE("Done\n");
+ else
+ WARN("Notification failure\n");
+ return ret;
}
/******************************************************************
Modified: trunk/reactos/dll/win32/winmm/playsound.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/winmm/playsound.…
==============================================================================
--- trunk/reactos/dll/win32/winmm/playsound.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/winmm/playsound.c [iso-8859-1] Thu Mar 26 09:53:23 2015
@@ -538,7 +538,7 @@
*/
BOOL WINAPI sndPlaySoundA(LPCSTR pszSoundA, UINT uFlags)
{
- uFlags &= SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC;
+ uFlags &=
SND_ALIAS_ID|SND_FILENAME|SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC;
return MULTIMEDIA_PlaySound(pszSoundA, 0, uFlags, FALSE);
}
@@ -547,7 +547,7 @@
*/
BOOL WINAPI sndPlaySoundW(LPCWSTR pszSound, UINT uFlags)
{
- uFlags &= SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC;
+ uFlags &=
SND_ALIAS_ID|SND_FILENAME|SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC;
return MULTIMEDIA_PlaySound(pszSound, 0, uFlags, TRUE);
}
Modified: trunk/reactos/dll/win32/winmm/winemm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/winmm/winemm.h?r…
==============================================================================
--- trunk/reactos/dll/win32/winmm/winemm.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/winmm/winemm.h [iso-8859-1] Thu Mar 26 09:53:23 2015
@@ -179,6 +179,8 @@
void TIME_MMTimeStop(void);
+MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer)
DECLSPEC_HIDDEN;
+
/* Global variables */
extern CRITICAL_SECTION WINMM_cs;
extern HINSTANCE hWinMM32Instance;
Modified: trunk/reactos/dll/win32/winmm/winmm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/winmm/winmm.c?re…
==============================================================================
--- trunk/reactos/dll/win32/winmm/winmm.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/winmm/winmm.c [iso-8859-1] Thu Mar 26 09:53:23 2015
@@ -140,6 +140,10 @@
ERR_TO_STR(WAVERR_STILLPLAYING);
ERR_TO_STR(WAVERR_UNPREPARED);
ERR_TO_STR(WAVERR_SYNC);
+ ERR_TO_STR(MIDIERR_INVALIDSETUP);
+ ERR_TO_STR(MIDIERR_NODEVICE);
+ ERR_TO_STR(MIDIERR_STILLPLAYING);
+ ERR_TO_STR(MIDIERR_UNPREPARED);
}
sprintf(unknown, "Unknown(0x%08x)", error);
return unknown;
@@ -184,6 +188,35 @@
break;
}
return TRUE;
+}
+
+/**************************************************************************
+ * WINMM_CheckCallback [internal]
+ */
+MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer)
+{
+ switch (fdwOpen & CALLBACK_TYPEMASK) {
+ case CALLBACK_NULL: /* dwCallback need not be NULL */
+ break;
+ case CALLBACK_WINDOW:
+ if (dwCallback && !IsWindow((HWND)dwCallback))
+ return MMSYSERR_INVALPARAM;
+ break;
+
+ case CALLBACK_FUNCTION:
+ /* a NULL cb is acceptable since w2k, MMSYSERR_INVALPARAM earlier */
+ if (mixer)
+ return MMSYSERR_INVALFLAG; /* since w2k, MMSYSERR_NOTSUPPORTED earlier */
+ break;
+ case CALLBACK_THREAD:
+ case CALLBACK_EVENT:
+ if (mixer) /* FIXME: mixer supports THREAD+EVENT since w2k */
+ return MMSYSERR_NOTSUPPORTED; /* w9X */
+ break;
+ default:
+ WARN("Unknown callback type %d\n", HIWORD(fdwOpen));
+ }
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
@@ -311,35 +344,27 @@
{
HANDLE hMix;
LPWINE_MLD wmld;
- DWORD dwRet = 0;
+ DWORD dwRet;
MIXEROPENDESC mod;
TRACE("(%p, %d, %08lx, %08lx, %08x)\n",
lphMix, uDeviceID, dwCallback, dwInstance, fdwOpen);
+ dwRet = WINMM_CheckCallback(dwCallback, fdwOpen, TRUE);
+ if(dwRet != MMSYSERR_NOERROR)
+ return dwRet;
+
mod.dwCallback = (DWORD_PTR)MIXER_WCallback;
- mod.dwInstance = 0;
-
-/* If callback is a function,
- * dwCallback contains function pointer
- * dwInstance private data
- *
- * if callback is a window
- * dwCallback contains a window handle
- */
- switch (fdwOpen & CALLBACK_TYPEMASK) {
- default:
- return MMSYSERR_INVALFLAG;
-
- case CALLBACK_NULL:
- break;
-
- case CALLBACK_WINDOW:
+ if ((fdwOpen & CALLBACK_TYPEMASK) == CALLBACK_WINDOW)
mod.dwInstance = dwCallback;
- if (dwCallback && !IsWindow((HWND)dwCallback))
- return MMSYSERR_INVALPARAM;
- break;
- }
+ else
+ mod.dwInstance = 0;
+
+ /* We're remapping to CALLBACK_FUNCTION because that's what old winmm is
+ * documented to do when opening the mixer driver.
+ * FIXME: Native supports CALLBACK_EVENT + CALLBACK_THREAD flags since w2k.
+ * FIXME: The non ALSA drivers ignore callback requests - bug.
+ */
wmld = MMDRV_Alloc(sizeof(WINE_MIXER), MMDRV_MIXER, &hMix, &fdwOpen,
&dwCallback, &dwInstance);
@@ -897,8 +922,7 @@
lpwm = (LPWINE_MIDI)MMDRV_Alloc(size, MMDRV_MIDIOUT, &hMidiOut, lpdwFlags,
lpdwCallback, lpdwInstance);
- if (lphMidiOut != NULL)
- *lphMidiOut = hMidiOut;
+ *lphMidiOut = hMidiOut;
if (lpwm) {
lpwm->mod.hMidi = hMidiOut;
@@ -920,12 +944,16 @@
{
HMIDIOUT hMidiOut;
LPWINE_MIDI lpwm;
- UINT dwRet = 0;
+ UINT dwRet;
TRACE("(%p, %d, %08lX, %08lX, %08X);\n",
lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
if (lphMidiOut != NULL) *lphMidiOut = 0;
+
+ dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
+ if (dwRet != MMSYSERR_NOERROR)
+ return dwRet;
lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &dwFlags,
0, NULL);
@@ -1211,12 +1239,16 @@
{
HANDLE hMidiIn;
LPWINE_MIDI lpwm;
- DWORD dwRet = 0;
+ DWORD dwRet;
TRACE("(%p, %d, %08lX, %08lX, %08X);\n",
lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
if (lphMidiIn != NULL) *lphMidiIn = 0;
+
+ dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
+ if (dwRet != MMSYSERR_NOERROR)
+ return dwRet;
lpwm = (LPWINE_MIDI)MMDRV_Alloc(sizeof(WINE_MIDI), MMDRV_MIDIIN, &hMidiIn,
&dwFlags, &dwCallback, &dwInstance);
@@ -1779,6 +1811,10 @@
if (cMidi != 1 || lphMidiStrm == NULL || lpuDeviceID == NULL)
return MMSYSERR_INVALPARAM;
+ ret = WINMM_CheckCallback(dwCallback, fdwOpen, FALSE);
+ if (ret != MMSYSERR_NOERROR)
+ return ret;
+
lpMidiStrm = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_MIDIStream));
if (!lpMidiStrm)
return MMSYSERR_NOMEM;
@@ -1792,8 +1828,7 @@
mosm.wDeviceID = *lpuDeviceID;
lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &fdwOpen,
1, &mosm);
lpMidiStrm->hDevice = hMidiOut;
- if (lphMidiStrm)
- *lphMidiStrm = (HMIDISTRM)hMidiOut;
+ *lphMidiStrm = (HMIDISTRM)hMidiOut;
lpwm->mld.uDeviceID = *lpuDeviceID;
@@ -1839,11 +1874,23 @@
TRACE("(%p, %p, %u)!\n", hMidiStrm, lpMidiHdr, cbMidiHdr);
+ if (cbMidiHdr < offsetof(MIDIHDR,dwOffset) || !lpMidiHdr || !lpMidiHdr->lpData
+ || lpMidiHdr->dwBufferLength < lpMidiHdr->dwBytesRecorded
+ || lpMidiHdr->dwBytesRecorded % 4 /* player expects DWORD padding */)
+ return MMSYSERR_INVALPARAM;
+ /* FIXME: Native additionally checks if the MIDIEVENTs in lpData
+ * exactly fit dwBytesRecorded. */
+
+ if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
+ return MIDIERR_UNPREPARED;
+
+ if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
+ return MIDIERR_STILLPLAYING;
+
if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
ret = MMSYSERR_INVALHANDLE;
- } else if (!lpMidiHdr) {
- ret = MMSYSERR_INVALPARAM;
} else {
+ lpMidiHdr->dwFlags |= MHDR_ISSTRM;
if (!PostThreadMessageA(lpMidiStrm->dwThreadID,
WINE_MSM_HEADER, cbMidiHdr,
(LPARAM)lpMidiHdr)) {
@@ -2011,7 +2058,7 @@
{
HANDLE handle;
LPWINE_MLD wmld;
- DWORD dwRet = MMSYSERR_NOERROR;
+ DWORD dwRet;
WAVEOPENDESC wod;
TRACE("(%p, %d, %s, %p, %08lX, %08lX, %08X);\n",
@@ -2020,6 +2067,10 @@
if (dwFlags & WAVE_FORMAT_QUERY)
TRACE("WAVE_FORMAT_QUERY requested !\n");
+
+ dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
+ if (dwRet != MMSYSERR_NOERROR)
+ return dwRet;
if (lpFormat == NULL) {
WARN("bad format\n");
@@ -2038,7 +2089,6 @@
if ((wmld = MMDRV_Alloc(sizeof(WINE_WAVE), uType, &handle,
&dwFlags, &dwCallback, &dwInstance)) == NULL) {
- WARN("no memory\n");
return MMSYSERR_NOMEM;
}