winmm: Use proper structure where possible to fix command string parsing on 64-bit.
This commit is contained in:
parent
5029331f55
commit
41a5b37b7a
119
dlls/winmm/mci.c
119
dlls/winmm/mci.c
|
@ -970,7 +970,7 @@ static WORD MCI_GetMessage(LPCWSTR lpCmd)
|
|||
/**************************************************************************
|
||||
* MCI_GetDWord [internal]
|
||||
*/
|
||||
static BOOL MCI_GetDWord(DWORD_PTR* data, LPWSTR* ptr)
|
||||
static BOOL MCI_GetDWord(DWORD* data, LPWSTR* ptr)
|
||||
{
|
||||
DWORD val;
|
||||
LPWSTR ret;
|
||||
|
@ -1023,7 +1023,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(DWORD* data, int _offset, LPCWSTR lpCmd,
|
||||
LPWSTR args, LPDWORD dwFlags)
|
||||
{
|
||||
int len, offset;
|
||||
|
@ -1098,7 +1098,7 @@ static DWORD MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
|
|||
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, data[offset]);
|
||||
}
|
||||
break;
|
||||
case MCI_RECT:
|
||||
|
@ -1117,7 +1117,7 @@ static DWORD MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
|
|||
*dwFlags |= flg;
|
||||
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");
|
||||
}
|
||||
|
@ -1133,8 +1133,8 @@ static DWORD MCI_ParseOptArgs(DWORD_PTR* data, int _offset, LPCWSTR lpCmd,
|
|||
case MCI_CONSTANT:
|
||||
case MCI_FLAG: break;
|
||||
case MCI_INTEGER: if (!inCst) offset++; break;
|
||||
case MCI_END_CONSTANT:
|
||||
case MCI_STRING: offset++; break;
|
||||
case MCI_END_CONSTANT: offset++; break;
|
||||
case MCI_STRING: offset += sizeof(LPWSTR)/sizeof(DWORD); break;
|
||||
case MCI_RECT: offset += 4; break;
|
||||
default: ERR("oops\n");
|
||||
}
|
||||
|
@ -1156,10 +1156,10 @@ 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)
|
||||
MCI_GENERIC_PARMS *params, 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 fmt_d [] = {'%','d',0};
|
||||
static const WCHAR fmt_d4 [] = {'%','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};
|
||||
|
||||
|
@ -1168,56 +1168,64 @@ static DWORD MCI_HandleReturnValues(DWORD dwRet, LPWINE_MCIDRIVER wmd, DWORD ret
|
|||
case 0: /* nothing to return */
|
||||
break;
|
||||
case MCI_INTEGER:
|
||||
{
|
||||
DWORD data = *(DWORD *)(params + 1);
|
||||
switch (dwRet & 0xFFFF0000ul) {
|
||||
case 0:
|
||||
case MCI_INTEGER_RETURNED:
|
||||
snprintfW(lpstrRet, uRetLen, wszLd, data[1]);
|
||||
snprintfW(lpstrRet, uRetLen, fmt_d, data);
|
||||
break;
|
||||
case MCI_RESOURCE_RETURNED:
|
||||
/* return string which ID is HIWORD(data[1]),
|
||||
/* return string which ID is HIWORD(data),
|
||||
* string is loaded from mmsystem.dll */
|
||||
LoadStringW(hWinMM32Instance, HIWORD(data[1]), lpstrRet, uRetLen);
|
||||
LoadStringW(hWinMM32Instance, HIWORD(data), lpstrRet, uRetLen);
|
||||
break;
|
||||
case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER:
|
||||
/* return string which ID is HIWORD(data[1]),
|
||||
/* return string which ID is HIWORD(data),
|
||||
* string is loaded from driver */
|
||||
/* FIXME: this is wrong for a 16 bit handle */
|
||||
LoadStringW(GetDriverModuleHandle(wmd->hDriver),
|
||||
HIWORD(data[1]), lpstrRet, uRetLen);
|
||||
HIWORD(data), 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(data)), HIBYTE(LOWORD(data)),
|
||||
LOBYTE(HIWORD(data)));
|
||||
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(data)), HIBYTE(LOWORD(data)),
|
||||
LOBYTE(HIWORD(data)), HIBYTE(HIWORD(data)));
|
||||
break;
|
||||
default: ERR("Ooops (%04X)\n", HIWORD(dwRet));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MCI_STRING:
|
||||
switch (dwRet & 0xFFFF0000ul) {
|
||||
case 0:
|
||||
/* nothing to do data[1] == lpstrRet */
|
||||
/* nothing to do data[0] == lpstrRet */
|
||||
break;
|
||||
case MCI_INTEGER_RETURNED:
|
||||
data[1] = *(LPDWORD)lpstrRet;
|
||||
snprintfW(lpstrRet, uRetLen, wszLd, data[1]);
|
||||
{
|
||||
DWORD *data = (DWORD *)(params + 1);
|
||||
*data = *(LPDWORD)lpstrRet;
|
||||
snprintfW(lpstrRet, uRetLen, fmt_d, *data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WARN("Oooch. MCI_STRING and HIWORD(dwRet)=%04x\n", HIWORD(dwRet));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MCI_RECT:
|
||||
{
|
||||
DWORD *data = (DWORD *)(params + 1);
|
||||
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]);
|
||||
snprintfW(lpstrRet, uRetLen, fmt_d4, data[0], data[1], data[2], data[3]);
|
||||
break;
|
||||
}
|
||||
default: ERR("oops\n");
|
||||
}
|
||||
}
|
||||
|
@ -1235,13 +1243,20 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
|
|||
MCIDEVICEID uDevID, auto_open = 0;
|
||||
DWORD dwFlags = 0, dwRet = 0;
|
||||
int offset = 0;
|
||||
DWORD_PTR data[MCI_DATA_SIZE];
|
||||
DWORD retType;
|
||||
LPCWSTR lpCmd = 0;
|
||||
WORD wMsg = 0;
|
||||
static const WCHAR wszNew[] = {'n','e','w',0};
|
||||
static const WCHAR wszSAliasS[] = {' ','a','l','i','a','s',' ',0};
|
||||
static const WCHAR wszTypeS[] = {'t','y','p','e',' ',0};
|
||||
union
|
||||
{
|
||||
MCI_GENERIC_PARMS generic;
|
||||
MCI_OPEN_PARMSW open;
|
||||
MCI_SOUND_PARMSW sound;
|
||||
MCI_SYSINFO_PARMSW sysinfo;
|
||||
DWORD dw[MCI_DATA_SIZE];
|
||||
} data;
|
||||
|
||||
TRACE("(%s, %p, %d, %p)\n",
|
||||
debugstr_w(lpstrCommand), lpstrRet, uRetLen, hwndCallback);
|
||||
|
@ -1253,7 +1268,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
|
|||
strcpyW( verb, lpstrCommand );
|
||||
CharLowerW(verb);
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
if (!(args = strchrW(verb, ' '))) {
|
||||
dwRet = MCIERR_MISSING_DEVICE_NAME;
|
||||
|
@ -1290,15 +1305,15 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
|
|||
tmp = devType; devType = dev; dev = tmp;
|
||||
|
||||
dwFlags |= MCI_OPEN_TYPE;
|
||||
data[2] = (DWORD_PTR)devType;
|
||||
data.open.lpstrDeviceType = devType;
|
||||
devType = str_dup_upper(devType);
|
||||
dwFlags |= MCI_OPEN_ELEMENT;
|
||||
data[3] = (DWORD_PTR)dev;
|
||||
data.open.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;
|
||||
data.open.lpstrDeviceType = dev;
|
||||
devType = str_dup_upper(dev);
|
||||
if (tmp) *tmp = ' ';
|
||||
dwFlags |= MCI_OPEN_TYPE;
|
||||
|
@ -1309,7 +1324,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 lpstrDeviceType will be correctly set in ParseOpt loop */
|
||||
} else {
|
||||
if ((dwRet = MCI_GetDevTypeFromFileName(dev, buf, sizeof(buf))))
|
||||
goto errCleanUp;
|
||||
|
@ -1317,7 +1332,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
|
|||
devType = str_dup_upper(buf);
|
||||
}
|
||||
dwFlags |= MCI_OPEN_ELEMENT;
|
||||
data[3] = (DWORD_PTR)dev;
|
||||
data.open.lpstrElementName = dev;
|
||||
}
|
||||
if (MCI_ALL_DEVICE_ID == uDevID) {
|
||||
dwRet = MCIERR_CANNOT_USE_ALL;
|
||||
|
@ -1391,18 +1406,29 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
|
|||
wMsg = MCI_GetMessage(lpCmd);
|
||||
|
||||
/* set return information */
|
||||
offset = sizeof(data.generic);
|
||||
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;
|
||||
default: ERR("oops\n");
|
||||
case 0:
|
||||
break;
|
||||
case MCI_INTEGER:
|
||||
offset += sizeof(DWORD);
|
||||
break;
|
||||
case MCI_STRING:
|
||||
data.sysinfo.lpstrReturn = lpstrRet;
|
||||
data.sysinfo.dwRetSize = uRetLen;
|
||||
offset = FIELD_OFFSET( MCI_SYSINFO_PARMSW, dwNumber );
|
||||
break;
|
||||
case MCI_RECT:
|
||||
offset += 4 * sizeof(DWORD);
|
||||
break;
|
||||
default:
|
||||
ERR("oops\n");
|
||||
}
|
||||
|
||||
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(data.dw, offset / sizeof(DWORD), lpCmd, args, &dwFlags)))
|
||||
goto errCleanUp;
|
||||
|
||||
/* set up call back */
|
||||
|
@ -1418,7 +1444,7 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
|
|||
* In the meantime special-case all commands but PLAY and RECORD below. */
|
||||
}
|
||||
if (dwFlags & MCI_NOTIFY) {
|
||||
data[0] = (DWORD_PTR)hwndCallback;
|
||||
data.generic.dwCallback = (DWORD_PTR)hwndCallback;
|
||||
}
|
||||
|
||||
switch (wMsg) {
|
||||
|
@ -1435,12 +1461,11 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
|
|||
* alias with INSTALLNAME, name like "digitalvideo"
|
||||
* with QUANTITY and NAME. */
|
||||
{
|
||||
LPMCI_SYSINFO_PARMSW lpParms = (LPMCI_SYSINFO_PARMSW)data;
|
||||
lpParms->wDeviceType = MCI_ALL_DEVICE_ID;
|
||||
data.sysinfo.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))) {
|
||||
else if (!(data.sysinfo.wDeviceType = MCI_GetDevTypeFromResource(dev))) {
|
||||
dwRet = MCIERR_DEVICE_TYPE_REQUIRED;
|
||||
goto errCleanUp;
|
||||
}
|
||||
|
@ -1450,25 +1475,25 @@ DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
|
|||
case MCI_SOUND:
|
||||
/* FIXME: name is optional, "sound" is a valid command.
|
||||
* FIXME: Parse "sound notify" as flag, not as name. */
|
||||
((LPMCI_SOUND_PARMSW)data)->lpstrSoundName = dev;
|
||||
data.sound.lpstrSoundName = dev;
|
||||
dwFlags |= MCI_SOUND_NAME;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("[%d, %s, %08x, %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx]\n",
|
||||
TRACE("[%d, %s, %08x, %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x]\n",
|
||||
wmd ? wmd->wDeviceID : uDevID, MCI_MessageToString(wMsg), dwFlags,
|
||||
data[0], data[1], data[2], data[3], data[4],
|
||||
data[5], data[6], data[7], data[8], data[9]);
|
||||
data.dw[0], data.dw[1], data.dw[2], data.dw[3], data.dw[4],
|
||||
data.dw[5], data.dw[6], data.dw[7], data.dw[8], data.dw[9]);
|
||||
|
||||
if (wMsg == MCI_OPEN) {
|
||||
if ((dwRet = MCI_FinishOpen(wmd, (LPMCI_OPEN_PARMSW)data, dwFlags)))
|
||||
if ((dwRet = MCI_FinishOpen(wmd, &data.open, dwFlags)))
|
||||
goto errCleanUp;
|
||||
/* FIXME: notification is not properly shared across two opens */
|
||||
} else {
|
||||
dwRet = MCI_SendCommand(wmd ? wmd->wDeviceID : uDevID, wMsg, dwFlags, (DWORD_PTR)data);
|
||||
dwRet = MCI_SendCommand(wmd ? wmd->wDeviceID : uDevID, wMsg, 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, &data.generic, lpstrRet, uRetLen);
|
||||
TRACE("=> 2/ %x (%s)\n", dwRet, debugstr_w(lpstrRet));
|
||||
|
||||
errCleanUp:
|
||||
|
|
Loading…
Reference in New Issue