mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-23 03:52:12 -04:00
win midi: increase BUFFER_INITIAL_SIZE, wait no more than 3 seconds (#1109)
Avoid midiOutUnprepareHeader() which contains use after free (tested with ASan). * manually unset `MHDR_INQUEUE` flag * never delete buffer * prepare header for new handle
This commit is contained in:
parent
01d31eb495
commit
2d296deeb0
@ -131,7 +131,9 @@ typedef struct
|
|||||||
|
|
||||||
static win_midi_song_t song;
|
static win_midi_song_t song;
|
||||||
|
|
||||||
#define BUFFER_INITIAL_SIZE 1024
|
#define BUFFER_INITIAL_SIZE 8192
|
||||||
|
|
||||||
|
#define PLAYER_THREAD_WAIT_TIME 3000
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -185,13 +187,29 @@ static void CALLBACK MidiStreamProc(HMIDIOUT hMidi, UINT uMsg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AllocateBuffer(const unsigned int size)
|
static void PrepareHeader(void)
|
||||||
{
|
{
|
||||||
MIDIHDR *hdr = &MidiStreamHdr;
|
MIDIHDR *hdr = &MidiStreamHdr;
|
||||||
MMRESULT mmr;
|
MMRESULT mmr;
|
||||||
|
|
||||||
|
hdr->lpData = (LPSTR)buffer.data;
|
||||||
|
hdr->dwBytesRecorded = 0;
|
||||||
|
hdr->dwBufferLength = buffer.size;
|
||||||
|
mmr = midiOutPrepareHeader((HMIDIOUT)hMidiStream, hdr, sizeof(MIDIHDR));
|
||||||
|
if (mmr != MMSYSERR_NOERROR)
|
||||||
|
{
|
||||||
|
MidiError("midiOutPrepareHeader", mmr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AllocateBuffer(const unsigned int size)
|
||||||
|
{
|
||||||
if (buffer.data)
|
if (buffer.data)
|
||||||
{
|
{
|
||||||
|
MIDIHDR *hdr = &MidiStreamHdr;
|
||||||
|
MMRESULT mmr;
|
||||||
|
|
||||||
|
hdr->dwFlags &= ~MHDR_INQUEUE;
|
||||||
mmr = midiOutUnprepareHeader((HMIDIOUT)hMidiStream, hdr, sizeof(MIDIHDR));
|
mmr = midiOutUnprepareHeader((HMIDIOUT)hMidiStream, hdr, sizeof(MIDIHDR));
|
||||||
if (mmr != MMSYSERR_NOERROR)
|
if (mmr != MMSYSERR_NOERROR)
|
||||||
{
|
{
|
||||||
@ -202,14 +220,7 @@ static void AllocateBuffer(const unsigned int size)
|
|||||||
buffer.size = PADDED_SIZE(size);
|
buffer.size = PADDED_SIZE(size);
|
||||||
buffer.data = I_Realloc(buffer.data, buffer.size);
|
buffer.data = I_Realloc(buffer.data, buffer.size);
|
||||||
|
|
||||||
hdr->lpData = (LPSTR)buffer.data;
|
PrepareHeader();
|
||||||
hdr->dwBytesRecorded = 0;
|
|
||||||
hdr->dwBufferLength = buffer.size;
|
|
||||||
mmr = midiOutPrepareHeader((HMIDIOUT)hMidiStream, hdr, sizeof(MIDIHDR));
|
|
||||||
if (mmr != MMSYSERR_NOERROR)
|
|
||||||
{
|
|
||||||
MidiError("midiOutPrepareHeader", mmr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteBufferPad(void)
|
static void WriteBufferPad(void)
|
||||||
@ -1424,7 +1435,14 @@ static boolean I_WIN_InitMusic(int device)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocateBuffer(BUFFER_INITIAL_SIZE);
|
if (buffer.data == NULL)
|
||||||
|
{
|
||||||
|
AllocateBuffer(BUFFER_INITIAL_SIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrepareHeader();
|
||||||
|
}
|
||||||
|
|
||||||
hBufferReturnEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
hBufferReturnEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
@ -1465,7 +1483,7 @@ static void I_WIN_StopSong(void *handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetEvent(hExitEvent);
|
SetEvent(hExitEvent);
|
||||||
WaitForSingleObject(hPlayerThread, INFINITE);
|
WaitForSingleObject(hPlayerThread, PLAYER_THREAD_WAIT_TIME);
|
||||||
CloseHandle(hPlayerThread);
|
CloseHandle(hPlayerThread);
|
||||||
hPlayerThread = NULL;
|
hPlayerThread = NULL;
|
||||||
|
|
||||||
@ -1660,27 +1678,14 @@ static void I_WIN_ShutdownMusic(void)
|
|||||||
{
|
{
|
||||||
MidiError("midiStreamRestart", mmr);
|
MidiError("midiStreamRestart", mmr);
|
||||||
}
|
}
|
||||||
WaitForSingleObject(hBufferReturnEvent, INFINITE);
|
WaitForSingleObject(hBufferReturnEvent, PLAYER_THREAD_WAIT_TIME);
|
||||||
mmr = midiStreamStop(hMidiStream);
|
mmr = midiStreamStop(hMidiStream);
|
||||||
if (mmr != MMSYSERR_NOERROR)
|
if (mmr != MMSYSERR_NOERROR)
|
||||||
{
|
{
|
||||||
MidiError("midiStreamStop", mmr);
|
MidiError("midiStreamStop", mmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer.data)
|
buffer.position = 0;
|
||||||
{
|
|
||||||
MidiStreamHdr.dwFlags &= ~MHDR_INQUEUE;
|
|
||||||
mmr = midiOutUnprepareHeader((HMIDIOUT)hMidiStream, &MidiStreamHdr,
|
|
||||||
sizeof(MIDIHDR));
|
|
||||||
if (mmr != MMSYSERR_NOERROR)
|
|
||||||
{
|
|
||||||
MidiError("midiOutUnprepareHeader", mmr);
|
|
||||||
}
|
|
||||||
free(buffer.data);
|
|
||||||
buffer.data = NULL;
|
|
||||||
buffer.size = 0;
|
|
||||||
buffer.position = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmr = midiStreamClose(hMidiStream);
|
mmr = midiStreamClose(hMidiStream);
|
||||||
if (mmr != MMSYSERR_NOERROR)
|
if (mmr != MMSYSERR_NOERROR)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user