winmm: Improve MCI A/W mapping.

This commit is contained in:
Jörg Höhle 2010-03-28 20:01:15 +02:00 committed by Alexandre Julliard
parent b84576fcef
commit db0df4c067
1 changed files with 55 additions and 62 deletions

View File

@ -260,7 +260,6 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
case MCI_STEP:
case MCI_RECORD:
case MCI_BREAK:
case MCI_SOUND:
case MCI_STATUS:
case MCI_CUE:
case MCI_REALIZE:
@ -275,24 +274,23 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
case MCI_RESUME:
case MCI_DELETE:
case MCI_MONITOR:
case MCI_SETAUDIO:
case MCI_SIGNAL:
case MCI_SETVIDEO:
case MCI_LIST:
case MCI_UNDO:
return 0;
case MCI_OPEN:
{
MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA*)*dwParam2;
MCI_OPEN_PARMSW *mci_openW;
{ /* MCI_ANIM_OPEN_PARMS is the largest known MCI_OPEN_PARMS
* structure, larger than MCI_WAVE_OPEN_PARMS */
MCI_ANIM_OPEN_PARMSA *mci_openA = (MCI_ANIM_OPEN_PARMSA*)*dwParam2;
MCI_ANIM_OPEN_PARMSW *mci_openW;
DWORD_PTR *ptr;
ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD_PTR) + sizeof(*mci_openW) + 2 * sizeof(DWORD));
ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD_PTR) + sizeof(*mci_openW));
if (!ptr) return -1;
*ptr++ = *dwParam2; /* save the previous pointer */
*dwParam2 = (DWORD_PTR)ptr;
mci_openW = (MCI_OPEN_PARMSW *)ptr;
mci_openW = (MCI_ANIM_OPEN_PARMSW *)ptr;
if (dwParam1 & MCI_NOTIFY)
mci_openW->dwCallback = mci_openA->dwCallback;
@ -313,11 +311,10 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
}
if (dwParam1 & MCI_OPEN_ALIAS)
mci_openW->lpstrAlias = MCI_strdupAtoW(mci_openA->lpstrAlias);
/* FIXME: this is only needed for specific types of MCI devices, and
* may cause a segfault if the two DWORD:s don't exist at the end of
* mci_openA
*/
memcpy(mci_openW + 1, mci_openA + 1, 2 * sizeof(DWORD));
/* We don't know how many DWORD follow, as
* the structure depends on the device. */
if (HIWORD(dwParam1))
memcpy(&mci_openW->dwStyle, &mci_openA->dwStyle, sizeof(MCI_ANIM_OPEN_PARMSW) - sizeof(MCI_OPEN_PARMSW));
}
return 1;
@ -346,6 +343,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
return 0;
case MCI_SYSINFO:
if (dwParam1 & (MCI_SYSINFO_INSTALLNAME | MCI_SYSINFO_NAME))
{
MCI_SYSINFO_PARMSA *mci_sysinfoA = (MCI_SYSINFO_PARMSA *)*dwParam2;
MCI_SYSINFO_PARMSW *mci_sysinfoW;
@ -367,6 +365,7 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
mci_sysinfoW->wDeviceType = mci_sysinfoA->wDeviceType;
return 1;
}
return 0;
case MCI_INFO:
{
MCI_INFO_PARMSA *mci_infoA = (MCI_INFO_PARMSA *)*dwParam2;
@ -383,28 +382,18 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
if (dwParam1 & MCI_NOTIFY)
mci_infoW->dwCallback = mci_infoA->dwCallback;
mci_infoW->dwRetSize = mci_infoA->dwRetSize * sizeof(WCHAR); /* it's not the same as SYSINFO !!! */
mci_infoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mci_infoW->dwRetSize);
/* Size is measured in numbers of characters. */
mci_infoW->dwRetSize = mci_infoA->dwRetSize; /* it's not the same as SYSINFO !!! */
mci_infoW->lpstrReturn = HeapAlloc(GetProcessHeap(), 0, mci_infoW->dwRetSize * sizeof(WCHAR));
return 1;
}
case MCI_SAVE:
{
MCI_SAVE_PARMSA *mci_saveA = (MCI_SAVE_PARMSA *)*dwParam2;
MCI_SAVE_PARMSW *mci_saveW;
mci_saveW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_saveW));
if (!mci_saveW) return -1;
*dwParam2 = (DWORD_PTR)mci_saveW;
if (dwParam1 & MCI_NOTIFY)
mci_saveW->dwCallback = mci_saveA->dwCallback;
mci_saveW->lpfilename = MCI_strdupAtoW(mci_saveA->lpfilename);
return 1;
}
case MCI_LOAD:
{
MCI_LOAD_PARMSA *mci_loadA = (MCI_LOAD_PARMSA *)*dwParam2;
MCI_LOAD_PARMSW *mci_loadW;
case MCI_CAPTURE:
case MCI_RESTORE:
{ /* All these commands have the same layout: callback + string + optional rect */
MCI_OVLY_LOAD_PARMSA *mci_loadA = (MCI_OVLY_LOAD_PARMSA *)*dwParam2;
MCI_OVLY_LOAD_PARMSW *mci_loadW;
mci_loadW = HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_loadW));
if (!mci_loadW) return -1;
@ -413,11 +402,16 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
if (dwParam1 & MCI_NOTIFY)
mci_loadW->dwCallback = mci_loadA->dwCallback;
mci_loadW->lpfilename = MCI_strdupAtoW(mci_loadA->lpfilename);
if ((MCI_SAVE == msg && dwParam1 & MCI_DGV_RECT) ||
(MCI_LOAD == msg && dwParam1 & MCI_OVLY_RECT) ||
(MCI_CAPTURE == msg && dwParam1 & MCI_DGV_CAPTURE_AT) ||
(MCI_RESTORE == msg && dwParam1 & MCI_DGV_RESTORE_AT))
mci_loadW->rc = mci_loadA->rc;
return 1;
}
case MCI_SOUND:
case MCI_ESCAPE:
{
{ /* All these commands have the same layout: callback + string */
MCI_VD_ESCAPE_PARMSA *mci_vd_escapeA = (MCI_VD_ESCAPE_PARMSA *)*dwParam2;
MCI_VD_ESCAPE_PARMSW *mci_vd_escapeW;
@ -430,13 +424,22 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
mci_vd_escapeW->lpstrCommand = MCI_strdupAtoW(mci_vd_escapeA->lpstrCommand);
return 1;
}
case MCI_SETAUDIO:
case MCI_SETVIDEO:
if (!(dwParam1 & (MCI_DGV_SETVIDEO_QUALITY | MCI_DGV_SETVIDEO_ALG
| MCI_DGV_SETAUDIO_QUALITY | MCI_DGV_SETAUDIO_ALG)))
return 0;
/* fall through to default */
case MCI_RESERVE:
case MCI_QUALITY:
case MCI_LIST:
default:
FIXME("Message %s needs translation\n", MCI_MessageToString(msg));
return -1;
return 0; /* pass through untouched */
}
}
static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
static void MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
DWORD result)
{
switch (msg)
@ -445,7 +448,7 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
{
DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1;
MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA *)*ptr;
MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)(ptr + 1);
MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)dwParam2;
mci_openA->wDeviceID = mci_openW->wDeviceID;
@ -475,22 +478,18 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
break;
case MCI_SYSINFO:
if (dwParam1 & (MCI_SYSINFO_INSTALLNAME | MCI_SYSINFO_NAME))
{
DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1;
MCI_SYSINFO_PARMSA *mci_sysinfoA = (MCI_SYSINFO_PARMSA *)*ptr;
MCI_SYSINFO_PARMSW *mci_sysinfoW = (MCI_SYSINFO_PARMSW *)(ptr + 1);
MCI_SYSINFO_PARMSW *mci_sysinfoW = (MCI_SYSINFO_PARMSW *)dwParam2;
if (!result)
{
mci_sysinfoA->dwNumber = mci_sysinfoW->dwNumber;
mci_sysinfoA->wDeviceType = mci_sysinfoW->wDeviceType;
if (dwParam1 & MCI_SYSINFO_QUANTITY)
*(DWORD*)mci_sysinfoA->lpstrReturn = *(DWORD*)mci_sysinfoW->lpstrReturn;
else
WideCharToMultiByte(CP_ACP, 0,
mci_sysinfoW->lpstrReturn, mci_sysinfoW->dwRetSize,
mci_sysinfoA->lpstrReturn, mci_sysinfoA->dwRetSize,
NULL, NULL);
WideCharToMultiByte(CP_ACP, 0,
mci_sysinfoW->lpstrReturn, mci_sysinfoW->dwRetSize,
mci_sysinfoA->lpstrReturn, mci_sysinfoA->dwRetSize,
NULL, NULL);
}
HeapFree(GetProcessHeap(), 0, mci_sysinfoW->lpstrReturn);
@ -501,12 +500,12 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
{
DWORD_PTR *ptr = (DWORD_PTR *)dwParam2 - 1;
MCI_INFO_PARMSA *mci_infoA = (MCI_INFO_PARMSA *)*ptr;
MCI_INFO_PARMSW *mci_infoW = (MCI_INFO_PARMSW *)(ptr + 1);
MCI_INFO_PARMSW *mci_infoW = (MCI_INFO_PARMSW *)dwParam2;
if (!result)
{
WideCharToMultiByte(CP_ACP, 0,
mci_infoW->lpstrReturn, mci_infoW->dwRetSize / sizeof(WCHAR),
mci_infoW->lpstrReturn, mci_infoW->dwRetSize,
mci_infoA->lpstrReturn, mci_infoA->dwRetSize,
NULL, NULL);
}
@ -516,23 +515,19 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
}
break;
case MCI_SAVE:
{
MCI_SAVE_PARMSW *mci_saveW = (MCI_SAVE_PARMSW *)dwParam2;
HeapFree(GetProcessHeap(), 0, (void*)mci_saveW->lpfilename);
HeapFree(GetProcessHeap(), 0, mci_saveW);
}
break;
case MCI_LOAD:
{
MCI_LOAD_PARMSW *mci_loadW = (MCI_LOAD_PARMSW *)dwParam2;
case MCI_CAPTURE:
case MCI_RESTORE:
{ /* All these commands have the same layout: callback + string + optional rect */
MCI_OVLY_LOAD_PARMSW *mci_loadW = (MCI_OVLY_LOAD_PARMSW *)dwParam2;
HeapFree(GetProcessHeap(), 0, (void*)mci_loadW->lpfilename);
HeapFree(GetProcessHeap(), 0, mci_loadW);
}
break;
case MCI_SOUND:
case MCI_ESCAPE:
{
{ /* All these commands have the same layout: callback + string */
MCI_VD_ESCAPE_PARMSW *mci_vd_escapeW = (MCI_VD_ESCAPE_PARMSW *)dwParam2;
HeapFree(GetProcessHeap(), 0, (void*)mci_vd_escapeW->lpstrCommand);
@ -544,8 +539,6 @@ static DWORD MCI_UnmapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR dwParam2,
FIXME("Message %s needs unmapping\n", MCI_MessageToString(msg));
break;
}
return result;
}
/**************************************************************************
@ -2141,7 +2134,7 @@ DWORD WINAPI mciSendCommandA(MCIDEVICEID wDevID, UINT wMsg, DWORD_PTR dwParam1,
if (mapped == -1)
{
FIXME("message %04x mapping failed\n", wMsg);
return MMSYSERR_NOMEM;
return MCIERR_OUT_OF_MEMORY;
}
ret = mciSendCommandW(wDevID, wMsg, dwParam1, dwParam2);
if (mapped)