[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