Module: wine Branch: master Commit: c662c35edc09f56e732157a1ba822886bea624d1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c662c35edc09f56e732157a1ba...
Author: Jörg Höhle hoehle@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);