Commit faa35949 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

Added cache for drivers information.

Fixed a few bugs (memory handling, version info...) Enhanced validity checks.
parent 60268d1d
......@@ -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;
}
......
......@@ -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;
}
}
}
......
......@@ -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;
}
}
}
......
......@@ -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);
}
}
/***********************************************************************
......
......@@ -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:
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment