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?rev=66900&r1=66899&r2=66900&view=diff
==============================================================================
--- 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.c?rev=66900&r1=66899&r2=66900&view=diff
==============================================================================
--- 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?rev=66900&r1=66899&r2=66900&view=diff
==============================================================================
--- 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?rev=66900&r1=66899&r2=66900&view=diff
==============================================================================
--- 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;
     }
 


Reply via email to