Hi,
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: http://source.winehq.org/source/dlls/mmsystem.dll16/mmsystem.c#L1287
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, ¶m1, ¶m2); http://source.winehq.org/source/dlls/mmsystem.dll16/message16.c?v=wine-1.5.2...
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