Skip to content
Snippets Groups Projects
Commit 81824b9b authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard
Browse files

No longer checking for correct iData in code.

Added look-up tables to command tables (speeds up queries).
parent e229260e
No related branches found
No related tags found
No related merge requests found
......@@ -38,11 +38,9 @@ LPWINE_MCIDRIVER MCI_GetDriver(UINT16 wDevID)
LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
EnterCriticalSection(&iData->cs);
if (iData) {
for (wmd = iData->lpMciDrv; wmd; wmd = wmd->lpNext) {
if (wmd->wDeviceID == wDevID)
break;
}
for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
if (wmd->wDeviceID == wDevID)
break;
}
LeaveCriticalSection(&iData->cs);
return wmd;
......@@ -54,7 +52,7 @@ LPWINE_MCIDRIVER MCI_GetDriver(UINT16 wDevID)
UINT MCI_GetDriverFromString(LPCSTR lpstrName)
{
LPWINE_MCIDRIVER wmd;
LPWINE_MM_IDATA iData;
LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
UINT ret = 0;
if (!lpstrName)
......@@ -63,26 +61,24 @@ UINT MCI_GetDriverFromString(LPCSTR lpstrName)
if (!lstrcmpiA(lpstrName, "ALL"))
return MCI_ALL_DEVICE_ID;
if ((iData = MULTIMEDIA_GetIData())) {
EnterCriticalSection(&iData->cs);
for (wmd = iData->lpMciDrv; wmd; wmd = wmd->lpNext) {
if (wmd->lpstrElementName && strcmp(wmd->lpstrElementName, lpstrName) == 0) {
ret = wmd->wDeviceID;
break;
}
EnterCriticalSection(&iData->cs);
for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
if (wmd->lpstrElementName && strcmp(wmd->lpstrElementName, lpstrName) == 0) {
ret = wmd->wDeviceID;
break;
}
if (wmd->lpstrDeviceType && strcmp(wmd->lpstrDeviceType, lpstrName) == 0) {
ret = wmd->wDeviceID;
break;
}
if (wmd->lpstrDeviceType && strcmp(wmd->lpstrDeviceType, lpstrName) == 0) {
ret = wmd->wDeviceID;
break;
}
if (wmd->lpstrAlias && strcmp(wmd->lpstrAlias, lpstrName) == 0) {
ret = wmd->wDeviceID;
break;
}
if (wmd->lpstrAlias && strcmp(wmd->lpstrAlias, lpstrName) == 0) {
ret = wmd->wDeviceID;
break;
}
LeaveCriticalSection(&iData->cs);
}
LeaveCriticalSection(&iData->cs);
return ret;
}
......@@ -170,13 +166,11 @@ static DWORD MCI_GetDevTypeFromFileName(LPCSTR fileName, LPSTR buf, UINT len)
#define MCI_COMMAND_TABLE_NOT_LOADED 0xFFFE
typedef struct tagWINE_MCICMDTABLE {
HANDLE hMem;
UINT uDevType;
LPSTR lpTable;
/* could also some more info to parse faster the lpTable
* an array of indexes to lpTable for all the commands
* could be a good start
*/
HANDLE hMem;
UINT uDevType;
LPCSTR lpTable;
UINT nVerbs; /* number of verbs in command table */
LPCSTR* aVerbs; /* array of verbs to speed up the verb look up process */
} WINE_MCICMDTABLE, *LPWINE_MCICMDTABLE;
WINE_MCICMDTABLE S_MciCmdTable[MAX_MCICMDTABLE];
......@@ -321,6 +315,10 @@ static UINT MCI_SetCommandTable(LPWINE_MM_IDATA iData, HANDLE hMem,
for (uTbl = 0; uTbl < MAX_MCICMDTABLE; uTbl++) {
if (S_MciCmdTable[uTbl].hMem == 0) {
LPCSTR lmem, str;
WORD eid;
WORD count;
S_MciCmdTable[uTbl].hMem = hMem;
S_MciCmdTable[uTbl].uDevType = uDevType;
S_MciCmdTable[uTbl].lpTable = LockResource(hMem);
......@@ -328,9 +326,35 @@ static UINT MCI_SetCommandTable(LPWINE_MM_IDATA iData, HANDLE hMem,
if (TRACE_ON(mci)) {
MCI_DumpCommandTable(uTbl);
}
/* create the verbs table */
/* get # of entries */
lmem = S_MciCmdTable[uTbl].lpTable;
count = 0;
do {
lmem += strlen(lmem) + 1;
eid = *(LPWORD)(lmem + sizeof(DWORD));
lmem += sizeof(DWORD) + sizeof(WORD);
if (eid == MCI_COMMAND_HEAD)
count++;
} while (eid != MCI_END_COMMAND_LIST);
S_MciCmdTable[uTbl].aVerbs = HeapAlloc(SystemHeap, 0, count * sizeof(LPCSTR));
S_MciCmdTable[uTbl].nVerbs = count;
lmem = S_MciCmdTable[uTbl].lpTable;
count = 0;
do {
str = lmem;
lmem += strlen(lmem) + 1;
eid = *(LPWORD)(lmem + sizeof(DWORD));
lmem += sizeof(DWORD) + sizeof(WORD);
if (eid == MCI_COMMAND_HEAD)
S_MciCmdTable[uTbl].aVerbs[count++] = str;
} while (eid != MCI_END_COMMAND_LIST);
/* assert(count == S_MciCmdTable[uTbl].nVerbs); */
return uTbl;
}
}
return MCI_NO_COMMAND_TABLE;
......@@ -346,6 +370,10 @@ static BOOL MCI_DeleteCommandTable(UINT uTbl)
FreeResource16(S_MciCmdTable[uTbl].hMem);
S_MciCmdTable[uTbl].hMem = 0;
if (S_MciCmdTable[uTbl].aVerbs) {
HeapFree(SystemHeap, 0, S_MciCmdTable[uTbl].aVerbs);
S_MciCmdTable[uTbl].aVerbs = 0;
}
return TRUE;
}
......@@ -354,7 +382,7 @@ static BOOL MCI_DeleteCommandTable(UINT uTbl)
*/
static BOOL MCI_UnLoadMciDriver(LPWINE_MM_IDATA iData, LPWINE_MCIDRIVER wmd)
{
LPWINE_MCIDRIVER* tmp;
LPWINE_MCIDRIVER* tmp;
if (!wmd)
return TRUE;
......@@ -366,7 +394,7 @@ static BOOL MCI_UnLoadMciDriver(LPWINE_MM_IDATA iData, LPWINE_MCIDRIVER wmd)
WARN("Unloading mci driver with non nul dwPrivate field\n");
EnterCriticalSection(&iData->cs);
for (tmp = &iData->lpMciDrv; *tmp; tmp = &(*tmp)->lpNext) {
for (tmp = &iData->lpMciDrvs; *tmp; tmp = &(*tmp)->lpNext) {
if (*tmp == wmd) {
*tmp = wmd->lpNext;
break;
......@@ -403,8 +431,8 @@ static DWORD MCI_LoadMciDriver(LPWINE_MM_IDATA iData, LPCSTR _strDevTyp,
/* wmd must be inserted in list before sending opening the driver, coz' it
* may want to lookup at wDevID
*/
wmd->lpNext = iData->lpMciDrv;
iData->lpMciDrv = wmd;
wmd->lpNext = iData->lpMciDrvs;
iData->lpMciDrvs = wmd;
for (modp.wDeviceID = MCI_MAGIC;
MCI_GetDriver(modp.wDeviceID) != 0;
......@@ -479,26 +507,20 @@ static DWORD MCI_FinishOpen(LPWINE_MCIDRIVER wmd, LPMCI_OPEN_PARMSA lpParms,
*/
static LPCSTR MCI_FindCommand(UINT uTbl, LPCSTR verb)
{
LPCSTR lmem, str;
DWORD flg;
WORD eid;
UINT idx;
if (uTbl >= MAX_MCICMDTABLE || S_MciCmdTable[uTbl].hMem == 0)
return NULL;
lmem = S_MciCmdTable[uTbl].lpTable;
/* another improvement would be to have the aVerbs array sorted,
* so that we could use a dichotomic search on it, rather than this dumb
* array look up
*/
for (idx = 0; idx < S_MciCmdTable[uTbl].nVerbs; idx++) {
if (strcmp(S_MciCmdTable[uTbl].aVerbs[idx], verb) == 0)
return S_MciCmdTable[uTbl].aVerbs[idx];
}
do {
do {
str = lmem;
lmem += strlen(lmem) + 1;
flg = *(LPDWORD)lmem;
eid = *(LPWORD)(lmem + sizeof(DWORD));
lmem += sizeof(DWORD) + sizeof(WORD);
if (eid == MCI_COMMAND_HEAD && strcmp(str, verb) == 0)
return str;
} while (eid != MCI_END_COMMAND_LIST);
} while (eid != MCI_END_COMMAND_LIST);
return NULL;
}
......@@ -697,8 +719,9 @@ static DWORD MCI_ParseOptArgs(LPDWORD data, int _offset, LPCSTR lpCmd,
/**************************************************************************
* MCI_HandleReturnValues [internal]
*/
static DWORD MCI_HandleReturnValues(LPWINE_MM_IDATA iData, DWORD dwRet, LPWINE_MCIDRIVER wmd,
LPCSTR lpCmd, LPDWORD data, LPSTR lpstrRet, UINT uRetLen)
static DWORD MCI_HandleReturnValues(LPWINE_MM_IDATA iData, DWORD dwRet,
LPWINE_MCIDRIVER wmd, LPCSTR lpCmd, LPDWORD data,
LPSTR lpstrRet, UINT uRetLen)
{
if (lpstrRet) {
switch (MCI_GetReturnType(lpCmd)) {
......@@ -752,7 +775,7 @@ static DWORD MCI_HandleReturnValues(LPWINE_MM_IDATA iData, DWORD dwRet, LPWINE_M
if (dwRet & 0xFFFF0000ul)
WARN("Oooch. MCI_STRING and HIWORD(dwRet)=%04x\n", HIWORD(dwRet));
wsnprintfA(lpstrRet, uRetLen, "%ld %ld %ld %ld",
data[1], data[2], data[3], data[4]);
data[1], data[2], data[3], data[4]);
break;
default: ERR("oops\n");
}
......@@ -772,13 +795,10 @@ DWORD WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR lpstrRet,
int offset = 0;
DWORD data[MCI_DATA_SIZE];
LPCSTR lpCmd = 0;
LPWINE_MM_IDATA iData;
LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
TRACE("('%s', %p, %d, %X)\n", lpstrCommand, lpstrRet, uRetLen, hwndCallback);
if (!(iData = MULTIMEDIA_GetIData()))
return MCIERR_INTERNAL;
/* format is <command> <device> <optargs> */
if (!(verb = HEAP_strdupA(GetProcessHeap(), 0, lpstrCommand)))
return MCIERR_OUT_OF_MEMORY;
......@@ -971,9 +991,6 @@ UINT16 WINAPI mciLoadCommandResource16(HANDLE16 hInst, LPCSTR resname, UINT16 ty
TRACE("(%04x, %s, %d)!\n", hInst, resname, type);
if (!iData)
return ret;
/* if file exists "resname.mci", then load resource "resname" from it
* otherwise directly from driver
* We don't support it (who uses this feature ?), but we check anyway
......@@ -1036,6 +1053,14 @@ BOOL WINAPI mciFreeCommandResource(UINT uTable)
return mciFreeCommandResource16(uTable);
}
typedef enum {
MCI_MAP_NOMEM, /* ko, memory problem */
MCI_MAP_MSGERROR, /* ko, unknown message */
MCI_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
MCI_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
MCI_MAP_PASS /* not handled (no memory allocated) to be sent to the driver */
} MCI_MapType;
/**************************************************************************
* MCI_MapMsg16To32A [internal]
*/
......@@ -1258,7 +1283,7 @@ static MCI_MapType MCI_UnMapMsg16To32A(WORD uDevType, WORD wMsg, DWORD lParam)
case MCI_OPEN_DRIVER:
if (lParam) {
LPMCI_OPEN_PARMSA mop32a = (LPMCI_OPEN_PARMSA)lParam;
LPMCI_OPEN_PARMS16 mop16 = *(LPMCI_OPEN_PARMS16*)((char*)mop32a - sizeof(LPMCI_OPEN_PARMS16*));
LPMCI_OPEN_PARMS16 mop16 = *(LPMCI_OPEN_PARMS16*)((char*)mop32a - sizeof(LPMCI_OPEN_PARMS16));
mop16->wDeviceID = mop32a->wDeviceID;
if (!HeapFree(SystemHeap, 0, (LPVOID)(lParam - sizeof(LPMCI_OPEN_PARMS16))))
......@@ -1983,23 +2008,20 @@ static DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSA lpParms)
{
char strDevTyp[128];
DWORD dwRet;
LPWINE_MCIDRIVER wmd = 0;
LPWINE_MM_IDATA iData;
LPWINE_MCIDRIVER wmd;
LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
TRACE("(%08lX, %p)\n", dwParam, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (!(iData = MULTIMEDIA_GetIData()))
return MCIERR_INTERNAL;
/* only two low bytes are generic, the other ones are dev type specific */
#define WINE_MCI_SUPP (0xFFFF0000|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT| \
#define WINE_MCIDRIVER_SUPP (0xFFFF0000|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT| \
MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID| \
MCI_NOTIFY|MCI_WAIT)
if ((dwParam & ~WINE_MCI_SUPP) != 0) {
FIXME("Unsupported yet dwFlags=%08lX\n", dwParam & ~WINE_MCI_SUPP);
if ((dwParam & ~WINE_MCIDRIVER_SUPP) != 0) {
FIXME("Unsupported yet dwFlags=%08lX\n", dwParam & ~WINE_MCIDRIVER_SUPP);
}
#undef WINE_MCI_SUPP
#undef WINE_MCIDRIVER_SUPP
strDevTyp[0] = 0;
......@@ -2041,13 +2063,12 @@ static DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSA lpParms)
if (!strDevTyp[0] &&
MCI_GetDevTypeFromFileName(lpParms->lpstrElementName,
strDevTyp, sizeof(strDevTyp))) {
if (GetDriveTypeA(lpParms->lpstrElementName) == DRIVE_CDROM) {
/* FIXME: this will not work if several CDROM drives are installed on the machine */
strcpy(strDevTyp, "CDAUDIO");
} else {
if (GetDriveTypeA(lpParms->lpstrElementName) != DRIVE_CDROM) {
dwRet = MCIERR_EXTENSION_NOT_FOUND;
goto errCleanUp;
}
/* FIXME: this will not work if several CDROM drives are installed on the machine */
strcpy(strDevTyp, "CDAUDIO");
}
}
......@@ -2097,13 +2118,10 @@ static DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms
{
DWORD dwRet;
LPWINE_MCIDRIVER wmd;
LPWINE_MM_IDATA iData;
LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
TRACE("(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
if (!(iData = MULTIMEDIA_GetIData()))
return MCIERR_INTERNAL;
if (wDevID == MCI_ALL_DEVICE_ID) {
LPWINE_MCIDRIVER next;
......@@ -2112,7 +2130,7 @@ static DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms
* each of the open drivers ? if the latest, which notif
* to return when only one fails ?
*/
for (wmd = iData->lpMciDrv; wmd; ) {
for (wmd = iData->lpMciDrvs; wmd; ) {
next = wmd->lpNext;
MCI_Close(wmd->wDeviceID, dwParam, lpParms);
wmd = next;
......@@ -2163,10 +2181,9 @@ static DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSA lpParm
{
DWORD ret = MCIERR_INVALID_DEVICE_ID;
LPWINE_MCIDRIVER wmd;
LPWINE_MM_IDATA iData;
LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (!(iData = MULTIMEDIA_GetIData())) return MCIERR_INTERNAL;
TRACE("(%08x, %08lX, %08lX[num=%ld, wDevTyp=%u])\n",
uDevID, dwFlags, (DWORD)lpParms, lpParms->dwNumber, lpParms->wDeviceType);
......@@ -2181,7 +2198,7 @@ static DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSA lpParm
if (dwFlags & MCI_SYSINFO_OPEN) {
TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers\n");
EnterCriticalSection(&iData->cs);
for (wmd = iData->lpMciDrv; wmd; wmd = wmd->lpNext) {
for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
cnt++;
}
LeaveCriticalSection(&iData->cs);
......@@ -2194,7 +2211,7 @@ static DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSA lpParm
TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers of type %u\n",
lpParms->wDeviceType);
EnterCriticalSection(&iData->cs);
for (wmd = iData->lpMciDrv; wmd; wmd = wmd->lpNext) {
for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
if (wmd->wType == lpParms->wDeviceType)
cnt++;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment