Jörg Höhle : winmm: MCI_INFO doesn' t change the output buffer in case of error.
Alexandre Julliard
julliard at winehq.org
Tue Nov 2 11:10:58 CDT 2010
Module: wine
Branch: master
Commit: 22055590f612994c1dceef1911cfd972747f218a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=22055590f612994c1dceef1911cfd972747f218a
Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date: Tue Oct 5 21:09:11 2010 +0200
winmm: MCI_INFO doesn't change the output buffer in case of error.
---
dlls/mciavi32/info.c | 13 ++++---------
dlls/mcicda/mcicda.c | 19 ++++++++-----------
dlls/mciseq/mcimidi.c | 16 +++++++---------
dlls/mciwave/mciwave.c | 21 ++++++++++-----------
dlls/winmm/tests/mci.c | 14 ++++++++++++++
5 files changed, 43 insertions(+), 40 deletions(-)
diff --git a/dlls/mciavi32/info.c b/dlls/mciavi32/info.c
index b2ec030..668464c 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 4c67085..3ec8307 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 ec9a24a..5d15874 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 b2dc1a1..edd63ce 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 1672433..4f89b82 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);
More information about the wine-cvs
mailing list