winmm: MCI_INFO doesn't change the output buffer in case of error.

This commit is contained in:
Jörg Höhle 2010-10-05 21:09:11 +02:00 committed by Alexandre Julliard
parent a9f9b34e17
commit 22055590f6
5 changed files with 43 additions and 40 deletions

View File

@ -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); WARN("Don't know this info command (%u)\n", dwFlags);
ret = MCIERR_UNRECOGNIZED_COMMAND; ret = MCIERR_UNRECOGNIZED_COMMAND;
} }
if (str) { if (!ret) {
if (strlenW(str) + 1 > lpParms->dwRetSize) { WCHAR zero = 0;
ret = MCIERR_PARAM_OVERFLOW; /* Only mciwave, mciseq and mcicda set dwRetSize (since NT). */
} else { lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize);
lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize);
} }
} else {
lpParms->lpstrReturn[0] = 0;
}
LeaveCriticalSection(&wma->cs); LeaveCriticalSection(&wma->cs);
return ret; return ret;
} }

View File

@ -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); WARN("Don't know this info command (%u)\n", dwFlags);
ret = MCIERR_MISSING_PARAMETER; ret = MCIERR_MISSING_PARAMETER;
} }
if (str) { if (!ret) {
if (lpParms->dwRetSize <= strlenW(str)) { TRACE("=> %s\n", debugstr_w(str));
lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize - 1); if (lpParms->dwRetSize) {
ret = MCIERR_PARAM_OVERFLOW; WCHAR zero = 0;
} else { /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize
strcpyW(lpParms->lpstrReturn, str); * to the number of characters written, excluding \0. */
lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize);
} else ret = MCIERR_PARAM_OVERFLOW;
} }
} else {
*lpParms->lpstrReturn = 0;
}
TRACE("=> %s (%d)\n", debugstr_w(lpParms->lpstrReturn), ret);
if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY)) if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY))
MCICDA_Notify(lpParms->dwCallback, wmcda, MCI_NOTIFY_SUCCESSFUL); MCICDA_Notify(lpParms->dwCallback, wmcda, MCI_NOTIFY_SUCCESSFUL);
return ret; return ret;

View File

@ -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); WARN("Don't know this info command (%u)\n", dwFlags);
return MCIERR_UNRECOGNIZED_COMMAND; return MCIERR_UNRECOGNIZED_COMMAND;
} }
if (str) { if (!ret) {
if (lpParms->dwRetSize <= strlenW(str)) { if (lpParms->dwRetSize) {
lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize - 1); WCHAR zero = 0;
ret = MCIERR_PARAM_OVERFLOW; /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize
} else { * to the number of characters written, excluding \0. */
strcpyW(lpParms->lpstrReturn, str); lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize);
} } else ret = MCIERR_PARAM_OVERFLOW;
} else {
*lpParms->lpstrReturn = 0;
} }
return ret; return ret;
} }

View File

@ -1665,6 +1665,8 @@ static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW l
if (!lpParms || !lpParms->lpstrReturn) if (!lpParms || !lpParms->lpstrReturn)
return MCIERR_NULL_PARAMETER_BLOCK; return MCIERR_NULL_PARAMETER_BLOCK;
TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize);
if (wmw == NULL) { if (wmw == NULL) {
ret = MCIERR_INVALID_DEVICE_ID; ret = MCIERR_INVALID_DEVICE_ID;
} else { } 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 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}; 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)) { switch (dwFlags & ~(MCI_WAIT|MCI_NOTIFY)) {
case MCI_INFO_PRODUCT: str = wszAudio; break; case MCI_INFO_PRODUCT: str = wszAudio; break;
case MCI_INFO_FILE: str = wmw->lpFileName; 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; case MCI_WAVE_OUTPUT: str = wszWaveOut; break;
default: default:
WARN("Don't know this info command (%u)\n", dwFlags); WARN("Don't know this info command (%u)\n", dwFlags);
ret = MCIERR_UNRECOGNIZED_COMMAND; ret = MCIERR_UNRECOGNIZED_KEYWORD;
} }
} }
if (str) { if (!ret) {
if (strlenW(str) + 1 > lpParms->dwRetSize) { if (lpParms->dwRetSize) {
ret = MCIERR_PARAM_OVERFLOW; WCHAR zero = 0;
} else { /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize
lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize); * to the number of characters written, excluding \0. */
} lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize);
} else { } else ret = MCIERR_PARAM_OVERFLOW;
lpParms->lpstrReturn[0] = 0;
} }
if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY)) if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY))
WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL); WAVE_mciNotify(lpParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);

View File

@ -30,6 +30,7 @@
static MCIERROR ok_saved = MCIERR_FILE_NOT_FOUND; static MCIERROR ok_saved = MCIERR_FILE_NOT_FOUND;
typedef union { typedef union {
MCI_INFO_PARMS info;
MCI_STATUS_PARMS status; MCI_STATUS_PARMS status;
MCI_WAVE_SET_PARMS set; MCI_WAVE_SET_PARMS set;
MCI_WAVE_OPEN_PARMS open; 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(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); 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"); 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); 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);