Jörg Höhle : winmm: Correctly parse the MCI Sysinfo command.
Alexandre Julliard
julliard at winehq.org
Fri Sep 3 10:07:10 CDT 2010
Module: wine
Branch: master
Commit: 565c56c61f1afa6c56734034f53333b748d83656
URL: http://source.winehq.org/git/wine.git/?a=commit;h=565c56c61f1afa6c56734034f53333b748d83656
Author: Jörg Höhle <hoehle at 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);
More information about the wine-cvs
mailing list