From b95910ccbc21f731874c11198b930ee6f91be737 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B6rg=20H=C3=B6hle?= Date: Sat, 26 Jan 2013 23:29:31 +0100 Subject: [PATCH] winmm: More compatible midiIn/Out[Un]Prepare MHDR_* flag handling. --- dlls/midimap/midimap.c | 17 ++++--- dlls/winealsa.drv/midi.c | 58 +++++++++--------------- dlls/winecoreaudio.drv/midi.c | 61 +++++++------------------ dlls/wineoss.drv/midi.c | 59 +++++++++--------------- dlls/winmm/tests/midi.c | 85 ++++++++++++++++++++++++++++++++--- dlls/winmm/winmm.c | 24 +--------- 6 files changed, 151 insertions(+), 153 deletions(-) diff --git a/dlls/midimap/midimap.c b/dlls/midimap/midimap.c index 0c54d457d5..c7b8da3bff 100644 --- a/dlls/midimap/midimap.c +++ b/dlls/midimap/midimap.c @@ -425,20 +425,25 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam) static DWORD modPrepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwSize) { if (MIDIMAP_IsBadData(mom)) return MMSYSERR_ERROR; - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE)) + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; + if (lpMidiHdr->dwFlags & MHDR_PREPARED) + return MMSYSERR_NOERROR; lpMidiHdr->dwFlags |= MHDR_PREPARED; - lpMidiHdr->dwFlags &= ~MHDR_DONE; + lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */ return MMSYSERR_NOERROR; } -static DWORD modUnprepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwParam2) +static DWORD modUnprepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwSize) { if (MIDIMAP_IsBadData(mom)) return MMSYSERR_ERROR; - if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED; - if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) + return MMSYSERR_INVALPARAM; + if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) + return MMSYSERR_NOERROR; + if (lpMidiHdr->dwFlags & MHDR_INQUEUE) + return MIDIERR_STILLPLAYING; lpMidiHdr->dwFlags &= ~MHDR_PREPARED; return MMSYSERR_NOERROR; diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c index 279810938a..ee975e3400 100644 --- a/dlls/winealsa.drv/midi.c +++ b/dlls/winealsa.drv/midi.c @@ -565,7 +565,7 @@ static DWORD midClose(WORD wDevID) */ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); if (wDevID >= MIDM_NumDevs) return MMSYSERR_BADDEVICEID; if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE; @@ -600,15 +600,16 @@ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) */ static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0) + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; + if (lpMidiHdr->dwFlags & MHDR_PREPARED) + return MMSYSERR_NOERROR; lpMidiHdr->lpNext = 0; lpMidiHdr->dwFlags |= MHDR_PREPARED; - lpMidiHdr->dwBytesRecorded = 0; + lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */ return MMSYSERR_NOERROR; } @@ -618,17 +619,14 @@ static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) */ static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); - - if (wDevID >= MIDM_NumDevs) return MMSYSERR_BADDEVICEID; - if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE; + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0) + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; - - if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED; - if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; + if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) + return MMSYSERR_NOERROR; + if (lpMidiHdr->dwFlags & MHDR_INQUEUE) + return MIDIERR_STILLPLAYING; lpMidiHdr->dwFlags &= ~MHDR_PREPARED; @@ -1024,27 +1022,16 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) */ static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); - if (midiSeq == NULL) { - WARN("can't prepare !\n"); - return MMSYSERR_NOTENABLED; - } - - /* MS doc says that dwFlags must be set to zero, but (kinda funny) MS mciseq drivers - * asks to prepare MIDIHDR which dwFlags != 0. - * So at least check for the inqueue flag - */ - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0) { - WARN("%p %p %08x %d\n", lpMidiHdr, lpMidiHdr ? lpMidiHdr->lpData : NULL, - lpMidiHdr ? lpMidiHdr->dwFlags : 0, dwSize); + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; - } + if (lpMidiHdr->dwFlags & MHDR_PREPARED) + return MMSYSERR_NOERROR; lpMidiHdr->lpNext = 0; lpMidiHdr->dwFlags |= MHDR_PREPARED; - lpMidiHdr->dwFlags &= ~MHDR_DONE; + lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */ return MMSYSERR_NOERROR; } @@ -1053,15 +1040,12 @@ static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) */ static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); - - if (midiSeq == NULL) { - WARN("can't unprepare !\n"); - return MMSYSERR_NOTENABLED; - } + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0) + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; + if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) + return MMSYSERR_NOERROR; if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; lpMidiHdr->dwFlags &= ~MHDR_PREPARED; diff --git a/dlls/winecoreaudio.drv/midi.c b/dlls/winecoreaudio.drv/midi.c index e84e6dee6b..491fc7e6da 100644 --- a/dlls/winecoreaudio.drv/midi.c +++ b/dlls/winecoreaudio.drv/midi.c @@ -455,25 +455,14 @@ static DWORD MIDIOut_Prepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize); - if (wDevID >= MIDIOut_NumDevs) { - WARN("bad device ID : %d\n", wDevID); - return MMSYSERR_BADDEVICEID; - } - - /* MS doc says that dwFlags must be set to zero, but (kinda funny) MS mciseq drivers - * asks to prepare MIDIHDR which dwFlags != 0. - * So at least check for the inqueue flag - */ - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0) { - WARN("%p %p %08x %lu/%d\n", lpMidiHdr, lpMidiHdr->lpData, - lpMidiHdr->dwFlags, offsetof(MIDIHDR,dwOffset), dwSize); + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; - } + if (lpMidiHdr->dwFlags & MHDR_PREPARED) + return MMSYSERR_NOERROR; lpMidiHdr->lpNext = 0; lpMidiHdr->dwFlags |= MHDR_PREPARED; - lpMidiHdr->dwFlags &= ~MHDR_DONE; + lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */ return MMSYSERR_NOERROR; } @@ -484,17 +473,14 @@ static DWORD MIDIOut_Unprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize); - if (wDevID >= MIDIOut_NumDevs) { - WARN("bad device ID : %d\n", wDevID); - return MMSYSERR_BADDEVICEID; - } - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0) + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; + if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) + return MMSYSERR_NOERROR; if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; lpMidiHdr->dwFlags &= ~MHDR_PREPARED; - return MMSYSERR_NOERROR; } @@ -707,42 +693,27 @@ static DWORD MIDIIn_Prepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize); - if (wDevID >= MIDIIn_NumDevs) { - WARN("bad device ID : %d\n", wDevID); - return MMSYSERR_BADDEVICEID; - } - /* MS doc says that dwFlags must be set to zero, but (kinda funny) MS mciseq drivers - * asks to prepare MIDIHDR which dwFlags != 0. - * So at least check for the inqueue flag - */ - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0) { - WARN("Invalid parameter %p %p %08x %d\n", lpMidiHdr, lpMidiHdr->lpData, - lpMidiHdr->dwFlags, dwSize); + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; - } + if (lpMidiHdr->dwFlags & MHDR_PREPARED) + return MMSYSERR_NOERROR; lpMidiHdr->lpNext = 0; lpMidiHdr->dwFlags |= MHDR_PREPARED; - lpMidiHdr->dwFlags &= ~MHDR_DONE; + lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */ return MMSYSERR_NOERROR; } static DWORD MIDIIn_Unprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize); - if (wDevID >= MIDIIn_NumDevs) { - WARN("bad device ID : %d\n", wDevID); - return MMSYSERR_BADDEVICEID; - } - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0) { - WARN("Invalid Parameter\n"); + + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; - } - if (lpMidiHdr->dwFlags & MHDR_INQUEUE) { - WARN("Still playing\n"); + if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) + return MMSYSERR_NOERROR; + if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; - } lpMidiHdr->dwFlags &= ~MHDR_PREPARED; return MMSYSERR_NOERROR; diff --git a/dlls/wineoss.drv/midi.c b/dlls/wineoss.drv/midi.c index 1c28a76216..0bf5d879ed 100644 --- a/dlls/wineoss.drv/midi.c +++ b/dlls/wineoss.drv/midi.c @@ -823,7 +823,7 @@ static DWORD midClose(WORD wDevID) */ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); if (wDevID >= MIDM_NumDevs) return MMSYSERR_BADDEVICEID; if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE; @@ -859,15 +859,16 @@ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) */ static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0) + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; + if (lpMidiHdr->dwFlags & MHDR_PREPARED) + return MMSYSERR_NOERROR; lpMidiHdr->lpNext = 0; lpMidiHdr->dwFlags |= MHDR_PREPARED; - lpMidiHdr->dwBytesRecorded = 0; + lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */ return MMSYSERR_NOERROR; } @@ -877,17 +878,14 @@ static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) */ static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); - - if (wDevID >= MIDM_NumDevs) return MMSYSERR_BADDEVICEID; - if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE; + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0) + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; - - if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED; - if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; + if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) + return MMSYSERR_NOERROR; + if (lpMidiHdr->dwFlags & MHDR_INQUEUE) + return MIDIERR_STILLPLAYING; lpMidiHdr->dwFlags &= ~MHDR_PREPARED; @@ -920,7 +918,6 @@ static DWORD midReset(WORD wDevID) return MMSYSERR_NOERROR; } - /************************************************************************** * midStart [internal] */ @@ -1584,27 +1581,16 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) */ static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); - if (midiSeqFD == -1) { - WARN("can't prepare !\n"); - return MMSYSERR_NOTENABLED; - } - - /* MS doc says that dwFlags must be set to zero, but (kinda funny) MS mciseq drivers - * asks to prepare MIDIHDR which dwFlags != 0. - * So at least check for the inqueue flag - */ - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || - lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0) { - WARN("%p %p %08x %d\n", lpMidiHdr, lpMidiHdr ? lpMidiHdr->lpData : NULL, - lpMidiHdr ? lpMidiHdr->dwFlags : 0, dwSize); + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; - } + if (lpMidiHdr->dwFlags & MHDR_PREPARED) + return MMSYSERR_NOERROR; lpMidiHdr->lpNext = 0; lpMidiHdr->dwFlags |= MHDR_PREPARED; - lpMidiHdr->dwFlags &= ~MHDR_DONE; + lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */ return MMSYSERR_NOERROR; } @@ -1613,15 +1599,12 @@ static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) */ static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) { - TRACE("(%04X, %p, %08X);\n", wDevID, lpMidiHdr, dwSize); + TRACE("(%04X, %p, %d);\n", wDevID, lpMidiHdr, dwSize); - if (midiSeqFD == -1) { - WARN("can't unprepare !\n"); - return MMSYSERR_NOTENABLED; - } - - if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0) + if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0) return MMSYSERR_INVALPARAM; + if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) + return MMSYSERR_NOERROR; if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; lpMidiHdr->dwFlags &= ~MHDR_PREPARED; diff --git a/dlls/winmm/tests/midi.c b/dlls/winmm/tests/midi.c index f02c4f0fd1..65b5e78e64 100644 --- a/dlls/winmm/tests/midi.c +++ b/dlls/winmm/tests/midi.c @@ -128,30 +128,79 @@ static void test_midiIn_device(UINT udev, HWND hwnd) test_notification(hwnd, "midiInOpen", MIM_OPEN, 0); memset(&mhdr, 0, sizeof(mhdr)); + mhdr.dwFlags = MHDR_DONE; mhdr.dwUser = 0x56FA552C; mhdr.dwBufferLength = 70000; /* > 64KB! */ + mhdr.dwBytesRecorded = 5; mhdr.lpData = HeapAlloc(GetProcessHeap(), 0 , mhdr.dwBufferLength); ok(mhdr.lpData!=NULL, "No %d bytes of memory!\n", mhdr.dwBufferLength); if (mhdr.lpData) { rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1); ok(rc==MMSYSERR_INVALPARAM, "midiInPrepare tiny rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags); + + mhdr.dwFlags |= MHDR_INQUEUE; rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)); ok(!rc, "midiInPrepare old size rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_INQUEUE|MHDR_DONE)/*w9x*/ || + mhdr.dwFlags == MHDR_PREPARED, "dwFlags=%x\n", mhdr.dwFlags); + trace("MIDIHDR flags=%x when unsent\n", mhdr.dwFlags); + + mhdr.dwFlags |= MHDR_INQUEUE|MHDR_DONE; rc = midiInPrepareHeader(hm, &mhdr, sizeof(mhdr)); ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_INQUEUE|MHDR_DONE), "dwFlags=%x\n", mhdr.dwFlags); + + mhdr.dwFlags &= ~MHDR_INQUEUE; rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr)); ok(!rc, "midiInUnprepare rc=%s\n", mmsys_error(rc)); - trace("MIDIHDR flags=%x when unsent\n", mhdr.dwFlags); + ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags); - HeapFree(GetProcessHeap(), 0, mhdr.lpData); - } - ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser); + mhdr.dwFlags &= ~MHDR_DONE; + rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr)); + ok(!rc, "midiInUnprepare rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == 0, "dwFlags=%x\n", mhdr.dwFlags); + + rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)); + ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == MHDR_PREPARED, "dwFlags=%x\n", mhdr.dwFlags); + + mhdr.dwFlags |= MHDR_DONE; + rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)); + ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwBytesRecorded == 5, "BytesRec=%u\n", mhdr.dwBytesRecorded); + + mhdr.dwFlags |= MHDR_DONE; + rc = midiInAddBuffer(hm, &mhdr, sizeof(mhdr)); + ok(!rc, "midiAddBuffer rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_INQUEUE), "dwFlags=%x\n", mhdr.dwFlags); + + /* w95 does not set dwBytesRecorded=0 within midiInAddBuffer. Wine does. */ + if (mhdr.dwBytesRecorded != 0) + trace("dwBytesRecorded %u\n", mhdr.dwBytesRecorded); + rc = midiInAddBuffer(hm, &mhdr, sizeof(mhdr)); + ok(rc==MIDIERR_STILLPLAYING, "midiAddBuffer rc=%s\n", mmsys_error(rc)); + + rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)); + ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_INQUEUE), "dwFlags=%x\n", mhdr.dwFlags); + } rc = midiInReset(hm); /* Return any pending buffer */ ok(!rc, "midiInReset rc=%s\n", mmsys_error(rc)); + test_notification(hwnd, "midiInReset", MIM_LONGDATA, (DWORD_PTR)&mhdr); + + ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_DONE), "dwFlags=%x\n", mhdr.dwFlags); + rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr)); + ok(!rc, "midiInUnprepare rc=%s\n", mmsys_error(rc)); + + ok(mhdr.dwBytesRecorded == 0, "Did some MIDI HW send %u bytes?\n", mhdr.dwBytesRecorded); rc = midiInClose(hm); ok(!rc, "midiInClose rc=%s\n", mmsys_error(rc)); + + ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser); + HeapFree(GetProcessHeap(), 0, mhdr.lpData); test_notification(hwnd, "midiInClose", MIM_CLOSE, 0); test_notification(hwnd, "midiIn over", 0, WHATEVER); } @@ -290,6 +339,7 @@ static void test_midiOut_device(UINT udev, HWND hwnd) } memset(&mhdr, 0, sizeof(mhdr)); + mhdr.dwFlags = MHDR_DONE; mhdr.dwUser = 0x56FA552C; mhdr.dwOffset = 0xDEADBEEF; mhdr.dwBufferLength = 70000; /* > 64KB! */ @@ -298,17 +348,41 @@ static void test_midiOut_device(UINT udev, HWND hwnd) if (mhdr.lpData) { rc = midiOutLongMsg(hm, &mhdr, sizeof(mhdr)); ok(rc==MIDIERR_UNPREPARED, "midiOutLongMsg unprepared rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags); test_notification(hwnd, "midiOutLong unprepared", 0, WHATEVER); rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1); ok(rc==MMSYSERR_INVALPARAM, "midiOutPrepare tiny rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags); + + /* Since at least w2k, midiOutPrepare clears the DONE and INQUEUE flags. w95 didn't. */ + /* mhdr.dwFlags |= MHDR_INQUEUE; would cause w95 to return STILLPLAYING from Unprepare */ rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)); ok(!rc, "midiOutPrepare old size rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_DONE)/*w9x*/ || + mhdr.dwFlags == MHDR_PREPARED, "dwFlags=%x\n", mhdr.dwFlags); + trace("MIDIHDR flags=%x when unsent\n", mhdr.dwFlags); + + /* No flag is cleared when already prepared. */ + mhdr.dwFlags |= MHDR_DONE|MHDR_INQUEUE; rc = midiOutPrepareHeader(hm, &mhdr, sizeof(mhdr)); ok(!rc, "midiOutPrepare rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_DONE|MHDR_INQUEUE), "dwFlags=%x\n", mhdr.dwFlags); + + mhdr.dwFlags |= MHDR_INQUEUE; + rc = midiOutUnprepareHeader(hm, &mhdr, sizeof(mhdr)); + ok(rc==MIDIERR_STILLPLAYING, "midiOutUnprepare rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_DONE|MHDR_INQUEUE), "dwFlags=%x\n", mhdr.dwFlags); + + mhdr.dwFlags &= ~MHDR_INQUEUE; rc = midiOutUnprepareHeader(hm, &mhdr, sizeof(mhdr)); ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc)); - trace("MIDIHDR flags=%x when unsent\n", mhdr.dwFlags); + ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags); + + mhdr.dwFlags |= MHDR_INQUEUE; + rc = midiOutUnprepareHeader(hm, &mhdr, sizeof(mhdr)); + ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc)); + ok(mhdr.dwFlags == (MHDR_INQUEUE|MHDR_DONE), "dwFlags=%x\n", mhdr.dwFlags); HeapFree(GetProcessHeap(), 0, mhdr.lpData); } @@ -327,6 +401,7 @@ static void test_midiOut_device(UINT udev, HWND hwnd) test_notification(hwnd, "midiOutClose", MOM_CLOSE, 0); rc = midiOutOpen(&hm, udev, 0, (DWORD_PTR)MYCBINST, CALLBACK_WINDOW); + /* w95 broken(rc==MMSYSERR_INVALPARAM) see WINMM_CheckCallback */ ok(!rc, "midiOutOpen(dev=%d) 0 CALLBACK_WINDOW rc=%s\n", udev, mmsys_error(rc)); /* PostMessage(hwnd=0) redirects to PostThreadMessage(GetCurrentThreadId()) * which PeekMessage((HWND)-1) queries. */ diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c index aecb9cfe47..bb686e0aa6 100644 --- a/dlls/winmm/winmm.c +++ b/dlls/winmm/winmm.c @@ -476,9 +476,6 @@ UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut, TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize); - if (lpMidiOutHdr == NULL || uSize < offsetof(MIDIHDR,dwOffset)) - return MMSYSERR_INVALPARAM; - if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; /* FIXME: detect MIDIStream handles and enforce 64KB buffer limit on those */ @@ -496,13 +493,6 @@ UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut, TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize); - if (lpMidiOutHdr == NULL || uSize < offsetof(MIDIHDR,dwOffset)) - return MMSYSERR_INVALPARAM; - - if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) { - return MMSYSERR_NOERROR; - } - if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; @@ -592,7 +582,7 @@ UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank, WORD* lpwPatchArray, UINT uFlags) { /* not really necessary to support this */ - FIXME("not supported yet\n"); + FIXME("(%p, %u, %p, %x): Stub\n", hMidiOut, uBank, lpwPatchArray, uFlags); return MMSYSERR_NOTSUPPORTED; } @@ -602,7 +592,7 @@ UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank, UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch, WORD* lpwKeyArray, UINT uFlags) { - FIXME("not supported yet\n"); + FIXME("(%p, %u, %p, %x): Stub\n", hMidiOut, uPatch, lpwKeyArray, uFlags); return MMSYSERR_NOTSUPPORTED; } @@ -774,9 +764,6 @@ UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn, TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize); - if (lpMidiInHdr == NULL || uSize < offsetof(MIDIHDR,dwOffset)) - return MMSYSERR_INVALPARAM; - if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; @@ -793,13 +780,6 @@ UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn, TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize); - if (lpMidiInHdr == NULL || uSize < offsetof(MIDIHDR,dwOffset)) - return MMSYSERR_INVALPARAM; - - if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) { - return MMSYSERR_NOERROR; - } - if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL) return MMSYSERR_INVALHANDLE; -- 2.32.0.93.g670b81a890