Added the ability to open several streams on the same driver.
Added a few acmMetrics options.
diff --git a/dlls/msacm32/driver.c b/dlls/msacm32/driver.c
index e1027c1..e22be5e 100644
--- a/dlls/msacm32/driver.c
+++ b/dlls/msacm32/driver.c
@@ -73,7 +73,8 @@
*/
MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
{
- PWINE_ACMDRIVER p;
+ PWINE_ACMDRIVER p;
+ PWINE_ACMDRIVER* tp;
if (fdwClose)
return MMSYSERR_INVALFLAG;
@@ -81,10 +82,15 @@
p = MSACM_GetDriver(had);
if (!p)
return MMSYSERR_INVALHANDLE;
+
+ for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
+ if (*tp == p) {
+ *tp = (*tp)->pNextACMDriver;
+ break;
+ }
+ }
- p->obj.pACMDriverID->pACMDriver = NULL;
-
- if (p->hDrvr)
+ if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
CloseDriver(p->hDrvr, 0, 0);
HeapFree(MSACM_hHeap, 0, p);
@@ -127,29 +133,17 @@
*/
MMRESULT WINAPI acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails)
{
- PWINE_ACMDRIVERID p;
+ HACMDRIVER acmDrvr;
MMRESULT mmr;
- BOOL bOpenTemporary;
-
- p = MSACM_GetDriverID(hadid);
- if (!p)
- return MMSYSERR_INVALHANDLE;
if (fdwDetails)
return MMSYSERR_INVALFLAG;
- bOpenTemporary = !p->pACMDriver;
- if (bOpenTemporary) {
- bOpenTemporary = TRUE;
- acmDriverOpen((PHACMDRIVER) &p->pACMDriver, hadid, 0);
- }
+ mmr = acmDriverOpen(&acmDrvr, hadid, 0);
+ if (mmr == 0) {
+ mmr = (MMRESULT)acmDriverMessage(acmDrvr, ACMDM_DRIVER_DETAILS, (LPARAM) padd, 0);
- mmr = (MMRESULT) acmDriverMessage((HACMDRIVER) p->pACMDriver, ACMDM_DRIVER_DETAILS,
- (LPARAM) padd, 0);
-
- if (bOpenTemporary) {
- acmDriverClose((HACMDRIVER) p->pACMDriver, 0);
- p->pACMDriver = NULL;
+ acmDriverClose(acmDrvr, 0);
}
return mmr;
@@ -160,8 +154,9 @@
*/
MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
{
- PWINE_ACMDRIVERID p;
-
+ PWINE_ACMDRIVERID p;
+ DWORD fdwSupport;
+
if (!fnCallback) {
return MMSYSERR_INVALPARAM;
}
@@ -170,10 +165,15 @@
return MMSYSERR_INVALFLAG;
}
- p = MSACM_pFirstACMDriverID;
- while (p) {
- (*fnCallback)((HACMDRIVERID) p, dwInstance, ACMDRIVERDETAILS_SUPPORTF_CODEC);
- p = p->pNextACMDriverID;
+ for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
+ fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
+ if (!p->bEnabled) {
+ if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
+ fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
+ else
+ continue;
+ }
+ (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
}
return MMSYSERR_NOERROR;
@@ -226,7 +226,8 @@
*/
MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
{
- PWINE_ACMDRIVERID padid;
+ PWINE_ACMDRIVERID padid;
+ PWINE_ACMDRIVER pad;
TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
@@ -240,30 +241,29 @@
if (fdwOpen)
return MMSYSERR_INVALFLAG;
- if (padid->pACMDriver) {
- /* FIXME: Is it allowed? */
- ERR("Can't open driver '%s' twice\n", padid->pszDriverAlias);
- return MMSYSERR_ERROR;
- }
-
- padid->pACMDriver = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
- padid->pACMDriver->obj.pACMDriverID = padid;
+ pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
+ if (!pad) return MMSYSERR_NOMEM;
+
+ pad->obj.pACMDriverID = padid;
if (!padid->hInstModule)
- padid->pACMDriver->hDrvr = OpenDriverA(padid->pszDriverAlias, "drivers32", 0);
+ pad->hDrvr = OpenDriverA(padid->pszDriverAlias, "drivers32", 0);
else
- padid->pACMDriver->hDrvr = padid->hInstModule;
+ pad->hDrvr = padid->hInstModule;
- if (!padid->pACMDriver->hDrvr) {
- HeapFree(MSACM_hHeap, 0, padid->pACMDriver);
- padid->pACMDriver = NULL;
+ if (!pad->hDrvr) {
+ HeapFree(MSACM_hHeap, 0, pad);
return MMSYSERR_ERROR;
}
- padid->pACMDriver->pfnDriverProc = GetProcAddress(padid->pACMDriver->hDrvr, "DriverProc");
-
+ pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
+
+ /* insert new pad at beg of list */
+ pad->pNextACMDriver = padid->pACMDriverList;
+ padid->pACMDriverList = pad;
+
/* FIXME: Create a WINE_ACMDRIVER32 */
- *phad = (HACMDRIVER) padid->pACMDriver;
+ *phad = (HACMDRIVER)pad;
return MMSYSERR_NOERROR;
}
diff --git a/dlls/msacm32/internal.c b/dlls/msacm32/internal.c
index 8b2c7e5..c179f3b 100644
--- a/dlls/msacm32/internal.c
+++ b/dlls/msacm32/internal.c
@@ -43,9 +43,9 @@
padid->pszFileName = HEAP_strdupA(MSACM_hHeap, 0, pszFileName);
padid->hInstModule = hinstModule;
padid->bEnabled = TRUE;
- padid->pACMDriver = NULL;
+ padid->pACMDriverList = NULL;
padid->pNextACMDriverID = NULL;
- padid->pPreviousACMDriverID = MSACM_pLastACMDriverID;
+ padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
if (MSACM_pLastACMDriverID)
MSACM_pLastACMDriverID->pNextACMDriverID = padid;
MSACM_pLastACMDriverID = padid;
@@ -100,8 +100,8 @@
{
PWINE_ACMDRIVERID pNextACMDriverID;
- if (p->pACMDriver)
- acmDriverClose((HACMDRIVER) p->pACMDriver, 0);
+ while (p->pACMDriverList)
+ acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
if (p->pszDriverAlias)
HeapFree(MSACM_hHeap, 0, p->pszDriverAlias);
@@ -111,12 +111,12 @@
if (p == MSACM_pFirstACMDriverID)
MSACM_pFirstACMDriverID = p->pNextACMDriverID;
if (p == MSACM_pLastACMDriverID)
- MSACM_pLastACMDriverID = p->pPreviousACMDriverID;
+ MSACM_pLastACMDriverID = p->pPrevACMDriverID;
- if (p->pPreviousACMDriverID)
- p->pPreviousACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
+ if (p->pPrevACMDriverID)
+ p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
if (p->pNextACMDriverID)
- p->pNextACMDriverID->pPreviousACMDriverID = p->pPreviousACMDriverID;
+ p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
pNextACMDriverID = p->pNextACMDriverID;
diff --git a/dlls/msacm32/msacm32_main.c b/dlls/msacm32/msacm32_main.c
index d46ce27..86437b3 100644
--- a/dlls/msacm32/msacm32_main.c
+++ b/dlls/msacm32/msacm32_main.c
@@ -87,36 +87,73 @@
*/
MMRESULT WINAPI acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric)
{
- PWINE_ACMOBJ pao = MSACM_GetObj(hao);
- BOOL bLocal = TRUE;
-
+ PWINE_ACMOBJ pao = MSACM_GetObj(hao);
+ BOOL bLocal = TRUE;
+ PWINE_ACMDRIVERID padid;
+ DWORD val = 0;
+
FIXME("(0x%08x, %d, %p): stub\n", hao, uMetric, pMetric);
switch (uMetric) {
case ACM_METRIC_COUNT_DRIVERS:
bLocal = FALSE;
+ /* fall thru */
case ACM_METRIC_COUNT_LOCAL_DRIVERS:
if (!pao)
- return MMSYSERR_INVALHANDLE;
- return MMSYSERR_NOTSUPPORTED;
+ return MMSYSERR_INVALHANDLE;
+ for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
+ if (padid->bEnabled /* && (local(padid) || !bLocal) */)
+ val++;
+ *(LPDWORD)pMetric = val;
+ return 0;
+
case ACM_METRIC_COUNT_CODECS:
+ if (!pao)
+ return MMSYSERR_INVALHANDLE;
bLocal = FALSE;
+ /* fall thru */
case ACM_METRIC_COUNT_LOCAL_CODECS:
- return MMSYSERR_NOTSUPPORTED;
+ /* FIXME: don't know how to differentiate codec, converters & filters yet */
+ for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
+ if (padid->bEnabled /* && (local(padid) || !bLocal) */)
+ val++;
+ *(LPDWORD)pMetric = val;
+ return 0;
+
case ACM_METRIC_COUNT_CONVERTERS:
bLocal = FALSE;
+ /* fall thru */
case ACM_METRIC_COUNT_LOCAL_CONVERTERS:
- return MMSYSERR_NOTSUPPORTED;
+ /* FIXME: don't know how to differentiate codec, converters & filters yet */
+ for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
+ if (padid->bEnabled /* && (local(padid) || !bLocal) */)
+ val++;
+ *(LPDWORD)pMetric = val;
+ return 0;
+
case ACM_METRIC_COUNT_FILTERS:
bLocal = FALSE;
+ /* fall thru */
case ACM_METRIC_COUNT_LOCAL_FILTERS:
- return MMSYSERR_NOTSUPPORTED;
+ /* FIXME: don't know how to differentiate codec, converters & filters yet */
+ for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
+ if (padid->bEnabled /* && (local(padid) || !bLocal) */)
+ val++;
+ *(LPDWORD)pMetric = val;
+ return 0;
+
case ACM_METRIC_COUNT_DISABLED:
bLocal = FALSE;
+ /* fall thru */
case ACM_METRIC_COUNT_LOCAL_DISABLED:
if (!pao)
return MMSYSERR_INVALHANDLE;
- return MMSYSERR_NOTSUPPORTED;
+ for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
+ if (!padid->bEnabled /* && (local(padid) || !bLocal) */)
+ val++;
+ *(LPDWORD)pMetric = val;
+ return 0;
+
case ACM_METRIC_COUNT_HARDWARE:
case ACM_METRIC_HARDWARE_WAVE_INPUT:
case ACM_METRIC_HARDWARE_WAVE_OUTPUT:
diff --git a/dlls/msacm32/wineacm.h b/dlls/msacm32/wineacm.h
index dfe1730..b86641c 100644
--- a/dlls/msacm32/wineacm.h
+++ b/dlls/msacm32/wineacm.h
@@ -4,6 +4,7 @@
* Wine specific - Win32
*/
typedef struct _WINE_ACMDRIVERID *PWINE_ACMDRIVERID;
+typedef struct _WINE_ACMDRIVER *PWINE_ACMDRIVER;
typedef struct _WINE_ACMOBJ
{
@@ -15,7 +16,8 @@
WINE_ACMOBJ obj;
HDRVR hDrvr;
DRIVERPROC pfnDriverProc;
-} WINE_ACMDRIVER, *PWINE_ACMDRIVER;
+ PWINE_ACMDRIVER pNextACMDriver;
+} WINE_ACMDRIVER;
typedef struct _WINE_ACMSTREAM
{
@@ -32,9 +34,9 @@
HINSTANCE hInstModule; /* NULL if global */
DWORD dwProcessID; /* ID of process which installed a local driver */
BOOL bEnabled;
- PWINE_ACMDRIVER pACMDriver; /* NULL if not open; shouldn't this be a list ? */
+ PWINE_ACMDRIVER pACMDriverList;
PWINE_ACMDRIVERID pNextACMDriverID;
- PWINE_ACMDRIVERID pPreviousACMDriverID;
+ PWINE_ACMDRIVERID pPrevACMDriverID;
} WINE_ACMDRIVERID;
/* From internal.c */