Commit b95910cc authored by Jörg Höhle's avatar Jörg Höhle Committed by Alexandre Julliard

winmm: More compatible midiIn/Out[Un]Prepare MHDR_* flag handling.

parent 097867de
...@@ -425,20 +425,25 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam) ...@@ -425,20 +425,25 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam)
static DWORD modPrepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwSize) static DWORD modPrepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwSize)
{ {
if (MIDIMAP_IsBadData(mom)) return MMSYSERR_ERROR; if (MIDIMAP_IsBadData(mom)) return MMSYSERR_ERROR;
if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE))
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
if (lpMidiHdr->dwFlags & MHDR_PREPARED)
return MMSYSERR_NOERROR;
lpMidiHdr->dwFlags |= MHDR_PREPARED; lpMidiHdr->dwFlags |= MHDR_PREPARED;
lpMidiHdr->dwFlags &= ~MHDR_DONE; lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */
return MMSYSERR_NOERROR; 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 (MIDIMAP_IsBadData(mom)) return MMSYSERR_ERROR;
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED; if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; return MMSYSERR_INVALPARAM;
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
return MMSYSERR_NOERROR;
if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
return MIDIERR_STILLPLAYING;
lpMidiHdr->dwFlags &= ~MHDR_PREPARED; lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
......
...@@ -565,7 +565,7 @@ static DWORD midClose(WORD wDevID) ...@@ -565,7 +565,7 @@ static DWORD midClose(WORD wDevID)
*/ */
static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) 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 (wDevID >= MIDM_NumDevs) return MMSYSERR_BADDEVICEID;
if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE; if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE;
...@@ -600,15 +600,16 @@ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -600,15 +600,16 @@ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
*/ */
static DWORD midPrepare(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 || if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0)
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
if (lpMidiHdr->dwFlags & MHDR_PREPARED)
return MMSYSERR_NOERROR;
lpMidiHdr->lpNext = 0; lpMidiHdr->lpNext = 0;
lpMidiHdr->dwFlags |= MHDR_PREPARED; lpMidiHdr->dwFlags |= MHDR_PREPARED;
lpMidiHdr->dwBytesRecorded = 0; lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
...@@ -618,17 +619,14 @@ static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -618,17 +619,14 @@ static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
*/ */
static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) static DWORD midUnprepare(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;
if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
lpMidiHdr->lpData == 0)
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED; return MMSYSERR_NOERROR;
if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
return MIDIERR_STILLPLAYING;
lpMidiHdr->dwFlags &= ~MHDR_PREPARED; lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
...@@ -1024,27 +1022,16 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -1024,27 +1022,16 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
*/ */
static DWORD modPrepare(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) { if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
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);
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
} if (lpMidiHdr->dwFlags & MHDR_PREPARED)
return MMSYSERR_NOERROR;
lpMidiHdr->lpNext = 0; lpMidiHdr->lpNext = 0;
lpMidiHdr->dwFlags |= MHDR_PREPARED; lpMidiHdr->dwFlags |= MHDR_PREPARED;
lpMidiHdr->dwFlags &= ~MHDR_DONE; lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
...@@ -1053,15 +1040,12 @@ static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -1053,15 +1040,12 @@ static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
*/ */
static DWORD modUnprepare(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 (midiSeq == NULL) {
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; return MMSYSERR_INVALPARAM;
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
return MMSYSERR_NOERROR;
if (lpMidiHdr->dwFlags & MHDR_INQUEUE) if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
return MIDIERR_STILLPLAYING; return MIDIERR_STILLPLAYING;
lpMidiHdr->dwFlags &= ~MHDR_PREPARED; lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
......
...@@ -455,25 +455,14 @@ static DWORD MIDIOut_Prepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -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); TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize);
if (wDevID >= MIDIOut_NumDevs) { if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
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);
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
} if (lpMidiHdr->dwFlags & MHDR_PREPARED)
return MMSYSERR_NOERROR;
lpMidiHdr->lpNext = 0; lpMidiHdr->lpNext = 0;
lpMidiHdr->dwFlags |= MHDR_PREPARED; lpMidiHdr->dwFlags |= MHDR_PREPARED;
lpMidiHdr->dwFlags &= ~MHDR_DONE; lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
...@@ -484,17 +473,14 @@ static DWORD MIDIOut_Unprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -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); TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize);
if (wDevID >= MIDIOut_NumDevs) { if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
WARN("bad device ID : %d\n", wDevID);
return MMSYSERR_BADDEVICEID;
}
if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0)
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
return MMSYSERR_NOERROR;
if (lpMidiHdr->dwFlags & MHDR_INQUEUE) if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
return MIDIERR_STILLPLAYING; return MIDIERR_STILLPLAYING;
lpMidiHdr->dwFlags &= ~MHDR_PREPARED; lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
...@@ -707,42 +693,27 @@ static DWORD MIDIIn_Prepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -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); TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize);
if (wDevID >= MIDIIn_NumDevs) { if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
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);
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
} if (lpMidiHdr->dwFlags & MHDR_PREPARED)
return MMSYSERR_NOERROR;
lpMidiHdr->lpNext = 0; lpMidiHdr->lpNext = 0;
lpMidiHdr->dwFlags |= MHDR_PREPARED; lpMidiHdr->dwFlags |= MHDR_PREPARED;
lpMidiHdr->dwFlags &= ~MHDR_DONE; lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
static DWORD MIDIIn_Unprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) static DWORD MIDIIn_Unprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{ {
TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize); TRACE("wDevID=%d lpMidiHdr=%p dwSize=%d\n", wDevID, lpMidiHdr, dwSize);
if (wDevID >= MIDIIn_NumDevs) {
WARN("bad device ID : %d\n", wDevID); if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
return MMSYSERR_BADDEVICEID;
}
if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0) {
WARN("Invalid Parameter\n");
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
} if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
if (lpMidiHdr->dwFlags & MHDR_INQUEUE) { return MMSYSERR_NOERROR;
WARN("Still playing\n"); if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
return MIDIERR_STILLPLAYING; return MIDIERR_STILLPLAYING;
}
lpMidiHdr->dwFlags &= ~MHDR_PREPARED; lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
......
...@@ -823,7 +823,7 @@ static DWORD midClose(WORD wDevID) ...@@ -823,7 +823,7 @@ static DWORD midClose(WORD wDevID)
*/ */
static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) 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 (wDevID >= MIDM_NumDevs) return MMSYSERR_BADDEVICEID;
if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE; if (MidiInDev[wDevID].state == -1) return MIDIERR_NODEVICE;
...@@ -859,15 +859,16 @@ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -859,15 +859,16 @@ static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
*/ */
static DWORD midPrepare(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 || if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0)
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
if (lpMidiHdr->dwFlags & MHDR_PREPARED)
return MMSYSERR_NOERROR;
lpMidiHdr->lpNext = 0; lpMidiHdr->lpNext = 0;
lpMidiHdr->dwFlags |= MHDR_PREPARED; lpMidiHdr->dwFlags |= MHDR_PREPARED;
lpMidiHdr->dwBytesRecorded = 0; lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
...@@ -877,17 +878,14 @@ static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -877,17 +878,14 @@ static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
*/ */
static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) static DWORD midUnprepare(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;
if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
lpMidiHdr->lpData == 0)
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED; return MMSYSERR_NOERROR;
if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING; if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
return MIDIERR_STILLPLAYING;
lpMidiHdr->dwFlags &= ~MHDR_PREPARED; lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
...@@ -920,7 +918,6 @@ static DWORD midReset(WORD wDevID) ...@@ -920,7 +918,6 @@ static DWORD midReset(WORD wDevID)
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
/************************************************************************** /**************************************************************************
* midStart [internal] * midStart [internal]
*/ */
...@@ -1584,27 +1581,16 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -1584,27 +1581,16 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
*/ */
static DWORD modPrepare(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) { if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
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);
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
} if (lpMidiHdr->dwFlags & MHDR_PREPARED)
return MMSYSERR_NOERROR;
lpMidiHdr->lpNext = 0; lpMidiHdr->lpNext = 0;
lpMidiHdr->dwFlags |= MHDR_PREPARED; lpMidiHdr->dwFlags |= MHDR_PREPARED;
lpMidiHdr->dwFlags &= ~MHDR_DONE; lpMidiHdr->dwFlags &= ~(MHDR_DONE|MHDR_INQUEUE); /* flags cleared since w2k */
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
...@@ -1613,15 +1599,12 @@ static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) ...@@ -1613,15 +1599,12 @@ static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
*/ */
static DWORD modUnprepare(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) { if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0 || lpMidiHdr->lpData == 0)
WARN("can't unprepare !\n");
return MMSYSERR_NOTENABLED;
}
if (dwSize < offsetof(MIDIHDR,dwOffset) || lpMidiHdr == 0)
return MMSYSERR_INVALPARAM; return MMSYSERR_INVALPARAM;
if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
return MMSYSERR_NOERROR;
if (lpMidiHdr->dwFlags & MHDR_INQUEUE) if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
return MIDIERR_STILLPLAYING; return MIDIERR_STILLPLAYING;
lpMidiHdr->dwFlags &= ~MHDR_PREPARED; lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
......
...@@ -128,30 +128,79 @@ static void test_midiIn_device(UINT udev, HWND hwnd) ...@@ -128,30 +128,79 @@ static void test_midiIn_device(UINT udev, HWND hwnd)
test_notification(hwnd, "midiInOpen", MIM_OPEN, 0); test_notification(hwnd, "midiInOpen", MIM_OPEN, 0);
memset(&mhdr, 0, sizeof(mhdr)); memset(&mhdr, 0, sizeof(mhdr));
mhdr.dwFlags = MHDR_DONE;
mhdr.dwUser = 0x56FA552C; mhdr.dwUser = 0x56FA552C;
mhdr.dwBufferLength = 70000; /* > 64KB! */ mhdr.dwBufferLength = 70000; /* > 64KB! */
mhdr.dwBytesRecorded = 5;
mhdr.lpData = HeapAlloc(GetProcessHeap(), 0 , mhdr.dwBufferLength); mhdr.lpData = HeapAlloc(GetProcessHeap(), 0 , mhdr.dwBufferLength);
ok(mhdr.lpData!=NULL, "No %d bytes of memory!\n", mhdr.dwBufferLength); ok(mhdr.lpData!=NULL, "No %d bytes of memory!\n", mhdr.dwBufferLength);
if (mhdr.lpData) { if (mhdr.lpData) {
rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1); rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1);
ok(rc==MMSYSERR_INVALPARAM, "midiInPrepare tiny rc=%s\n", mmsys_error(rc)); 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)); rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset));
ok(!rc, "midiInPrepare old size rc=%s\n", mmsys_error(rc)); 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)); rc = midiInPrepareHeader(hm, &mhdr, sizeof(mhdr));
ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc)); 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)); rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr));
ok(!rc, "midiInUnprepare rc=%s\n", mmsys_error(rc)); 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); mhdr.dwFlags &= ~MHDR_DONE;
} rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr));
ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser); 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 */ rc = midiInReset(hm); /* Return any pending buffer */
ok(!rc, "midiInReset rc=%s\n", mmsys_error(rc)); 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); rc = midiInClose(hm);
ok(!rc, "midiInClose rc=%s\n", mmsys_error(rc)); 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, "midiInClose", MIM_CLOSE, 0);
test_notification(hwnd, "midiIn over", 0, WHATEVER); test_notification(hwnd, "midiIn over", 0, WHATEVER);
} }
...@@ -290,6 +339,7 @@ static void test_midiOut_device(UINT udev, HWND hwnd) ...@@ -290,6 +339,7 @@ static void test_midiOut_device(UINT udev, HWND hwnd)
} }
memset(&mhdr, 0, sizeof(mhdr)); memset(&mhdr, 0, sizeof(mhdr));
mhdr.dwFlags = MHDR_DONE;
mhdr.dwUser = 0x56FA552C; mhdr.dwUser = 0x56FA552C;
mhdr.dwOffset = 0xDEADBEEF; mhdr.dwOffset = 0xDEADBEEF;
mhdr.dwBufferLength = 70000; /* > 64KB! */ mhdr.dwBufferLength = 70000; /* > 64KB! */
...@@ -298,17 +348,41 @@ static void test_midiOut_device(UINT udev, HWND hwnd) ...@@ -298,17 +348,41 @@ static void test_midiOut_device(UINT udev, HWND hwnd)
if (mhdr.lpData) { if (mhdr.lpData) {
rc = midiOutLongMsg(hm, &mhdr, sizeof(mhdr)); rc = midiOutLongMsg(hm, &mhdr, sizeof(mhdr));
ok(rc==MIDIERR_UNPREPARED, "midiOutLongMsg unprepared rc=%s\n", mmsys_error(rc)); 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); test_notification(hwnd, "midiOutLong unprepared", 0, WHATEVER);
rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1); rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1);
ok(rc==MMSYSERR_INVALPARAM, "midiOutPrepare tiny rc=%s\n", mmsys_error(rc)); 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)); rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset));
ok(!rc, "midiOutPrepare old size rc=%s\n", mmsys_error(rc)); 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)); rc = midiOutPrepareHeader(hm, &mhdr, sizeof(mhdr));
ok(!rc, "midiOutPrepare rc=%s\n", mmsys_error(rc)); 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)); rc = midiOutUnprepareHeader(hm, &mhdr, sizeof(mhdr));
ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc)); 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); HeapFree(GetProcessHeap(), 0, mhdr.lpData);
} }
...@@ -327,6 +401,7 @@ static void test_midiOut_device(UINT udev, HWND hwnd) ...@@ -327,6 +401,7 @@ static void test_midiOut_device(UINT udev, HWND hwnd)
test_notification(hwnd, "midiOutClose", MOM_CLOSE, 0); test_notification(hwnd, "midiOutClose", MOM_CLOSE, 0);
rc = midiOutOpen(&hm, udev, 0, (DWORD_PTR)MYCBINST, CALLBACK_WINDOW); 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)); ok(!rc, "midiOutOpen(dev=%d) 0 CALLBACK_WINDOW rc=%s\n", udev, mmsys_error(rc));
/* PostMessage(hwnd=0) redirects to PostThreadMessage(GetCurrentThreadId()) /* PostMessage(hwnd=0) redirects to PostThreadMessage(GetCurrentThreadId())
* which PeekMessage((HWND)-1) queries. */ * which PeekMessage((HWND)-1) queries. */
......
...@@ -476,9 +476,6 @@ UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut, ...@@ -476,9 +476,6 @@ UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut,
TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize); 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) if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
return MMSYSERR_INVALHANDLE; return MMSYSERR_INVALHANDLE;
/* FIXME: detect MIDIStream handles and enforce 64KB buffer limit on those */ /* FIXME: detect MIDIStream handles and enforce 64KB buffer limit on those */
...@@ -496,13 +493,6 @@ UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut, ...@@ -496,13 +493,6 @@ UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut,
TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize); 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) if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
return MMSYSERR_INVALHANDLE; return MMSYSERR_INVALHANDLE;
...@@ -592,7 +582,7 @@ UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank, ...@@ -592,7 +582,7 @@ UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank,
WORD* lpwPatchArray, UINT uFlags) WORD* lpwPatchArray, UINT uFlags)
{ {
/* not really necessary to support this */ /* 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; return MMSYSERR_NOTSUPPORTED;
} }
...@@ -602,7 +592,7 @@ UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank, ...@@ -602,7 +592,7 @@ UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank,
UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch, UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch,
WORD* lpwKeyArray, UINT uFlags) WORD* lpwKeyArray, UINT uFlags)
{ {
FIXME("not supported yet\n"); FIXME("(%p, %u, %p, %x): Stub\n", hMidiOut, uPatch, lpwKeyArray, uFlags);
return MMSYSERR_NOTSUPPORTED; return MMSYSERR_NOTSUPPORTED;
} }
...@@ -774,9 +764,6 @@ UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn, ...@@ -774,9 +764,6 @@ UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn,
TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize); 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) if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
return MMSYSERR_INVALHANDLE; return MMSYSERR_INVALHANDLE;
...@@ -793,13 +780,6 @@ UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn, ...@@ -793,13 +780,6 @@ UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn,
TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize); 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) if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
return MMSYSERR_INVALHANDLE; return MMSYSERR_INVALHANDLE;
......
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