Commit 96291a4b authored by Christian Costa's avatar Christian Costa Committed by Alexandre Julliard

winealsa.drv: Handle midi sysex greater than a buffer.

parent 2afc8fcd
...@@ -374,27 +374,34 @@ static DWORD WINAPI midRecThread(LPVOID arg) ...@@ -374,27 +374,34 @@ static DWORD WINAPI midRecThread(LPVOID arg)
break; break;
case SND_SEQ_EVENT_SYSEX: case SND_SEQ_EVENT_SYSEX:
{ {
int pos = 0;
int len = ev->data.ext.len; int len = ev->data.ext.len;
LPBYTE ptr = (BYTE*) ev->data.ext.ptr; LPBYTE ptr = (BYTE*) ev->data.ext.ptr;
LPMIDIHDR lpMidiHdr; LPMIDIHDR lpMidiHdr;
/* FIXME: Should handle sysex greater than lpMidiHdr->dwBufferLength */
EnterCriticalSection(&crit_sect); EnterCriticalSection(&crit_sect);
while (len) {
if ((lpMidiHdr = MidiInDev[wDevID].lpQueueHdr) != NULL) { if ((lpMidiHdr = MidiInDev[wDevID].lpQueueHdr) != NULL) {
if (lpMidiHdr->dwBytesRecorded + len <= lpMidiHdr->dwBufferLength) { int copylen = min(len, lpMidiHdr->dwBufferLength - lpMidiHdr->dwBytesRecorded);
memcpy(lpMidiHdr->lpData + lpMidiHdr->dwBytesRecorded, ptr, len); memcpy(lpMidiHdr->lpData + lpMidiHdr->dwBytesRecorded, ptr + pos, copylen);
lpMidiHdr->dwBytesRecorded += len; lpMidiHdr->dwBytesRecorded += copylen;
if (*(ptr + (len-1)) == 0xF7) { len -= copylen;
pos += copylen;
/* We check if we reach the end of buffer or the end of sysex before notifying
* to handle the case where ALSA splitted the sysex into several events */
if ((lpMidiHdr->dwBytesRecorded == lpMidiHdr->dwBufferLength) ||
(*(BYTE*)(lpMidiHdr->lpData + lpMidiHdr->dwBytesRecorded - 1) == 0xF7)) {
lpMidiHdr->dwFlags &= ~MHDR_INQUEUE; lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
lpMidiHdr->dwFlags |= MHDR_DONE; lpMidiHdr->dwFlags |= MHDR_DONE;
MidiInDev[wDevID].lpQueueHdr = (LPMIDIHDR)lpMidiHdr->lpNext; MidiInDev[wDevID].lpQueueHdr = (LPMIDIHDR)lpMidiHdr->lpNext;
if (MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD_PTR)lpMidiHdr, dwTime) != MMSYSERR_NOERROR) if (MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD_PTR)lpMidiHdr, dwTime) != MMSYSERR_NOERROR)
WARN("Couldn't notify client\n"); WARN("Couldn't notify client\n");
} }
} else } else {
FIXME("No enough space in the buffer to store sysex!\n"); FIXME("Sysex data received but no buffer to store it!\n");
} else break;
FIXME("Sysex received but no buffer to store it!\n"); }
}
LeaveCriticalSection(&crit_sect); LeaveCriticalSection(&crit_sect);
} }
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment