diff --git a/dlls/msacm32/driver.c b/dlls/msacm32/driver.c index e1027c1986c..e22be5e67fb 100644 --- a/dlls/msacm32/driver.c +++ b/dlls/msacm32/driver.c @@ -73,7 +73,8 @@ MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule, */ 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 @@ MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose) 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 acmDriverDetailsA(HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, D */ 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 acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, D */ 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 @@ MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWOR 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 @@ LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARA */ 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 @@ MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpe 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 8b2c7e566ef..c179f3b2e4b 100644 --- a/dlls/msacm32/internal.c +++ b/dlls/msacm32/internal.c @@ -43,9 +43,9 @@ PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName, 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 MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) { 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 @@ PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) 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 d46ce273be1..86437b33cb1 100644 --- a/dlls/msacm32/msacm32_main.c +++ b/dlls/msacm32/msacm32_main.c @@ -87,36 +87,73 @@ DWORD WINAPI acmGetVersion(void) */ 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 dfe1730ab56..b86641cc44b 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 @@ typedef struct _WINE_ACMDRIVER WINE_ACMOBJ obj; HDRVR hDrvr; DRIVERPROC pfnDriverProc; -} WINE_ACMDRIVER, *PWINE_ACMDRIVER; + PWINE_ACMDRIVER pNextACMDriver; +} WINE_ACMDRIVER; typedef struct _WINE_ACMSTREAM { @@ -32,9 +34,9 @@ typedef struct _WINE_ACMDRIVERID 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 */