From faa359492bc28d5b1814b0179c1d101bccc7d703 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Mon, 23 Apr 2001 18:14:41 +0000 Subject: [PATCH] Added cache for drivers information. Fixed a few bugs (memory handling, version info...) Enhanced validity checks. --- dlls/msacm/driver.c | 17 ++- dlls/msacm/filter.c | 49 +++------ dlls/msacm/format.c | 108 +++++++++---------- dlls/msacm/internal.c | 212 ++++++++++++++++++++++++++++++++++++-- dlls/msacm/msacm32_main.c | 91 +++++++++------- dlls/msacm/pcmconverter.c | 3 +- dlls/msacm/stream.c | 35 ++++--- dlls/msacm/wineacm.h | 9 ++ 8 files changed, 362 insertions(+), 162 deletions(-) diff --git a/dlls/msacm/driver.c b/dlls/msacm/driver.c index 2ef4ca9ae76..fa08caf6187 100644 --- a/dlls/msacm/driver.c +++ b/dlls/msacm/driver.c @@ -166,25 +166,24 @@ MMRESULT WINAPI acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, D */ MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum) { - PWINE_ACMDRIVERID p; - ACMDRIVERDETAILSW add; + PWINE_ACMDRIVERID padid; + DWORD fdwSupport; if (!fnCallback) return MMSYSERR_INVALPARAM; if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) return MMSYSERR_INVALFLAG; - add.cbStruct = sizeof(add); - for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) { - if (acmDriverDetailsW((HACMDRIVERID)p, &add, 0) != MMSYSERR_NOERROR) - continue; - if (!p->bEnabled) { + for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { + fdwSupport = padid->fdwSupport; + + if (!padid->bEnabled) { if (fdwEnum & ACM_DRIVERENUMF_DISABLED) - add.fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; + fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; else continue; } - if (!(*fnCallback)((HACMDRIVERID)p, dwInstance, add.fdwSupport)) + if (!(*fnCallback)((HACMDRIVERID)padid, dwInstance, fdwSupport)) break; } diff --git a/dlls/msacm/filter.c b/dlls/msacm/filter.c index 02044c99a51..abeec5cdd0f 100644 --- a/dlls/msacm/filter.c +++ b/dlls/msacm/filter.c @@ -101,14 +101,12 @@ MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd, } } } else { - mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, - (LPARAM)pafd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails); } break; case ACM_FILTERDETAILSF_INDEX: /* should check pafd->dwFilterIndex < aftd->cStandardFilters */ - mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, - (LPARAM)pafd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails); break; default: WARN("Unknown fdwDetails %08lx\n", fdwDetails); @@ -175,15 +173,10 @@ static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had, ACMFILTERENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum) { - ACMDRIVERDETAILSW add; ACMFILTERTAGDETAILSW aftd; int i, j; - add.cbStruct = sizeof(add); - - if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) != MMSYSERR_NOERROR) return FALSE; - - for (i = 0; i < add.cFilterTags; i++) { + for (i = 0; i < padid->cFilterTags; i++) { memset(&aftd, 0, sizeof(aftd)); aftd.cbStruct = sizeof(aftd); aftd.dwFilterTagIndex = i; @@ -200,7 +193,7 @@ static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had, if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR) continue; - if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, add.fdwSupport)) + if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport)) return FALSE; } } @@ -295,22 +288,19 @@ MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { /* should check for codec only */ if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { - mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, - (LPARAM)paftd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails); acmDriverClose(had, 0); if (mmr == MMSYSERR_NOERROR) break; } } } else { - mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, - (LPARAM)paftd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails); } break; case ACM_FILTERTAGDETAILSF_INDEX: /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */ - mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, - (LPARAM)paftd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails); break; case ACM_FILTERTAGDETAILSF_LARGESTSIZE: @@ -328,9 +318,8 @@ MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd tmp.cbStruct = sizeof(tmp); tmp.dwFilterTag = ft; - if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, - (LPARAM)&tmp, - (LPARAM)fdwDetails) == MMSYSERR_NOERROR) { + if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, + (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) { if (mmr == ACMERR_NOTPOSSIBLE || paftd->cbFilterSize < tmp.cbFilterSize) { *paftd = tmp; @@ -341,8 +330,7 @@ MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd } } } else { - mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, - (LPARAM)paftd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails); } break; @@ -417,7 +405,6 @@ MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, DWORD fdwEnum) { PWINE_ACMDRIVERID padid; - ACMDRIVERDETAILSW add; int i; TRACE("(0x%08x, %p, %p, %ld, %ld)\n", @@ -430,17 +417,13 @@ MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { /* should check for codec only */ if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) { - add.cbStruct = sizeof(add); - if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) == MMSYSERR_NOERROR) { - for (i = 0; i < add.cFilterTags; i++) { - paftd->dwFilterTagIndex = i; - if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { - if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, - add.fdwSupport)) { - padid = NULL; - break; - } + for (i = 0; i < padid->cFilterTags; i++) { + paftd->dwFilterTagIndex = i; + if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { + if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) { + padid = NULL; + break; } } } diff --git a/dlls/msacm/format.c b/dlls/msacm/format.c index fc47b051907..03c7d18c501 100644 --- a/dlls/msacm/format.c +++ b/dlls/msacm/format.c @@ -58,11 +58,12 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid, ACMFORMATDETAILSA afd; int i, idx; MMRESULT mmr; - char buffer[64]; + char buffer[ACMFORMATDETAILS_FORMAT_CHARS+16]; afd.cbStruct = sizeof(afd); afd.dwFormatTag = paftd->dwFormatTag; - afd.pwfx = HeapAlloc(GetProcessHeap(), 0, paftd->cbFormatSize); + afd.pwfx = HeapAlloc(MSACM_hHeap, 0, paftd->cbFormatSize); + if (!afd.pwfx) return FALSE; afd.pwfx->wFormatTag = paftd->dwFormatTag; afd.pwfx->cbSize = paftd->cbFormatSize; afd.cbwfx = paftd->cbFormatSize; @@ -71,7 +72,7 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid, afd.dwFormatIndex = i; mmr = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX); if (mmr == MMSYSERR_NOERROR) { - strcpy(buffer, afd.szFormat); + strncpy(buffer, afd.szFormat, ACMFORMATTAGDETAILS_FORMATTAG_CHARS); for (idx = strlen(buffer); idx < ACMFORMATTAGDETAILS_FORMATTAG_CHARS; idx++) buffer[idx] = ' '; @@ -86,6 +87,7 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid, acmDriverClose(had, 0); SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_SETCURSEL, 0, 0); + HeapFree(MSACM_hHeap, 0, afd.pwfx); } } break; @@ -101,7 +103,8 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid, afd.pwfx = affd->afc->pwfx; afd.cbwfx = affd->afc->cbwfx; - afd.dwFormatIndex = SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_GETCURSEL, 0, 0);; + afd.dwFormatIndex = SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, + CB_GETCURSEL, 0, 0);; affd->ret = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX); acmDriverClose(had, 0); return TRUE; @@ -290,8 +293,7 @@ MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd, /*********************************************************************** * acmFormatDetailsW (MSACM32.26) */ -MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, - DWORD fdwDetails) +MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails) { MMRESULT mmr; static WCHAR fmt1[] = {'%','d',' ','H','z',0}; @@ -319,21 +321,18 @@ MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, /* should check for codec only */ if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { - mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, - (LPARAM)pafd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails); acmDriverClose(had, 0); if (mmr == MMSYSERR_NOERROR) break; } } } else { - mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, - (LPARAM)pafd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails); } break; case ACM_FORMATDETAILSF_INDEX: /* should check pafd->dwFormatIndex < aftd->cStandardFormats */ - mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, - (LPARAM)pafd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails); break; default: WARN("Unknown fdwDetails %08lx\n", fdwDetails); @@ -414,15 +413,10 @@ static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had, ACMFORMATENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum) { - ACMDRIVERDETAILSW add; ACMFORMATTAGDETAILSW aftd; int i, j; - add.cbStruct = sizeof(add); - - if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) != MMSYSERR_NOERROR) return FALSE; - - for (i = 0; i < add.cFormatTags; i++) { + for (i = 0; i < padid->cFormatTags; i++) { memset(&aftd, 0, sizeof(aftd)); aftd.cbStruct = sizeof(aftd); aftd.dwFormatTagIndex = i; @@ -453,7 +447,7 @@ static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had, /* more checks to be done on fdwEnum */ - if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, add.fdwSupport)) + if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport)) return FALSE; } /* the "formats" used by the filters are also reported */ @@ -551,8 +545,7 @@ MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc, acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR) continue; - if (MSACM_Message(had, ACMDM_FORMAT_SUGGEST, - (LPARAM)&adfg, 0L) == MMSYSERR_NOERROR) { + if (MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L) == MMSYSERR_NOERROR) { mmr = MMSYSERR_NOERROR; break; } @@ -598,7 +591,7 @@ MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd DWORD fdwDetails) { PWINE_ACMDRIVERID padid; - MMRESULT mmr; + MMRESULT mmr = ACMERR_NOTPOSSIBLE; TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails); @@ -609,26 +602,31 @@ MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd switch (fdwDetails) { case ACM_FORMATTAGDETAILSF_FORMATTAG: if (had == (HACMDRIVER)NULL) { - mmr = ACMERR_NOTPOSSIBLE; for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { /* should check for codec only */ - if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { - mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, - (LPARAM)paftd, (LPARAM)fdwDetails); + if (padid->bEnabled && + MSACM_FindFormatTagInCache(padid, paftd->dwFormatTag, NULL) && + acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { + mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails); acmDriverClose(had, 0); if (mmr == MMSYSERR_NOERROR) break; } } } else { - mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, - (LPARAM)paftd, (LPARAM)fdwDetails); + PWINE_ACMDRIVER pad = MSACM_GetDriver(had); + + if (pad && MSACM_FindFormatTagInCache(pad->obj.pACMDriverID, paftd->dwFormatTag, NULL)) + mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails); } break; case ACM_FORMATTAGDETAILSF_INDEX: - /* FIXME should check paftd->dwFormatTagIndex < add.cFormatTags */ - mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, - (LPARAM)paftd, (LPARAM)fdwDetails); + if (had != (HACMDRIVER)NULL) { + PWINE_ACMDRIVER pad = MSACM_GetDriver(had); + + if (pad && paftd->dwFormatTagIndex < pad->obj.pACMDriverID->cFormatTags) + mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails); + } break; case ACM_FORMATTAGDETAILSF_LARGESTSIZE: @@ -636,7 +634,6 @@ MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd ACMFORMATTAGDETAILSW tmp; DWORD ft = paftd->dwFormatTag; - mmr = ACMERR_NOTPOSSIBLE; for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { /* should check for codec only */ if (padid->bEnabled && @@ -646,9 +643,8 @@ MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd tmp.cbStruct = sizeof(tmp); tmp.dwFormatTag = ft; - if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, - (LPARAM)&tmp, - (LPARAM)fdwDetails) == MMSYSERR_NOERROR) { + if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, + (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) { if (mmr == ACMERR_NOTPOSSIBLE || paftd->cbFormatSize < tmp.cbFormatSize) { *paftd = tmp; @@ -659,8 +655,7 @@ MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd } } } else { - mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, - (LPARAM)paftd, (LPARAM)fdwDetails); + mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails); } break; @@ -735,7 +730,6 @@ MMRESULT WINAPI acmFormatTagEnumW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, DWORD fdwEnum) { PWINE_ACMDRIVERID padid; - ACMDRIVERDETAILSW add; int i; BOOL bPcmDone = FALSE; @@ -749,26 +743,26 @@ MMRESULT WINAPI acmFormatTagEnumW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { /* should check for codec only */ if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) { - add.cbStruct = sizeof(add); - if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) == MMSYSERR_NOERROR) { - for (i = 0; i < add.cFormatTags; i++) { - paftd->dwFormatTagIndex = i; - if (acmFormatTagDetailsW(had, paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { - if (paftd->dwFormatTag == WAVE_FORMAT_PCM) { - /* FIXME (EPP): I'm not sure this is the correct - * algorithm (should make more sense to apply the same - * for all already loaded formats, but this will do - * for now - */ - if (bPcmDone) continue; - bPcmDone = TRUE; - } - if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, - add.fdwSupport)) { - padid = NULL; - break; - } + for (i = 0; i < padid->cFormatTags; i++) { + paftd->dwFormatTagIndex = i; + if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, + (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { + if (paftd->dwFormatTag == WAVE_FORMAT_PCM) { + if (paftd->szFormatTag[0] == 0) + MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag, + sizeof(paftd->szFormatTag)/sizeof(WCHAR) ); + /* FIXME (EPP): I'm not sure this is the correct + * algorithm (should make more sense to apply the same + * for all already loaded formats, but this will do + * for now + */ + if (bPcmDone) continue; + bPcmDone = TRUE; + } + if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) { + padid = NULL; /* to exist the two nested for loops */ + break; } } } diff --git a/dlls/msacm/internal.c b/dlls/msacm/internal.c index 4f6924c1b18..566a9847311 100644 --- a/dlls/msacm/internal.c +++ b/dlls/msacm/internal.c @@ -14,6 +14,7 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" +#include "winreg.h" #include "mmsystem.h" #include "msacm.h" #include "msacmdrv.h" @@ -28,6 +29,195 @@ HANDLE MSACM_hHeap = (HANDLE) NULL; PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL; PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL; +#if 0 +/*********************************************************************** + * MSACM_DumpCache + */ +static void MSACM_DumpCache(PWINE_ACMDRIVERID padid) +{ + unsigned i; + + TRACE("cFilterTags=%lu cFormatTags=%lu fdwSupport=%08lx\n", + padid->cFilterTags, padid->cFormatTags, padid->fdwSupport); + for (i = 0; i < padid->cache->cFormatTags; i++) { + TRACE("\tdwFormatTag=%lu cbwfx=%lu\n", + padid->aFormatTag[i].dwFormatTag, padid->aFormatTag[i].cbwfx); + } +} +#endif + +/*********************************************************************** + * MSACM_FindFormatTagInCache [internal] + * + * Returns TRUE is the format tag fmtTag is present in the cache. + * If so, idx is set to its index. + */ +BOOL MSACM_FindFormatTagInCache(WINE_ACMDRIVERID* padid, DWORD fmtTag, LPDWORD idx) +{ + unsigned i; + + for (i = 0; i < padid->cFormatTags; i++) { + if (padid->aFormatTag[i].dwFormatTag == fmtTag) { + if (idx) *idx = i; + return TRUE; + } + } + return FALSE; +} + +/*********************************************************************** + * MSACM_FillCache + */ +static BOOL MSACM_FillCache(PWINE_ACMDRIVERID padid) +{ + HACMDRIVER had = 0; + int ntag; + ACMDRIVERDETAILSW add; + ACMFORMATDETAILSW aftd; + WAVEFORMATEX wfx; + + if (acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != 0) + return FALSE; + + padid->aFormatTag = NULL; + add.cbStruct = sizeof(add); + if (MSACM_Message(had, ACMDM_DRIVER_DETAILS, (LPARAM)&add, 0)) + goto errCleanUp; + + if (add.cFormatTags > 0) { + padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY, + add.cFormatTags * sizeof(padid->aFormatTag[0])); + if (!padid->aFormatTag) goto errCleanUp; + } + + padid->cFormatTags = add.cFormatTags; + padid->cFilterTags = add.cFilterTags; + padid->fdwSupport = add.fdwSupport; + + aftd.cbStruct = sizeof(aftd); + /* don't care about retrieving full struct... so a bare WAVEFORMATEX should do */ + aftd.pwfx = &wfx; + aftd.cbwfx = sizeof(wfx); + + for (ntag = 0; ntag < add.cFormatTags; ntag++) { + aftd.dwFormatIndex = ntag; + if (MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)&aftd, ACM_FORMATDETAILSF_INDEX)) { + TRACE("IIOs (%s)\n", padid->pszDriverAlias); + goto errCleanUp; + } + padid->aFormatTag[ntag].dwFormatTag = aftd.dwFormatTag; + padid->aFormatTag[ntag].cbwfx = aftd.cbwfx; + } + + acmDriverClose(had, 0); + + return TRUE; + +errCleanUp: + if (had) acmDriverClose(had, 0); + HeapFree(MSACM_hHeap, 0, padid->aFormatTag); + padid->aFormatTag = NULL; + return FALSE; +} + +/*********************************************************************** + * MSACM_GetRegistryKey + */ +static LPSTR MSACM_GetRegistryKey(const WINE_ACMDRIVERID* padid) +{ + static const char* baseKey = "Software\\Microsoft\\AudioCompressionManager\\DriverCache\\"; + LPSTR ret; + int len; + + if (!padid->pszDriverAlias) { + ERR("No alias needed for registry entry\n"); + return NULL; + } + len = strlen(baseKey); + ret = HeapAlloc(MSACM_hHeap, 0, len + strlen(padid->pszDriverAlias) + 1); + if (!ret) return NULL; + + strcpy(ret, baseKey); + strcpy(ret + len, padid->pszDriverAlias); + CharLowerA(ret + len); + return ret; +} + +/*********************************************************************** + * MSACM_ReadCache + */ +static BOOL MSACM_ReadCache(PWINE_ACMDRIVERID padid) +{ + LPSTR key = MSACM_GetRegistryKey(padid); + HKEY hKey; + DWORD type, size; + + if (!key) return FALSE; + + padid->aFormatTag = NULL; + + if (RegCreateKeyA(HKEY_LOCAL_MACHINE, key, &hKey)) + goto errCleanUp; + + size = sizeof(padid->cFormatTags); + if (RegQueryValueExA(hKey, "cFormatTags", 0, &type, (void*)&padid->cFormatTags, &size)) + goto errCleanUp; + size = sizeof(padid->cFilterTags); + if (RegQueryValueExA(hKey, "cFilterTags", 0, &type, (void*)&padid->cFilterTags, &size)) + goto errCleanUp; + size = sizeof(padid->fdwSupport); + if (RegQueryValueExA(hKey, "fdwSupport", 0, &type, (void*)&padid->fdwSupport, &size)) + goto errCleanUp; + + if (padid->cFormatTags > 0) { + size = padid->cFormatTags * sizeof(padid->aFormatTag[0]); + padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY, size); + if (!padid->aFormatTag) goto errCleanUp; + if (RegQueryValueExA(hKey, "aFormatTagCache", 0, &type, (void*)padid->aFormatTag, &size)) + goto errCleanUp; + } + HeapFree(MSACM_hHeap, 0, key); + return TRUE; + + errCleanUp: + HeapFree(MSACM_hHeap, 0, key); + HeapFree(MSACM_hHeap, 0, padid->aFormatTag); + padid->aFormatTag = NULL; + RegCloseKey(hKey); + return FALSE; +} + +/*********************************************************************** + * MSACM_WriteCache + */ +static BOOL MSACM_WriteCache(PWINE_ACMDRIVERID padid) +{ + LPSTR key = MSACM_GetRegistryKey(padid); + HKEY hKey; + + if (!key) return FALSE; + + if (RegCreateKeyA(HKEY_LOCAL_MACHINE, key, &hKey)) + goto errCleanUp; + + if (RegSetValueExA(hKey, "cFormatTags", 0, REG_DWORD, (void*)&padid->cFormatTags, sizeof(DWORD))) + goto errCleanUp; + if (RegSetValueExA(hKey, "cFilterTags", 0, REG_DWORD, (void*)&padid->cFilterTags, sizeof(DWORD))) + goto errCleanUp; + if (RegSetValueExA(hKey, "fdwSupport", 0, REG_DWORD, (void*)&padid->fdwSupport, sizeof(DWORD))) + goto errCleanUp; + if (RegSetValueExA(hKey, "aFormatTagCache", 0, REG_BINARY, + (void*)padid->aFormatTag, + padid->cFormatTags * sizeof(padid->aFormatTag[0]))) + goto errCleanUp; + HeapFree(MSACM_hHeap, 0, key); + return TRUE; + + errCleanUp: + HeapFree(MSACM_hHeap, 0, key); + return FALSE; +} + /*********************************************************************** * MSACM_RegisterDriver() */ @@ -54,6 +244,7 @@ PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName, strcpy( padid->pszFileName, pszFileName ); } padid->hInstModule = hinstModule; + padid->bEnabled = TRUE; padid->pACMDriverList = NULL; padid->pNextACMDriverID = NULL; @@ -63,7 +254,12 @@ PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName, MSACM_pLastACMDriverID = padid; if (!MSACM_pFirstACMDriverID) MSACM_pFirstACMDriverID = padid; - + /* disable the driver if we cannot load the cache */ + if (!MSACM_ReadCache(padid) && !MSACM_FillCache(padid)) { + WARN("Couldn't load cache for ACM driver (%s)\n", pszFileName); + MSACM_UnregisterDriver(padid); + return NULL; + } return padid; } @@ -82,7 +278,7 @@ void MSACM_RegisterAllDrivers(void) if (MSACM_pFirstACMDriverID) return; - /* FIXME: Do not work! How do I determine the section length? */ + /* FIXME: Does not work! How do I determine the section length? */ dwBufferLength = 1024; /* EPP GetPrivateProfileSectionA("drivers32", NULL, 0, "system.ini"); */ @@ -122,7 +318,8 @@ PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) HeapFree(MSACM_hHeap, 0, p->pszDriverAlias); if (p->pszFileName) HeapFree(MSACM_hHeap, 0, p->pszFileName); - + HeapFree(MSACM_hHeap, 0, p->aFormatTag); + if (p == MSACM_pFirstACMDriverID) MSACM_pFirstACMDriverID = p->pNextACMDriverID; if (p == MSACM_pLastACMDriverID) @@ -142,14 +339,15 @@ PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) /*********************************************************************** * MSACM_UnregisterAllDrivers() - * FIXME - * Where should this function be called? */ void MSACM_UnregisterAllDrivers(void) { - PWINE_ACMDRIVERID p; + PWINE_ACMDRIVERID p = MSACM_pFirstACMDriverID; - for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p)); + while (p) { + MSACM_WriteCache(p); + p = MSACM_UnregisterDriver(p); + } } /*********************************************************************** diff --git a/dlls/msacm/msacm32_main.c b/dlls/msacm/msacm32_main.c index ca9ea2512f5..09ab89c0fe8 100644 --- a/dlls/msacm/msacm32_main.c +++ b/dlls/msacm/msacm32_main.c @@ -37,7 +37,7 @@ BOOL WINAPI MSACM32_LibMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReser case DLL_PROCESS_DETACH: MSACM_UnregisterAllDrivers(); HeapDestroy(MSACM_hHeap); - MSACM_hHeap = (HANDLE) NULL; + MSACM_hHeap = (HANDLE)NULL; MSACM_hInstance32 = (HINSTANCE)NULL; break; case DLL_THREAD_ATTACH: @@ -62,16 +62,19 @@ BOOL WINAPI MSACM32_LibMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReser DWORD WINAPI acmGetVersion(void) { OSVERSIONINFOA version; - GetVersionExA( &version ); - switch(version.dwPlatformId) - { + + version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if (!GetVersionExA( &version )) + return 0x04030000; + + switch (version.dwPlatformId) { case VER_PLATFORM_WIN32_NT: return 0x04000565; /* 4.0.1381 */ default: - FIXME("%ld not supported\n",version.dwPlatformId); + FIXME("%lx not supported\n", version.dwPlatformId); case VER_PLATFORM_WIN32_WINDOWS: - return 0x04000000; /* 4.0.0 */ - } + return 0x04030000; /* 4.3.0 */ + } } /*********************************************************************** @@ -89,32 +92,33 @@ MMRESULT WINAPI acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric) BOOL bLocal = TRUE; PWINE_ACMDRIVERID padid; DWORD val = 0; + int i; MMRESULT mmr = MMSYSERR_NOERROR; TRACE("(0x%08x, %d, %p);\n", hao, uMetric, pMetric); +#define CheckLocal(padid) (!bLocal || ((padid)->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL)) + switch (uMetric) { case ACM_METRIC_COUNT_DRIVERS: bLocal = FALSE; /* fall thru */ case ACM_METRIC_COUNT_LOCAL_DRIVERS: - if (!pao) - return MMSYSERR_INVALHANDLE; + if (hao) return MMSYSERR_INVALHANDLE; for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) - if (padid->bEnabled /* && (local(padid) || !bLocal) */) + if (padid->bEnabled && CheckLocal(padid)) val++; *(LPDWORD)pMetric = val; break; case ACM_METRIC_COUNT_CODECS: - if (!pao) - return MMSYSERR_INVALHANDLE; bLocal = FALSE; /* fall thru */ case ACM_METRIC_COUNT_LOCAL_CODECS: - /* FIXME: don't know how to differentiate codec, converters & filters yet */ + if (hao) return MMSYSERR_INVALHANDLE; for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) - if (padid->bEnabled /* && (local(padid) || !bLocal) */) + if (padid->bEnabled && (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) + && CheckLocal(padid)) val++; *(LPDWORD)pMetric = val; break; @@ -123,9 +127,10 @@ MMRESULT WINAPI acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric) bLocal = FALSE; /* fall thru */ case ACM_METRIC_COUNT_LOCAL_CONVERTERS: - /* FIXME: don't know how to differentiate codec, converters & filters yet */ + if (hao) return MMSYSERR_INVALHANDLE; for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) - if (padid->bEnabled /* && (local(padid) || !bLocal) */) + if (padid->bEnabled && (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) + && CheckLocal(padid)) val++; *(LPDWORD)pMetric = val; break; @@ -134,9 +139,10 @@ MMRESULT WINAPI acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric) bLocal = FALSE; /* fall thru */ case ACM_METRIC_COUNT_LOCAL_FILTERS: - /* FIXME: don't know how to differentiate codec, converters & filters yet */ + if (hao) return MMSYSERR_INVALHANDLE; for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) - if (padid->bEnabled /* && (local(padid) || !bLocal) */) + if (padid->bEnabled && (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER) + && CheckLocal(padid)) val++; *(LPDWORD)pMetric = val; break; @@ -145,37 +151,42 @@ MMRESULT WINAPI acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric) bLocal = FALSE; /* fall thru */ case ACM_METRIC_COUNT_LOCAL_DISABLED: - if (!pao) - return MMSYSERR_INVALHANDLE; + if (hao) return MMSYSERR_INVALHANDLE; for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) - if (!padid->bEnabled /* && (local(padid) || !bLocal) */) + if (!padid->bEnabled && CheckLocal(padid)) val++; *(LPDWORD)pMetric = val; break; case ACM_METRIC_MAX_SIZE_FORMAT: - { - ACMFORMATTAGDETAILSW aftd; - - aftd.cbStruct = sizeof(aftd); - aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN; - - if (hao == (HACMOBJ)NULL) { - mmr = acmFormatTagDetailsW((HACMDRIVER)NULL, &aftd, ACM_FORMATTAGDETAILSF_LARGESTSIZE); - } else if (MSACM_GetObj(hao, WINE_ACMOBJ_DRIVER)) { - mmr = acmFormatTagDetailsW((HACMDRIVER)hao, &aftd, ACM_FORMATTAGDETAILSF_LARGESTSIZE); - } else if (MSACM_GetObj(hao, WINE_ACMOBJ_DRIVERID)) { - HACMDRIVER had; - - if (acmDriverOpen(&had, (HACMDRIVERID)hao, 0) == 0) { - mmr = acmFormatTagDetailsW((HACMDRIVER)hao, &aftd, ACM_FORMATTAGDETAILSF_LARGESTSIZE); - acmDriverClose(had, 0); + if (hao == (HACMOBJ)NULL) { + for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { + if (padid->bEnabled) { + for (i = 0; i < padid->cFormatTags; i++) { + if (val < padid->aFormatTag[i].cbwfx) + val = padid->aFormatTag[i].cbwfx; + } } - } else { - mmr = MMSYSERR_INVALHANDLE; } - if (mmr == MMSYSERR_NOERROR) *(LPDWORD)pMetric = aftd.cbFormatSize; + } else if (pao != NULL) { + switch (pao->dwType) { + case WINE_ACMOBJ_DRIVER: + case WINE_ACMOBJ_DRIVERID: + padid = pao->pACMDriverID; + break; + default: + return MMSYSERR_INVALHANDLE; + } + if (padid->bEnabled) { + for (i = 0; i < padid->cFormatTags; i++) { + if (val < padid->aFormatTag[i].cbwfx) + val = padid->aFormatTag[i].cbwfx; + } + } + } else { + return MMSYSERR_INVALHANDLE; } + *(LPDWORD)pMetric = val; break; case ACM_METRIC_COUNT_HARDWARE: diff --git a/dlls/msacm/pcmconverter.c b/dlls/msacm/pcmconverter.c index 6471e574d5f..9a801f82323 100644 --- a/dlls/msacm/pcmconverter.c +++ b/dlls/msacm/pcmconverter.c @@ -778,7 +778,8 @@ static LRESULT PCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery) afd->dwFormatTag = WAVE_FORMAT_PCM; afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CONVERTER; afd->szFormat[0] = 0; /* let MSACM format this for us... */ - + afd->cbwfx = sizeof(PCMWAVEFORMAT); + return MMSYSERR_NOERROR; } diff --git a/dlls/msacm/stream.c b/dlls/msacm/stream.c index 4c0fcc6804e..4e5b7bcb0b7 100644 --- a/dlls/msacm/stream.c +++ b/dlls/msacm/stream.c @@ -181,25 +181,30 @@ MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pw ret = ACMERR_NOTPOSSIBLE; for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) { + if (!wadi->bEnabled || + !MSACM_FindFormatTagInCache(wadi, pwfxSrc->wFormatTag, NULL) || + !MSACM_FindFormatTagInCache(wadi, pwfxDst->wFormatTag, NULL)) + continue; ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L); - if (ret == MMSYSERR_NOERROR) { - if ((wad = MSACM_GetDriver(had)) != 0) { - was->obj.dwType = WINE_ACMOBJ_STREAM; - was->obj.pACMDriverID = wad->obj.pACMDriverID; - was->pDrv = wad; - was->hAcmDriver = had; - - ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); - if (ret == MMSYSERR_NOERROR) { - if (fdwOpen & ACM_STREAMOPENF_QUERY) { - acmDriverClose(had, 0L); - } - break; + if (ret != MMSYSERR_NOERROR) + continue; + if ((wad = MSACM_GetDriver(had)) != 0) { + was->obj.dwType = WINE_ACMOBJ_STREAM; + was->obj.pACMDriverID = wad->obj.pACMDriverID; + was->pDrv = wad; + was->hAcmDriver = had; + + ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); + TRACE("%s => %08x\n", wadi->pszFileName, ret); + if (ret == MMSYSERR_NOERROR) { + if (fdwOpen & ACM_STREAMOPENF_QUERY) { + acmDriverClose(had, 0L); } + break; } - /* no match, close this acm driver and try next one */ - acmDriverClose(had, 0L); } + /* no match, close this acm driver and try next one */ + acmDriverClose(had, 0L); } if (ret != MMSYSERR_NOERROR) { ret = ACMERR_NOTPOSSIBLE; diff --git a/dlls/msacm/wineacm.h b/dlls/msacm/wineacm.h index cb43ca758c9..61e043b9ed9 100644 --- a/dlls/msacm/wineacm.h +++ b/dlls/msacm/wineacm.h @@ -307,6 +307,14 @@ typedef struct _WINE_ACMDRIVERID PWINE_ACMDRIVER pACMDriverList; PWINE_ACMDRIVERID pNextACMDriverID; PWINE_ACMDRIVERID pPrevACMDriverID; + /* information about the driver itself, either gotten from registry or driver itself */ + DWORD cFilterTags; + DWORD cFormatTags; + DWORD fdwSupport; + struct { + DWORD dwFormatTag; + DWORD cbwfx; + }* aFormatTag; } WINE_ACMDRIVERID; /* From internal.c */ @@ -323,6 +331,7 @@ extern PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver); extern PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj, DWORD type); extern MMRESULT MSACM_Message(HACMDRIVER, UINT, LPARAM, LPARAM); +extern BOOL MSACM_FindFormatTagInCache(WINE_ACMDRIVERID*, DWORD, LPDWORD); /* From msacm32.c */ extern HINSTANCE MSACM_hInstance32;