mmsystem 16bit questions

Joerg-Cyril.Hoehle at Joerg-Cyril.Hoehle at
Fri Feb 15 11:08:13 CST 2013


I noticed some dubious differences among winmm16 functions. I believe
there should be none, but perhaps I'm missing some 16bit idiosyncrasies?

Please compare waveOutPrepareHeader16, Unprepare16 and waveOutWrite16:

UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut,       /* [in] */
                                       SEGPTR lpsegWaveOutHdr,    /* [???] */
                                       UINT16 uSize)              /* [in] */
{   [...]
    return MMSYSTDRV_Message(..., WODM_UNPREPARE, lpsegWaveOutHdr, uSize);

UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut,       /* [in] */
                             LPWAVEHDR lpsegWaveOutHdr, /* [???] NOTE: SEGPTR */
                             UINT16 uSize)              /* [in] */
{   [...]
    return MMSYSTDRV_Message(..., WODM_WRITE, (DWORD_PTR)lpsegWaveOutHdr, uSize);

The mmsystem.spec knows no difference:
pascal  waveOutPrepareHeader(word segptr word) waveOutPrepareHeader16
pascal  waveOutUnprepareHeader(word segptr word) waveOutUnprepareHeader16
pascal  waveOutWrite(word segptr word) waveOutWrite16

I believe:
 - SEGPTR should be used everywhere the .spec says;
 - (DWORD_PTR) cast then becomes obsolete.
Shall I submit a patch?

Furthermore, how to perform a 16bit NULL pointer check?
waveInUnPrepareHeader16 uses:
    LPWAVEHDR           lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
    if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
waveInAddBuffer16 directly uses:
    if (lpsegWaveInHdr == NULL) return MMSYSERR_INVALPARAM;

Last but not least, some but not all of the functions check for a NULL
pointer.  Why only some?
When the check is missing, it looks like MMSYSTDRV_Message will crash
when calling:
    map = drvtype->mapmsg16to32W(msg, &param1, &param2);

I don't know whether the check should occur or if we should let the
app crash (all I know is that native MCI_PLAY crashes on w2k when
given MCI_FROM/TO or callback flags with a NULL MCI_PARMS pointer,
whereas Wine returns INVALPARAM, whereas a NULL pointer is ok in native
when not setting any flags that require access via the pointer).

If the check shall be done, then I believe that it should occur
centrally in MMSYSTDRV_Message, not within the wave/midi* functions,
such that if an app calls e.g. waveInMessage16(WIDM_UNPREPARE) that
dispatches to MMSYSTDRV_Message, the check is not bypassed.

BTW, MMSYSTDRV_WaveOut_UnMap16To32W forgets to deallocate the wh32
when waveOutPrepare fails.  Same with wave in and MIDI.

Thank you for 16bit enlightening,
      Jörg Höhle

More information about the wine-devel mailing list