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