Module: wine Branch: master Commit: 565c56c61f1afa6c56734034f53333b748d83656 URL: http://source.winehq.org/git/wine.git/?a=commit;h=565c56c61f1afa6c56734034f5...
Author: Jörg Höhle hoehle@users.sourceforge.net Date: Fri Sep 3 06:33:52 2010 +0200
winmm: Correctly parse the MCI Sysinfo command.
---
dlls/winmm/mci.c | 79 ++++++++++++++++++++++++++++++++++------------- dlls/winmm/tests/mci.c | 23 +++++++++++++- 2 files changed, 78 insertions(+), 24 deletions(-)
diff --git a/dlls/winmm/mci.c b/dlls/winmm/mci.c index 7a3cd8f..b7799c8 100644 --- a/dlls/winmm/mci.c +++ b/dlls/winmm/mci.c @@ -544,6 +544,23 @@ static DWORD MCI_GetDevTypeFromFileName(LPCWSTR fileName, LPWSTR buf, UINT len) return MCIERR_EXTENSION_NOT_FOUND; }
+/************************************************************************** + * MCI_GetDevTypeFromResource [internal] + */ +static UINT MCI_GetDevTypeFromResource(LPCWSTR lpstrName) +{ + WCHAR buf[32]; + UINT uDevType; + for (uDevType = MCI_DEVTYPE_FIRST; uDevType <= MCI_DEVTYPE_LAST; uDevType++) { + if (LoadStringW(hWinMM32Instance, uDevType, buf, sizeof(buf) / sizeof(WCHAR))) { + /* FIXME: ignore digits suffix */ + if (!strcmpiW(buf, lpstrName)) + return uDevType; + } + } + return 0; +} + #define MAX_MCICMDTABLE 20 #define MCI_COMMAND_TABLE_NOT_LOADED 0xFFFE
@@ -1319,21 +1336,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet, HeapFree(GetProcessHeap(), 0, devType); if (dwRet) goto errCleanUp; - } else if (!strcmpW(verb, wszSysinfo)) { - /* System commands are not subject to auto-open. */ - /* It's too early to handle Sysinfo here because the - * requirements on dev depend on the flags: - * alias with INSTALLNAME, name like "waveaudio" - * with QUANTITY and NAME. */ - data[4] = MCI_ALL_DEVICE_ID; - if (MCI_ALL_DEVICE_ID != uDevID) { - /* FIXME: Map device name like waveaudio to MCI_DEVTYPE_xyz */ - uDevID = mciGetDeviceIDW(dev); - wmd = MCI_GetDriver(uDevID); - if (wmd) - data[4] = wmd->wType; - } - } else if (!strcmpW(verb, wszSound) || !strcmpW(verb, wszBreak)) { + } else if (!strcmpW(verb, wszSysinfo) || !strcmpW(verb, wszSound) || !strcmpW(verb, wszBreak)) { /* Prevent auto-open for system commands. */ } else if ((MCI_ALL_DEVICE_ID != uDevID) && !(wmd = MCI_GetDriver(mciGetDeviceIDW(dev)))) { /* auto open */ @@ -1409,11 +1412,32 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet, data[0] = (DWORD_PTR)hwndCallback; }
- if (wMsg == MCI_OPEN && strcmpW(verb, wszOpen)) { - ERR("Cannot open with command %s\n", debugstr_w(verb)); - dwRet = MCIERR_INTERNAL; - wMsg = 0; - goto errCleanUp; + switch (wMsg) { + case MCI_OPEN: + if (strcmpW(verb, wszOpen)) { + FIXME("Cannot open with command %s\n", debugstr_w(verb)); + dwRet = MCIERR_INTERNAL; + wMsg = 0; + goto errCleanUp; + } + break; + case MCI_SYSINFO: + /* Requirements on dev depend on the flags: + * alias with INSTALLNAME, name like "digitalvideo" + * with QUANTITY and NAME. */ + { + LPMCI_SYSINFO_PARMSW lpParms = (LPMCI_SYSINFO_PARMSW)data; + lpParms->wDeviceType = MCI_ALL_DEVICE_ID; + if (uDevID != MCI_ALL_DEVICE_ID) { + if (dwFlags & MCI_SYSINFO_INSTALLNAME) + wmd = MCI_GetDriver(mciGetDeviceIDW(dev)); + else if (!(lpParms->wDeviceType = MCI_GetDevTypeFromResource(dev))) { + dwRet = MCIERR_DEVICE_TYPE_REQUIRED; + goto errCleanUp; + } + } + } + break; }
TRACE("[%d, %s, %08x, %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx]\n", @@ -1799,7 +1823,17 @@ static DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSW lpParm } else { TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers of type %d\n", lpParms->wDeviceType); FIXME("Don't know how to get # of MCI devices of a given type\n"); - cnt = 1; + /* name = LoadStringW(hWinMM32Instance, LOWORD(lpParms->wDeviceType)) + * then lookup registry and/or system.ini for name, ignoring digits suffix */ + switch (LOWORD(lpParms->wDeviceType)) { + case MCI_DEVTYPE_CD_AUDIO: + case MCI_DEVTYPE_WAVEFORM_AUDIO: + case MCI_DEVTYPE_SEQUENCER: + cnt = 1; + break; + default: /* "digitalvideo" gets 0 because it's not in the registry */ + cnt = 0; + } } } *(DWORD*)lpParms->lpstrReturn = cnt; @@ -1814,7 +1848,8 @@ static DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSW lpParm wmd->lpstrDeviceType); } else { *lpParms->lpstrReturn = 0; - ret = MCIERR_INVALID_DEVICE_ID; + ret = (uDevID == MCI_ALL_DEVICE_ID) + ? MCIERR_CANNOT_USE_ALL : MCIERR_INVALID_DEVICE_NAME; } TRACE("(%d) => %s\n", lpParms->dwNumber, debugstr_w(lpParms->lpstrReturn)); break; diff --git a/dlls/winmm/tests/mci.c b/dlls/winmm/tests/mci.c index 382ff6a..8adc46b 100644 --- a/dlls/winmm/tests/mci.c +++ b/dlls/winmm/tests/mci.c @@ -263,6 +263,19 @@ static void test_mciParser(HWND hwnd) err = mciSendString("open all", buf, sizeof(buf), NULL); todo_wine ok(err==MCIERR_CANNOT_USE_ALL,"open all: %s\n", dbg_mcierr(err));
+ /* avivideo is not a known MCI_DEVTYPE resource name */ + err = mciSendString("sysinfo avivideo quantity", buf, sizeof(buf), hwnd); + ok(err==MCIERR_DEVICE_TYPE_REQUIRED,"sysinfo sequencer quantity: %s\n", dbg_mcierr(err)); + + err = mciSendString("sysinfo digitalvideo quantity", buf, sizeof(buf), hwnd); + ok(!err,"sysinfo digitalvideo quantity: %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"0"), "sysinfo digitalvideo quantity returned %s\n", buf); + + /* quantity 0 yet open 1 (via type "avivideo"), fun */ + err = mciSendString("sysinfo digitalvideo quantity open", buf, sizeof(buf), hwnd); + ok(!err,"sysinfo digitalvideo quantity open: %s\n", dbg_mcierr(err)); + if(!err) ok(!strcmp(buf,"1"), "sysinfo digitalvideo quantity open returned %s\n", buf); + err = mciSendString("put a window at 0 0", buf, sizeof(buf), NULL); todo_wine ok(err==MCIERR_BAD_INTEGER,"put incomplete rect: %s\n", dbg_mcierr(err));
@@ -425,10 +438,16 @@ static void test_openCloseWAVE(HWND hwnd) if(!err) ok(!strcmp(buf,"mysound"), "sysinfo short name returned %s\n", buf);
err = mciSendString("sysinfo mysound quantity open", buf, sizeof(buf), hwnd); - todo_wine ok(err==MCIERR_DEVICE_TYPE_REQUIRED,"sysinfo alias quantity returned %s\n", dbg_mcierr(err)); + ok(err==MCIERR_DEVICE_TYPE_REQUIRED,"sysinfo alias quantity: %s\n", dbg_mcierr(err));
err = mciSendString("sysinfo nosuchalias quantity open", buf, sizeof(buf), hwnd); - todo_wine ok(err==MCIERR_DEVICE_TYPE_REQUIRED,"sysinfo unknown quantity open returned %s\n", dbg_mcierr(err)); + ok(err==MCIERR_DEVICE_TYPE_REQUIRED,"sysinfo unknown quantity open: %s\n", dbg_mcierr(err)); + + err = mciSendString("sysinfo all installname", buf, sizeof(buf), hwnd); + ok(err==MCIERR_CANNOT_USE_ALL,"sysinfo all installname: %s\n", dbg_mcierr(err)); + + err = mciSendString("sysinfo nodev installname", buf, sizeof(buf), hwnd); + ok(err==MCIERR_INVALID_DEVICE_NAME,"sysinfo nodev installname: %s\n", dbg_mcierr(err));
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);