diff --git a/dlls/mciavi32/info.c b/dlls/mciavi32/info.c index b2ec0308cdd..668464cded1 100644 --- a/dlls/mciavi32/info.c +++ b/dlls/mciavi32/info.c @@ -211,16 +211,11 @@ DWORD MCIAVI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_INFO_PARMSW lpParms) WARN("Don't know this info command (%u)\n", dwFlags); ret = MCIERR_UNRECOGNIZED_COMMAND; } - if (str) { - if (strlenW(str) + 1 > lpParms->dwRetSize) { - ret = MCIERR_PARAM_OVERFLOW; - } else { - lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize); - } - } else { - lpParms->lpstrReturn[0] = 0; + if (!ret) { + WCHAR zero = 0; + /* Only mciwave, mciseq and mcicda set dwRetSize (since NT). */ + lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize); } - LeaveCriticalSection(&wma->cs); return ret; } diff --git a/dlls/mcicda/mcicda.c b/dlls/mcicda/mcicda.c index 4c67085de00..3ec83077729 100644 --- a/dlls/mcicda/mcicda.c +++ b/dlls/mcicda/mcicda.c @@ -650,18 +650,15 @@ static DWORD MCICDA_Info(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms) WARN("Don't know this info command (%u)\n", dwFlags); ret = MCIERR_MISSING_PARAMETER; } - if (str) { - if (lpParms->dwRetSize <= strlenW(str)) { - lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize - 1); - ret = MCIERR_PARAM_OVERFLOW; - } else { - strcpyW(lpParms->lpstrReturn, str); - } - } else { - *lpParms->lpstrReturn = 0; + if (!ret) { + TRACE("=> %s\n", debugstr_w(str)); + if (lpParms->dwRetSize) { + WCHAR zero = 0; + /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize + * to the number of characters written, excluding \0. */ + lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize); + } else ret = MCIERR_PARAM_OVERFLOW; } - TRACE("=> %s (%d)\n", debugstr_w(lpParms->lpstrReturn), ret); - if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY)) MCICDA_Notify(lpParms->dwCallback, wmcda, MCI_NOTIFY_SUCCESSFUL); return ret; diff --git a/dlls/mciseq/mcimidi.c b/dlls/mciseq/mcimidi.c index ec9a24ae4f9..5d15874c4e1 100644 --- a/dlls/mciseq/mcimidi.c +++ b/dlls/mciseq/mcimidi.c @@ -1600,15 +1600,13 @@ static DWORD MIDI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms) WARN("Don't know this info command (%u)\n", dwFlags); return MCIERR_UNRECOGNIZED_COMMAND; } - if (str) { - if (lpParms->dwRetSize <= strlenW(str)) { - lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize - 1); - ret = MCIERR_PARAM_OVERFLOW; - } else { - strcpyW(lpParms->lpstrReturn, str); - } - } else { - *lpParms->lpstrReturn = 0; + if (!ret) { + if (lpParms->dwRetSize) { + WCHAR zero = 0; + /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize + * to the number of characters written, excluding \0. */ + lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize); + } else ret = MCIERR_PARAM_OVERFLOW; } return ret; } diff --git a/dlls/mciwave/mciwave.c b/dlls/mciwave/mciwave.c index b2dc1a14009..edd63cec25c 100644 --- a/dlls/mciwave/mciwave.c +++ b/dlls/mciwave/mciwave.c @@ -1665,6 +1665,8 @@ static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW l if (!lpParms || !lpParms->lpstrReturn) return MCIERR_NULL_PARAMETER_BLOCK; + TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize); + if (wmw == NULL) { ret = MCIERR_INVALID_DEVICE_ID; } else { @@ -1672,8 +1674,6 @@ static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW l static const WCHAR wszWaveIn [] = {'W','i','n','e',' ','W','a','v','e',' ','I','n',0}; static const WCHAR wszWaveOut[] = {'W','i','n','e',' ','W','a','v','e',' ','O','u','t',0}; - TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize); - switch (dwFlags & ~(MCI_WAIT|MCI_NOTIFY)) { case MCI_INFO_PRODUCT: str = wszAudio; break; case MCI_INFO_FILE: str = wmw->lpFileName; break; @@ -1681,17 +1681,16 @@ static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW l case MCI_WAVE_OUTPUT: str = wszWaveOut; break; default: WARN("Don't know this info command (%u)\n", dwFlags); - ret = MCIERR_UNRECOGNIZED_COMMAND; + ret = MCIERR_UNRECOGNIZED_KEYWORD; } } - if (str) { - if (strlenW(str) + 1 > lpParms->dwRetSize) { - ret = MCIERR_PARAM_OVERFLOW; - } else { - lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize); - } - } else { - lpParms->lpstrReturn[0] = 0; + if (!ret) { + if (lpParms->dwRetSize) { + WCHAR zero = 0; + /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize + * to the number of characters written, excluding \0. */ + lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize); + } else ret = MCIERR_PARAM_OVERFLOW; } if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY)) WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL); diff --git a/dlls/winmm/tests/mci.c b/dlls/winmm/tests/mci.c index 1672433f5e1..4f89b82a23c 100644 --- a/dlls/winmm/tests/mci.c +++ b/dlls/winmm/tests/mci.c @@ -30,6 +30,7 @@ static MCIERROR ok_saved = MCIERR_FILE_NOT_FOUND; typedef union { + MCI_INFO_PARMS info; MCI_STATUS_PARMS status; MCI_WAVE_SET_PARMS set; MCI_WAVE_OPEN_PARMS open; @@ -486,6 +487,19 @@ static void test_openCloseWAVE(HWND hwnd) ok(err==MCIERR_INVALID_DEVICE_NAME || broken(err==MMSYSERR_NOTSUPPORTED/* Win9x */), "mciCommand MCI_SYSINFO nodev installname: %s\n", dbg_mcierr(err)); ok(!strcmp(buf,"K"), "output buffer %s\n", buf); + buf[1] = 'L'; + parm.info.lpstrReturn = buf; + parm.info.dwRetSize = 2; + err = mciSendCommand(1, MCI_INFO, MCI_INFO_PRODUCT, (DWORD_PTR)&parm); + ok(!err, "mciCommand MCI_INFO product: %s\n", dbg_mcierr(err)); + ok(buf[0] && !buf[1], "info product output buffer %s\n", buf); + + buf[0] = 'K'; + parm.info.dwRetSize = sizeof(buf); + err = mciSendCommandW(1, MCI_INFO, 0x07000000, (DWORD_PTR)&parm); + ok(err==MCIERR_UNRECOGNIZED_KEYWORD, "mciCommand MCI_INFO other: %s\n", dbg_mcierr(err)); + ok(!strcmp(buf,"K"), "info output buffer %s\n", buf); + err = mciGetDeviceID("all"); ok(MCI_ALL_DEVICE_ID==err || /* Win9x */(WORD)MCI_ALL_DEVICE_ID==err,"mciGetDeviceID all returned %u, expected %d\n", err, MCI_ALL_DEVICE_ID);