Jörg Höhle : winmm: MCI_SYSINFO dwRetSize counts characters, not bytes.

Alexandre Julliard julliard at winehq.org
Fri Apr 16 10:56:03 CDT 2010


Module: wine
Branch: master
Commit: c662c35edc09f56e732157a1ba822886bea624d1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c662c35edc09f56e732157a1ba822886bea624d1

Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date:   Fri Apr  9 05:45:07 2010 +0200

winmm: MCI_SYSINFO dwRetSize counts characters, not bytes.

MSDN says the contrary.

---

 dlls/winmm/mci.c       |   17 ++++++-----------
 dlls/winmm/tests/mci.c |   39 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/dlls/winmm/mci.c b/dlls/winmm/mci.c
index f9c65eb..8a66ab4 100644
--- a/dlls/winmm/mci.c
+++ b/dlls/winmm/mci.c
@@ -37,11 +37,6 @@
  * - command table handling isn't thread safe
  */
 
-/* to be cross checked:
- * - heapalloc for *sizeof(WCHAR) when needed
- * - size of string in WCHAR or bytes? (#chars for MCI_INFO, #bytes for MCI_SYSINFO)
- */
-
 #include "config.h"
 #include "wine/port.h"
 
@@ -359,8 +354,9 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
             if (dwParam1 & MCI_NOTIFY)
                 mci_sysinfoW->dwCallback = mci_sysinfoA->dwCallback;
 
+            /* Size is measured in numbers of characters, despite what MSDN says. */
             mci_sysinfoW->dwRetSize = mci_sysinfoA->dwRetSize;
-            mci_sysinfoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mci_sysinfoW->dwRetSize);
+            mci_sysinfoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mci_sysinfoW->dwRetSize * sizeof(WCHAR));
             mci_sysinfoW->dwNumber = mci_sysinfoA->dwNumber;
             mci_sysinfoW->wDeviceType = mci_sysinfoA->wDeviceType;
             return 1;
@@ -383,7 +379,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
                 mci_infoW->dwCallback = mci_infoA->dwCallback;
 
             /* Size is measured in numbers of characters. */
-            mci_infoW->dwRetSize = mci_infoA->dwRetSize; /* it's not the same as SYSINFO !!! */
+            mci_infoW->dwRetSize = mci_infoA->dwRetSize;
             mci_infoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mci_infoW->dwRetSize * sizeof(WCHAR));
             return 1;
         }
@@ -1726,7 +1722,6 @@ static DWORD MCI_WriteString(LPWSTR lpDstStr, DWORD dstSize, LPCWSTR lpSrcStr)
     DWORD	ret = 0;
 
     if (lpSrcStr) {
-        dstSize /= sizeof(WCHAR);
 	if (dstSize <= strlenW(lpSrcStr)) {
 	    lstrcpynW(lpDstStr, lpSrcStr, dstSize - 1);
 	    ret = MCIERR_PARAM_OVERFLOW;
@@ -1830,7 +1825,7 @@ static	DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSW lpParm
 		}
 	    }
 	    LeaveCriticalSection(&WINMM_cs);
-	    ret = s ? MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize / sizeof(WCHAR), s) : MCIERR_OUTOFRANGE;
+	    ret = s ? MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, s) : MCIERR_OUTOFRANGE;
 	} else if (MCI_ALL_DEVICE_ID == uDevID) {
 	    TRACE("MCI_SYSINFO_NAME: device #%d\n", lpParms->dwNumber);
 	    if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, wszHklmMci, 0, 
@@ -1856,7 +1851,7 @@ static	DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSW lpParm
 		    }
 		}
 	    }
-	    ret = s ? MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize / sizeof(WCHAR), s) : MCIERR_OUTOFRANGE;
+	    ret = s ? MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, s) : MCIERR_OUTOFRANGE;
 	} else {
 	    FIXME("MCI_SYSINFO_NAME: nth device of type %d\n", lpParms->wDeviceType);
 	    /* Cheating: what is asked for is the nth device from the registry. */
@@ -1865,7 +1860,7 @@ static	DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSW lpParm
 		ret = MCIERR_OUTOFRANGE;
 	    else {
 		LoadStringW(hWinMM32Instance, LOWORD(lpParms->wDeviceType),
-			    lpParms->lpstrReturn, lpParms->dwRetSize / sizeof(WCHAR));
+			    lpParms->lpstrReturn, lpParms->dwRetSize);
 		ret = 0;
 	    }
 	}
diff --git a/dlls/winmm/tests/mci.c b/dlls/winmm/tests/mci.c
index aa718d7..b064c0c 100644
--- a/dlls/winmm/tests/mci.c
+++ b/dlls/winmm/tests/mci.c
@@ -212,6 +212,7 @@ static void test_openCloseWAVE(HWND hwnd)
         else trace("locale-dependent time format: %s (ms)\n", buf);
     }
 
+    memset(buf, 0, sizeof(buf));
     parm.sys.dwNumber = 1;
     parm.sys.wDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; /* ignored */
     parm.sys.lpstrReturn = buf;
@@ -219,9 +220,45 @@ static void test_openCloseWAVE(HWND hwnd)
     parm.sys.dwCallback = (DWORD_PTR)hwnd;
     err = mciSendCommand(MCI_ALL_DEVICE_ID, MCI_SYSINFO, MCI_SYSINFO_NAME | MCI_SYSINFO_OPEN | MCI_NOTIFY, (DWORD_PTR)&parm);
     ok(!err,"mciCommand MCI_SYSINFO all name 1 open notify: %s\n", dbg_mcierr(err));
-    if(!err) ok(!strcmp(buf,"mysound"),"sysinfo name returned %s\n", buf);
+    if(!err) ok(!strcmp(buf,"mysound"), "sysinfo name returned %s\n", buf);
     test_notification(hwnd, "SYSINFO name notify\n", MCI_NOTIFY_SUCCESSFUL);
 
+    memset(buf, 0, sizeof(buf));
+    parm.sys.dwNumber = 1;
+    parm.sys.wDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; /* ignored */
+    parm.sys.lpstrReturn = buf;
+    parm.sys.dwRetSize = 8; /* mysound\0 */
+    err = mciSendCommand(MCI_ALL_DEVICE_ID, MCI_SYSINFO, MCI_SYSINFO_NAME | MCI_SYSINFO_OPEN, (DWORD_PTR)&parm);
+    ok(!err,"mciCommand MCI_SYSINFO all name 1 open buffer[8]: %s\n", dbg_mcierr(err));
+    if(!err) ok(!strcmp(buf,"mysound"), "sysinfo name returned %s\n", buf);
+
+    /* dwRetSize counts characters, not bytes, despite what MSDN says. */
+    parm.sys.dwNumber = 1;
+    parm.sys.wDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; /* ignored */
+    parm.sys.lpstrReturn = buf;
+    parm.sys.dwRetSize = 8; /* mysound\0 */
+    /* MCI_..._PARMSA and PARMSW share the same layout, use one for both tests. */
+    err = mciSendCommandW(MCI_ALL_DEVICE_ID, MCI_SYSINFO, MCI_SYSINFO_NAME | MCI_SYSINFO_OPEN, (DWORD_PTR)&parm);
+    ok(!err || broken(err==MMSYSERR_NOTSUPPORTED/* Win9x */), "mciCommandW MCI_SYSINFO all name 1 open buffer[8]: %s\n", dbg_mcierr(err));
+    /* TODO strcmpW((LPWSTR)buf,"mysound") */
+
+    parm.sys.dwNumber = 1;
+    parm.sys.wDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; /* ignored */
+    parm.sys.lpstrReturn = buf;
+    parm.sys.dwRetSize = 7; /* too short for mysound\0 */
+    err = mciSendCommandW(MCI_ALL_DEVICE_ID, MCI_SYSINFO, MCI_SYSINFO_NAME | MCI_SYSINFO_OPEN, (DWORD_PTR)&parm);
+    ok(err==MCIERR_PARAM_OVERFLOW || broken(err==MMSYSERR_NOTSUPPORTED/* Win9x */), "mciCommandW MCI_SYSINFO all name 1 open too small: %s\n", dbg_mcierr(err));
+
+    /* Win9x overwrites the tiny buffer and returns success, newer versions signal overflow. */
+    memset(buf, 0, sizeof(buf));
+    parm.sys.dwNumber = 1;
+    parm.sys.wDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; /* ignored */
+    parm.sys.lpstrReturn = buf;
+    parm.sys.dwRetSize = 2; /* too short for mysound\0 */
+    err = mciSendCommand(MCI_ALL_DEVICE_ID, MCI_SYSINFO, MCI_SYSINFO_NAME | MCI_SYSINFO_OPEN, (DWORD_PTR)&parm);
+    ok(err==MCIERR_PARAM_OVERFLOW || broken(!err /* Win9x */),"mciCommand MCI_SYSINFO all name 1 open too small: %s\n", dbg_mcierr(err));
+    if(!err) ok(!strcmp(buf,"mysound"), "sysinfo short name returned %s\n", buf);
+
     err = mciGetDeviceID("all");
     ok(MCI_ALL_DEVICE_ID==err || /* Win9x */(UINT16)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