mmsystem 16bit questions
Joerg-Cyril.Hoehle at t-systems.com
Joerg-Cyril.Hoehle at t-systems.com
Fri Feb 15 11:08:13 CST 2013
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.23#L994
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