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