[PATCH 1/3] winmm: Fix mciSendString command parsing on 64-bit.

Octavian Voicu octavian.voicu at gmail.com
Tue Aug 24 21:55:39 CDT 2010


---
 dlls/winmm/mci.c |  113 ++++++++++++++++++++++++++++++------------------------
 1 files changed, 63 insertions(+), 50 deletions(-)

diff --git a/dlls/winmm/mci.c b/dlls/winmm/mci.c
index f65aee7..4c30b55 100644
--- a/dlls/winmm/mci.c
+++ b/dlls/winmm/mci.c
@@ -961,7 +961,7 @@ static	WORD		MCI_GetMessage(LPCWSTR lpCmd)
 /**************************************************************************
  * 				MCI_GetDWord			[internal]
  */
-static	BOOL		MCI_GetDWord(DWORD_PTR* data, LPWSTR* ptr)
+static	BOOL		MCI_GetDWord(BYTE* data, LPWSTR* ptr)
 {
     DWORD	val;
     LPWSTR	ret;
@@ -974,7 +974,7 @@ static	BOOL		MCI_GetDWord(DWORD_PTR* data, LPWSTR* ptr)
     default:	return FALSE;
     }
 
-    *data |= val;
+    *(DWORD*)data |= val;
     *ptr = ret;
     return TRUE;
 }
@@ -1014,7 +1014,7 @@ static	DWORD	MCI_GetString(LPWSTR* str, LPWSTR* args)
 /**************************************************************************
  * 				MCI_ParseOptArgs		[internal]
  */
-static	DWORD	MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
+static	DWORD	MCI_ParseOptArgs(BYTE* data, int _offset, LPCWSTR lpCmd,
 				 LPWSTR args, LPDWORD dwFlags)
 {
     int		len, offset;
@@ -1047,7 +1047,7 @@ static	DWORD	MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
 		inCst = TRUE;	cflg = flg;	break;
 	    case MCI_END_CONSTANT:
 		/* there may be additional integral values after flag in constant */
-		if (inCst && MCI_GetDWord(&(data[offset]), &args)) {
+		if (inCst && MCI_GetDWord(data+offset, &args)) {
 		    *dwFlags |= cflg;
 		}
 		inCst = FALSE;	cflg = 0;
@@ -1080,25 +1080,25 @@ static	DWORD	MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
 		    break;
 		case MCI_INTEGER:
 		    if (inCst) {
-			data[offset] |= flg;
+			*(DWORD*)(data+offset) |= flg;
 			*dwFlags |= cflg;
 			inCst = FALSE;
 			TRACE("flag=%08x constant=%08x\n", cflg, flg);
 		    } else {
 			*dwFlags |= flg;
-			if (!MCI_GetDWord(&(data[offset]), &args)) {
+			if (!MCI_GetDWord(data+offset, &args)) {
 			    return MCIERR_BAD_INTEGER;
 			}
-			TRACE("flag=%08x int=%ld\n", flg, data[offset]);
+			TRACE("flag=%08x int=%d\n", flg, *(DWORD*)(data+offset));
 		    }
 		    break;
 		case MCI_RECT:
-		    /* store rect in data (offset..offset+3) */
+		    /* store rect in data (offset..offset+3*sizeof(DWORD)) */
 		    *dwFlags |= flg;
-		    if (!MCI_GetDWord(&(data[offset+0]), &args) ||
-			!MCI_GetDWord(&(data[offset+1]), &args) ||
-			!MCI_GetDWord(&(data[offset+2]), &args) ||
-			!MCI_GetDWord(&(data[offset+3]), &args)) {
+		    if (!MCI_GetDWord(data+offset+0*sizeof(DWORD), &args) ||
+			!MCI_GetDWord(data+offset+1*sizeof(DWORD), &args) ||
+			!MCI_GetDWord(data+offset+2*sizeof(DWORD), &args) ||
+			!MCI_GetDWord(data+offset+3*sizeof(DWORD), &args)) {
 			ERR("Bad rect %s\n", debugstr_w(args));
 			return MCIERR_BAD_INTEGER;
 		    }
@@ -1106,9 +1106,9 @@ static	DWORD	MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
 		    break;
 		case MCI_STRING:
 		    *dwFlags |= flg;
-		    if ((dwRet = MCI_GetString((LPWSTR*)&data[offset], &args)))
+		    if ((dwRet = MCI_GetString((LPWSTR*)(data+offset), &args)))
 			return dwRet;
-		    TRACE("flag=%08x string=%s\n", flg, debugstr_w((LPWSTR)data[offset]));
+		    TRACE("flag=%08x string=%s\n", flg, debugstr_w(*(LPWSTR*)(data+offset)));
 		    break;
 		default:	ERR("oops\n");
 		}
@@ -1123,10 +1123,10 @@ static	DWORD	MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
 		case MCI_END_COMMAND_LIST:
 		case MCI_CONSTANT:
 		case MCI_FLAG:			break;
-		case MCI_INTEGER:		if (!inCst) offset++;	break;
+		case MCI_INTEGER:		if (!inCst) offset += sizeof(DWORD);	break;
 		case MCI_END_CONSTANT:
-		case MCI_STRING:		offset++; break;
-		case MCI_RECT:			offset += 4; break;
+		case MCI_STRING:		offset += sizeof(DWORD_PTR); break;
+		case MCI_RECT:			offset += 4 * sizeof(DWORD); break;
 		default:			ERR("oops\n");
 		}
 	    }
@@ -1135,7 +1135,7 @@ static	DWORD	MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
 	    WARN("Optarg %s not found\n", debugstr_w(args));
 	    return MCIERR_UNRECOGNIZED_COMMAND;
 	}
-	if (offset == MCI_DATA_SIZE) {
+	if (offset >= MCI_DATA_SIZE * sizeof(DWORD_PTR)) {
 	    ERR("Internal data[] buffer overflow\n");
 	    return MCIERR_PARSER_INTERNAL;
 	}
@@ -1147,14 +1147,16 @@ static	DWORD	MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
  * 				MCI_HandleReturnValues	[internal]
  */
 static	DWORD	MCI_HandleReturnValues(DWORD dwRet, LPWINE_MCIDRIVER wmd, DWORD retType,
-                                       DWORD_PTR* data, LPWSTR lpstrRet, UINT uRetLen)
+                                       BYTE* data, LPWSTR lpstrRet, UINT uRetLen)
 {
-    static const WCHAR wszLd  [] = {'%','l','d',0};
-    static const WCHAR wszLd4 [] = {'%','l','d',' ','%','l','d',' ','%','l','d',' ','%','l','d',0};
+    static const WCHAR wszD   [] = {'%','d',0};
+    static const WCHAR wszD4  [] = {'%','d',' ','%','d',' ','%','d',' ','%','d',0};
     static const WCHAR wszCol3[] = {'%','0','2','d',':','%','0','2','d',':','%','0','2','d',0};
     static const WCHAR wszCol4[] = {'%','0','2','d',':','%','0','2','d',':','%','0','2','d',':','%','0','2','d',0};
 
     if (lpstrRet) {
+	DWORD *ptrRet = (DWORD*)(data + sizeof(DWORD_PTR));
+
 	switch (retType) {
 	case 0: /* nothing to return */
 	    break;
@@ -1162,29 +1164,29 @@ static	DWORD	MCI_HandleReturnValues(DWORD dwRet, LPWINE_MCIDRIVER wmd, DWORD ret
 	    switch (dwRet & 0xFFFF0000ul) {
 	    case 0:
 	    case MCI_INTEGER_RETURNED:
-		snprintfW(lpstrRet, uRetLen, wszLd, data[1]);
+		snprintfW(lpstrRet, uRetLen, wszD, ptrRet[0]);
 		break;
 	    case MCI_RESOURCE_RETURNED:
-		/* return string which ID is HIWORD(data[1]),
+		/* return string which ID is HIWORD(ptrRet[0]),
 		 * string is loaded from mmsystem.dll */
-		LoadStringW(hWinMM32Instance, HIWORD(data[1]), lpstrRet, uRetLen);
+		LoadStringW(hWinMM32Instance, HIWORD(ptrRet[0]), lpstrRet, uRetLen);
 		break;
 	    case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER:
-		/* return string which ID is HIWORD(data[1]),
+		/* return string which ID is HIWORD(ptrRet[0]),
 		 * string is loaded from driver */
 		/* FIXME: this is wrong for a 16 bit handle */
 		LoadStringW(GetDriverModuleHandle(wmd->hDriver),
-			    HIWORD(data[1]), lpstrRet, uRetLen);
+			    HIWORD(ptrRet[0]), lpstrRet, uRetLen);
 		break;
 	    case MCI_COLONIZED3_RETURN:
 		snprintfW(lpstrRet, uRetLen, wszCol3,
-			  LOBYTE(LOWORD(data[1])), HIBYTE(LOWORD(data[1])),
-			  LOBYTE(HIWORD(data[1])));
+			  LOBYTE(LOWORD(ptrRet[0])), HIBYTE(LOWORD(ptrRet[0])),
+			  LOBYTE(HIWORD(ptrRet[0])));
 		break;
 	    case MCI_COLONIZED4_RETURN:
 		snprintfW(lpstrRet, uRetLen, wszCol4,
-			  LOBYTE(LOWORD(data[1])), HIBYTE(LOWORD(data[1])),
-			  LOBYTE(HIWORD(data[1])), HIBYTE(HIWORD(data[1])));
+			  LOBYTE(LOWORD(ptrRet[0])), HIBYTE(LOWORD(ptrRet[0])),
+			  LOBYTE(HIWORD(ptrRet[0])), HIBYTE(HIWORD(ptrRet[0])));
 		break;
 	    default:	ERR("Ooops (%04X)\n", HIWORD(dwRet));
 	    }
@@ -1192,11 +1194,11 @@ static	DWORD	MCI_HandleReturnValues(DWORD dwRet, LPWINE_MCIDRIVER wmd, DWORD ret
 	case MCI_STRING:
 	    switch (dwRet & 0xFFFF0000ul) {
 	    case 0:
-		/* nothing to do data[1] == lpstrRet */
+		/* nothing to do ptrRet[0] == lpstrRet */
 		break;
 	    case MCI_INTEGER_RETURNED:
-		data[1] = *(LPDWORD)lpstrRet;
-		snprintfW(lpstrRet, uRetLen, wszLd, data[1]);
+		ptrRet[0] = *(LPDWORD)lpstrRet;
+		snprintfW(lpstrRet, uRetLen, wszD, ptrRet[0]);
 		break;
 	    default:
 		WARN("Oooch. MCI_STRING and HIWORD(dwRet)=%04x\n", HIWORD(dwRet));
@@ -1205,9 +1207,9 @@ static	DWORD	MCI_HandleReturnValues(DWORD dwRet, LPWINE_MCIDRIVER wmd, DWORD ret
 	    break;
 	case MCI_RECT:
 	    if (dwRet & 0xFFFF0000ul)
-		WARN("Oooch. MCI_STRING and HIWORD(dwRet)=%04x\n", HIWORD(dwRet));
-	    snprintfW(lpstrRet, uRetLen, wszLd4,
-                      data[1], data[2], data[3], data[4]);
+		WARN("Oooch. MCI_RECT and HIWORD(dwRet)=%04x\n", HIWORD(dwRet));
+	    snprintfW(lpstrRet, uRetLen, wszD4,
+                      ptrRet[0], ptrRet[1], ptrRet[2], ptrRet[3]);
 	    break;
 	default:		ERR("oops\n");
 	}
@@ -1261,6 +1263,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
     if (!strcmpW(verb, wszOpen)) {
 	LPWSTR	devType, tmp;
         WCHAR	buf[128];
+        LPMCI_OPEN_PARMSW lpOpenParms = (LPMCI_OPEN_PARMSW)data;
 
 	/* case dev == 'new' has to be handled */
 	if (!strcmpW(dev, wszNew)) {
@@ -1271,7 +1274,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
 		if (tmp) *tmp = '\0';
 		devType = str_dup_upper(devType);
 		if (tmp) *tmp = ' ';
-		/* dwFlags and data[2] will be correctly set in ParseOpt loop */
+		/* dwFlags and lpOpenParms->lpstrDeviceType will be correctly set in ParseOpt loop */
 	    } else {
 		WARN("open new requires device type\n");
 		dwRet = MCIERR_MISSING_DEVICE_NAME;
@@ -1282,15 +1285,15 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
 	    tmp = devType; devType = dev; dev = tmp;
 
 	    dwFlags |= MCI_OPEN_TYPE;
-	    data[2] = (DWORD_PTR)devType;
+	    lpOpenParms->lpstrDeviceType = devType;
 	    devType = str_dup_upper(devType);
 	    dwFlags |= MCI_OPEN_ELEMENT;
-	    data[3] = (DWORD_PTR)dev;
+	    lpOpenParms->lpstrElementName = dev;
 	} else if (DRIVER_GetLibName(dev, wszMci, buf, sizeof(buf))) {
             /* this is the name of a mci driver's type */
 	    tmp = strchrW(dev, ' ');
 	    if (tmp) *tmp = '\0';
-	    data[2] = (DWORD_PTR)dev;
+	    lpOpenParms->lpstrDeviceType = dev;
 	    devType = str_dup_upper(dev);
 	    if (tmp) *tmp = ' ';
 	    dwFlags |= MCI_OPEN_TYPE;
@@ -1301,7 +1304,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
 		if (tmp) *tmp = '\0';
 		devType = str_dup_upper(devType);
 		if (tmp) *tmp = ' ';
-		/* dwFlags and data[2] will be correctly set in ParseOpt loop */
+		/* dwFlags and lpOpenParms->lpstrDeviceType will be correctly set in ParseOpt loop */
 	    } else {
 		if ((dwRet = MCI_GetDevTypeFromFileName(dev, buf, sizeof(buf))))
 		    goto errCleanUp;
@@ -1309,7 +1312,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
 		devType = str_dup_upper(buf);
 	    }
 	    dwFlags |= MCI_OPEN_ELEMENT;
-	    data[3] = (DWORD_PTR)dev;
+	    lpOpenParms->lpstrElementName = dev;
 	}
 	if (MCI_ALL_DEVICE_ID == uDevID) {
 	    dwRet = MCIERR_CANNOT_USE_ALL;
@@ -1334,13 +1337,15 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
 	 * requirements on dev depend on the flags:
 	 * alias with INSTALLNAME, name like "waveaudio"
 	 * with QUANTITY and NAME. */
-	data[4] = MCI_ALL_DEVICE_ID;
+	LPMCI_SYSINFO_PARMSW lpSysinfoParms = (LPMCI_SYSINFO_PARMSW)data;
+
+	lpSysinfoParms->wDeviceType = 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;
+		lpSysinfoParms->wDeviceType = wmd->wType;
 	}
     } else if (!strcmpW(verb, wszSound) || !strcmpW(verb, wszBreak)) {
 	/* Prevent auto-open for system commands. */
@@ -1383,18 +1388,26 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
     }
 
     /* set return information */
+    offset = sizeof(DWORD_PTR); /* skip over dwCallback field */
     switch (retType = MCI_GetReturnType(lpCmd)) {
-    case 0:		offset = 1;	break;
-    case MCI_INTEGER:	offset = 2;	break;
-    case MCI_STRING:	data[1] = (DWORD_PTR)lpstrRet; data[2] = uRetLen; offset = 3; break;
-    case MCI_RECT:	offset = 5;	break;
+    case 0:		break;
+    case MCI_INTEGER:	offset += sizeof(DWORD); break;
+    case MCI_STRING:	offset += sizeof(DWORD_PTR) + sizeof(DWORD); break;
+    case MCI_RECT:	offset += 4 * sizeof(DWORD); break;
     default:	ERR("oops\n");
     }
 
+    if (retType == MCI_STRING) {
+        LPMCI_INFO_PARMSW lpInfoParms = (LPMCI_INFO_PARMSW)data;
+
+        lpInfoParms->lpstrReturn = lpstrRet;
+        lpInfoParms->dwRetSize = uRetLen;
+    }
+
     TRACE("verb=%s on dev=%s; offset=%d\n", 
           debugstr_w(verb), debugstr_w(dev), offset);
 
-    if ((dwRet = MCI_ParseOptArgs(data, offset, lpCmd, args, &dwFlags)))
+    if ((dwRet = MCI_ParseOptArgs((BYTE*)data, offset, lpCmd, args, &dwFlags)))
 	goto errCleanUp;
 
     /* set up call back */
@@ -1420,7 +1433,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
 	dwRet = MCI_SendCommand(wmd ? wmd->wDeviceID : uDevID, MCI_GetMessage(lpCmd), dwFlags, (DWORD_PTR)data);
     }
     TRACE("=> 1/ %x (%s)\n", dwRet, debugstr_w(lpstrRet));
-    dwRet = MCI_HandleReturnValues(dwRet, wmd, retType, data, lpstrRet, uRetLen);
+    dwRet = MCI_HandleReturnValues(dwRet, wmd, retType, (BYTE*)data, lpstrRet, uRetLen);
     TRACE("=> 2/ %x (%s)\n", dwRet, debugstr_w(lpstrRet));
 
 errCleanUp:
-- 
1.7.0.4




More information about the wine-patches mailing list