From b0fc000ce1fef6067d921040965e055f5e09d926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20H=C3=B6hle?= Date: Wed, 23 Jan 2013 09:47:27 +0100 Subject: [PATCH] winmm: Prevent some MIDI race conditions. --- dlls/winealsa.drv/midi.c | 37 ++++++++++++++++--------------------- dlls/wineoss.drv/midi.c | 17 ++++++----------- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c index 11b0f30a11e..748fa79980f 100644 --- a/dlls/winealsa.drv/midi.c +++ b/dlls/winealsa.drv/midi.c @@ -389,9 +389,9 @@ static DWORD WINAPI midRecThread(LPVOID arg) * to handle the case where ALSA split the sysex into several events */ if ((lpMidiHdr->dwBytesRecorded == lpMidiHdr->dwBufferLength) || (*(BYTE*)(lpMidiHdr->lpData + lpMidiHdr->dwBytesRecorded - 1) == 0xF7)) { + MidiInDev[wDevID].lpQueueHdr = lpMidiHdr->lpNext; lpMidiHdr->dwFlags &= ~MHDR_INQUEUE; lpMidiHdr->dwFlags |= MHDR_DONE; - MidiInDev[wDevID].lpQueueHdr = lpMidiHdr->lpNext; MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD_PTR)lpMidiHdr, dwTime); } } else { @@ -478,6 +478,16 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) return MMSYSERR_ERROR; } + MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); + + MidiInDev[wDevID].lpQueueHdr = NULL; + MidiInDev[wDevID].dwTotalPlayed = 0; + MidiInDev[wDevID].bufsize = 0x3FFF; + MidiInDev[wDevID].midiDesc = *lpDesc; + MidiInDev[wDevID].state = 0; + MidiInDev[wDevID].incLen = 0; + MidiInDev[wDevID].startTime = 0; + /* Connect our app port to the device port */ if (snd_seq_connect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port) < 0) return MMSYSERR_NOTENABLED; @@ -497,16 +507,6 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) TRACE("Created thread for midi-in\n"); } - MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); - - MidiInDev[wDevID].lpQueueHdr = NULL; - MidiInDev[wDevID].dwTotalPlayed = 0; - MidiInDev[wDevID].bufsize = 0x3FFF; - MidiInDev[wDevID].midiDesc = *lpDesc; - MidiInDev[wDevID].state = 0; - MidiInDev[wDevID].incLen = 0; - MidiInDev[wDevID].startTime = 0; - MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L); return MMSYSERR_NOERROR; } @@ -644,12 +644,11 @@ static DWORD midReset(WORD wDevID) EnterCriticalSection(&crit_sect); while (MidiInDev[wDevID].lpQueueHdr) { - MidiInDev[wDevID].lpQueueHdr->dwFlags &= ~MHDR_INQUEUE; - MidiInDev[wDevID].lpQueueHdr->dwFlags |= MHDR_DONE; - /* FIXME: when called from 16 bit, lpQueueHdr needs to be a segmented ptr */ - MIDI_NotifyClient(wDevID, MIM_LONGDATA, - (DWORD_PTR)MidiInDev[wDevID].lpQueueHdr, dwTime); - MidiInDev[wDevID].lpQueueHdr = MidiInDev[wDevID].lpQueueHdr->lpNext; + LPMIDIHDR lpMidiHdr = MidiInDev[wDevID].lpQueueHdr; + MidiInDev[wDevID].lpQueueHdr = lpMidiHdr->lpNext; + lpMidiHdr->dwFlags &= ~MHDR_INQUEUE; + lpMidiHdr->dwFlags |= MHDR_DONE; + MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD_PTR)lpMidiHdr, dwTime); } LeaveCriticalSection(&crit_sect); @@ -726,10 +725,6 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) WARN("bad dwFlags\n"); return MMSYSERR_INVALFLAG; } - if (!MidiOutDev[wDevID].bEnabled) { - TRACE("disabled wDevID\n"); - return MMSYSERR_NOTENABLED; - } MidiOutDev[wDevID].lpExtra = 0; diff --git a/dlls/wineoss.drv/midi.c b/dlls/wineoss.drv/midi.c index 2b3d4333a8a..bd013e1ef5d 100644 --- a/dlls/wineoss.drv/midi.c +++ b/dlls/wineoss.drv/midi.c @@ -563,9 +563,9 @@ static void midReceiveChar(WORD wDevID, unsigned char value, DWORD dwTime) } if (sbfb && lpMidiHdr != NULL) { lpMidiHdr = MidiInDev[wDevID].lpQueueHdr; + MidiInDev[wDevID].lpQueueHdr = lpMidiHdr->lpNext; lpMidiHdr->dwFlags &= ~MHDR_INQUEUE; lpMidiHdr->dwFlags |= MHDR_DONE; - MidiInDev[wDevID].lpQueueHdr = lpMidiHdr->lpNext; MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD_PTR)lpMidiHdr, dwTime); } LeaveCriticalSection(&crit_sect); @@ -906,12 +906,11 @@ static DWORD midReset(WORD wDevID) EnterCriticalSection(&crit_sect); while (MidiInDev[wDevID].lpQueueHdr) { - MidiInDev[wDevID].lpQueueHdr->dwFlags &= ~MHDR_INQUEUE; - MidiInDev[wDevID].lpQueueHdr->dwFlags |= MHDR_DONE; - /* FIXME: when called from 16 bit, lpQueueHdr needs to be a segmented ptr */ - MIDI_NotifyClient(wDevID, MIM_LONGDATA, - (DWORD_PTR)MidiInDev[wDevID].lpQueueHdr, dwTime); - MidiInDev[wDevID].lpQueueHdr = MidiInDev[wDevID].lpQueueHdr->lpNext; + LPMIDIHDR lpMidiHdr = MidiInDev[wDevID].lpQueueHdr; + MidiInDev[wDevID].lpQueueHdr = lpMidiHdr->lpNext; + lpMidiHdr->dwFlags &= ~MHDR_INQUEUE; + lpMidiHdr->dwFlags |= MHDR_DONE; + MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD_PTR)lpMidiHdr, dwTime); } LeaveCriticalSection(&crit_sect); @@ -1102,10 +1101,6 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) WARN("bad dwFlags\n"); return MMSYSERR_INVALFLAG; } - if (!MidiOutDev[wDevID].bEnabled) { - TRACE("disabled wDevID\n"); - return MMSYSERR_NOTENABLED; - } MidiOutDev[wDevID].lpExtra = 0;