diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c
index 611583863f960f7ecf7152970694b56b7d673019..cb6292af021649279998f68c0463d19b084a51fe 100644
--- a/dlls/winmm/winmm.c
+++ b/dlls/winmm/winmm.c
@@ -957,6 +957,8 @@ typedef struct WINE_MIDIStream {
 
 #define WINE_MSM_HEADER		(WM_USER+0)
 #define WINE_MSM_STOP		(WM_USER+1)
+#define WINE_MSM_PAUSE		(WM_USER+2)
+#define WINE_MSM_RESUME		(WM_USER+3)
 
 /**************************************************************************
  * 				MMSYSTEM_GetMidiStream		[internal]
@@ -1006,34 +1008,41 @@ static	BOOL	MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
     LPMIDIHDR	lpMidiHdr;
     LPMIDIHDR*	lpmh;
     LPBYTE	lpData;
-
-    switch (msg->message) {
-    case WM_QUIT:
-	SetEvent(lpMidiStrm->hEvent);
-	return FALSE;
-    case WINE_MSM_STOP:
-	TRACE("STOP\n");
-	/* this is not quite what MS doc says... */
-	midiOutReset(lpMidiStrm->hDevice);
-	/* empty list of already submitted buffers */
-	for (lpMidiHdr = lpMidiStrm->lpMidiHdr; lpMidiHdr; ) {
-	    LPMIDIHDR lphdr = lpMidiHdr;
-	    lpMidiHdr = lpMidiHdr->lpNext;
-	    lphdr->dwFlags |= MHDR_DONE;
-	    lphdr->dwFlags &= ~MHDR_INQUEUE;
-
-	    DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
-			   (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
-			   lpwm->mod.dwInstance, (DWORD_PTR)lphdr, 0);
-	}
-	lpMidiStrm->lpMidiHdr = 0;
-	SetEvent(lpMidiStrm->hEvent);
-	break;
-    case WINE_MSM_HEADER:
-	/* sets initial tick count for first MIDIHDR */
-	if (!lpMidiStrm->dwStartTicks)
-	    lpMidiStrm->dwStartTicks = GetTickCount();
-
+    BOOL	paused = FALSE;
+
+    for (;;) {
+        switch (msg->message) {
+        case WM_QUIT:
+            SetEvent(lpMidiStrm->hEvent);
+            return FALSE;
+        case WINE_MSM_STOP:
+            TRACE("STOP\n");
+            /* this is not quite what MS doc says... */
+            midiOutReset(lpMidiStrm->hDevice);
+            /* empty list of already submitted buffers */
+            for (lpMidiHdr = lpMidiStrm->lpMidiHdr; lpMidiHdr; ) {
+                LPMIDIHDR lphdr = lpMidiHdr;
+                lpMidiHdr = lpMidiHdr->lpNext;
+                lphdr->dwFlags |= MHDR_DONE;
+                lphdr->dwFlags &= ~MHDR_INQUEUE;
+
+                DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
+                               (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
+                               lpwm->mod.dwInstance, (DWORD_PTR)lphdr, 0);
+            }
+            lpMidiStrm->lpMidiHdr = 0;
+            SetEvent(lpMidiStrm->hEvent);
+            return TRUE;
+        case WINE_MSM_RESUME:
+            /* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
+            lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
+            SetEvent(lpMidiStrm->hEvent);
+            return TRUE;
+        case WINE_MSM_PAUSE:
+            /* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
+            paused = TRUE;
+            SetEvent(lpMidiStrm->hEvent);
+            break;
 	/* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
 	 * by native mcimidi, it doesn't look like a correct one".
 	 * this trick allows to throw it away... but I don't like it.
@@ -1061,60 +1070,62 @@ static	BOOL	MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
 	 * 48 00 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 H..#x..;...#..|.
 	 * 3b 4c 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 ;L..#^..;...#.|.
 	 */
-	lpMidiHdr = (LPMIDIHDR)msg->lParam;
-	lpData = (LPBYTE)lpMidiHdr->lpData;
-	TRACE("Adding %s lpMidiHdr=%p [lpData=0x%p dwBytesRecorded=%u/%u dwFlags=0x%08x size=%lu]\n",
-	      (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", lpMidiHdr,
-	      lpMidiHdr, lpMidiHdr->dwBytesRecorded, lpMidiHdr->dwBufferLength,
-	      lpMidiHdr->dwFlags, msg->wParam);
+        case WINE_MSM_HEADER:
+            /* sets initial tick count for first MIDIHDR */
+            if (!lpMidiStrm->dwStartTicks)
+                lpMidiStrm->dwStartTicks = GetTickCount();
+            lpMidiHdr = (LPMIDIHDR)msg->lParam;
+            lpData = (LPBYTE)lpMidiHdr->lpData;
+            TRACE("Adding %s lpMidiHdr=%p [lpData=0x%p dwBytesRecorded=%u/%u dwFlags=0x%08x size=%lu]\n",
+                  (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", lpMidiHdr,
+                  lpData, lpMidiHdr->dwBytesRecorded, lpMidiHdr->dwBufferLength,
+                  lpMidiHdr->dwFlags, msg->wParam);
 #if 0
-	/* dumps content of lpMidiHdr->lpData
-	 * FIXME: there should be a debug routine somewhere that already does this
-	 * I hate spreading this type of shit all around the code
-	 */
-	for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) {
-	    DWORD	i;
-	    BYTE	ch;
-
-	    for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++)
-		printf("%02x ", lpData[dwToGo + i]);
-	    for (; i < 16; i++)
-		printf("   ");
-	    for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) {
-		ch = lpData[dwToGo + i];
-		printf("%c", (ch >= 0x20 && ch <= 0x7F) ? ch : '.');
-	    }
-	    printf("\n");
-	}
+            /* dumps content of lpMidiHdr->lpData
+             * FIXME: there should be a debug routine somewhere that already does this
+             */
+            for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) {
+                DWORD       i;
+                BYTE        ch;
+
+                for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++)
+                    printf("%02x ", lpData[dwToGo + i]);
+                for (; i < 16; i++)
+                    printf("   ");
+                for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) {
+                    ch = lpData[dwToGo + i];
+                    printf("%c", (ch >= 0x20 && ch <= 0x7F) ? ch : '.');
+                }
+                printf("\n");
+            }
 #endif
-	if (((LPMIDIEVENT)lpData)->dwStreamID != 0 &&
-	    ((LPMIDIEVENT)lpData)->dwStreamID != 0xFFFFFFFF &&
-	    ((LPMIDIEVENT)lpData)->dwStreamID != (DWORD)lpMidiStrm) {
-	    FIXME("Dropping bad %s lpMidiHdr (streamID=%08x)\n",
-		  (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular",
-		  ((LPMIDIEVENT)lpData)->dwStreamID);
-	    lpMidiHdr->dwFlags |= MHDR_DONE;
-	    lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
-
-	    DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
-			   (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
-			   lpwm->mod.dwInstance, (DWORD_PTR)lpMidiHdr, 0);
-	    break;
-	}
-
-	for (lpmh = &lpMidiStrm->lpMidiHdr; *lpmh; lpmh = &(*lpmh)->lpNext);
-	*lpmh = lpMidiHdr;
-	lpMidiHdr = (LPMIDIHDR)msg->lParam;
-	lpMidiHdr->lpNext = 0;
-	lpMidiHdr->dwFlags |= MHDR_INQUEUE;
-	lpMidiHdr->dwFlags &= ~MHDR_DONE;
-
-	break;
-    default:
-	FIXME("Unknown message %d\n", msg->message);
-	break;
+            if (((LPMIDIEVENT)lpData)->dwStreamID != 0 &&
+                ((LPMIDIEVENT)lpData)->dwStreamID != 0xFFFFFFFF &&
+                ((LPMIDIEVENT)lpData)->dwStreamID != (DWORD)lpMidiStrm) {
+                FIXME("Dropping bad %s lpMidiHdr (streamID=%08x)\n",
+                      (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular",
+                      ((LPMIDIEVENT)lpData)->dwStreamID);
+                lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
+                lpMidiHdr->dwFlags |= MHDR_DONE;
+
+                DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
+                               (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
+                               lpwm->mod.dwInstance, (DWORD_PTR)lpMidiHdr, 0);
+                break;
+            }
+
+            lpMidiHdr->lpNext = 0;
+            for (lpmh = &lpMidiStrm->lpMidiHdr; *lpmh; lpmh = &(*lpmh)->lpNext);
+            *lpmh = lpMidiHdr;
+            break;
+        default:
+            FIXME("Unknown message %d\n", msg->message);
+            break;
+        }
+        if (!paused)
+            return TRUE;
+        GetMessageA(msg, 0, 0, 0);
     }
-    return TRUE;
 }
 
 /**************************************************************************
@@ -1335,8 +1346,8 @@ MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
 
     /* wait for thread to have started, and for its queue to be created */
     WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
-    /* start in paused mode */
-    SuspendThread(lpMidiStrm->hThread);
+
+    MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_PAUSE, 0, 0);
 
     TRACE("=> (%u/%d) hMidi=%p ret=%d lpMidiStrm=%p\n",
 	  *lpuDeviceID, lpwm->mld.uDeviceID, *lphMidiStrm, ret, lpMidiStrm);
@@ -1392,14 +1403,9 @@ MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
 
     TRACE("(%p)!\n", hMidiStrm);
 
-    if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
-	ret = MMSYSERR_INVALHANDLE;
-    } else {
-	if (SuspendThread(lpMidiStrm->hThread) == 0xFFFFFFFF) {
-	    ERR("bad Suspend (%d)\n", GetLastError());
-	    ret = MMSYSERR_ERROR;
-	}
-    }
+    if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
+        return MMSYSERR_INVALHANDLE;
+    MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_PAUSE, 0, 0);
     return ret;
 }
 
@@ -1493,24 +1499,9 @@ MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
 
     TRACE("(%p)!\n", hMidiStrm);
 
-    if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
-	ret = MMSYSERR_INVALHANDLE;
-    } else {
-	DWORD	ret;
-
-	/* since we increase the thread suspend count on each midiStreamPause
-	 * there may be a need for several ResumeThread
-	 */
-	do {
-	    ret = ResumeThread(lpMidiStrm->hThread);
-	} while (ret != 0xFFFFFFFF && ret > 1);
-	if (ret == 0xFFFFFFFF) {
-	    ERR("bad Resume (%d)\n", GetLastError());
-	    ret = MMSYSERR_ERROR;
-	} else {
-	    lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
-	}
-    }
+    if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
+        return MMSYSERR_INVALHANDLE;
+    MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_RESUME, 0, 0);
     return ret;
 }
 
@@ -1524,13 +1515,9 @@ MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
 
     TRACE("(%p)!\n", hMidiStrm);
 
-    if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
-	ret = MMSYSERR_INVALHANDLE;
-    } else {
-	/* in case stream has been paused... FIXME is the current state correct ? */
-	midiStreamRestart(hMidiStrm);
-	MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_STOP, 0, 0);
-    }
+    if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
+        return MMSYSERR_INVALHANDLE;
+    MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_STOP, 0, 0);
     return ret;
 }