/* -*- tab-width: 8; c-basic-offset: 4 -*- */

/*
 *      MSACM32 library
 *
 *      Copyright 1998  Patrik Stridvall
 *		  1999	Eric Pouech
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "winreg.h"
#include "mmsystem.h"
#include "mmreg.h"
#include "msacm.h"
#include "msacmdrv.h"
#include "wineacm.h"
#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(msacm);

/**********************************************************************/

HANDLE MSACM_hHeap = NULL;
PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;

static DWORD MSACM_suspendBroadcastCount = 0;
static BOOL MSACM_pendingBroadcast = FALSE;
static PWINE_ACMNOTIFYWND MSACM_pFirstACMNotifyWnd = NULL;
static PWINE_ACMNOTIFYWND MSACM_pLastACMNotifyWnd = NULL;

static void MSACM_ReorderDriversByPriority(void);

/***********************************************************************
 *           MSACM_RegisterDriverFromRegistry()
 */
PWINE_ACMDRIVERID MSACM_RegisterDriverFromRegistry(LPCWSTR pszRegEntry)
{
    static const WCHAR msacmW[] = {'M','S','A','C','M','.'};
    static const WCHAR drvkey[] = {'S','o','f','t','w','a','r','e','\\',
				   'M','i','c','r','o','s','o','f','t','\\',
				   'W','i','n','d','o','w','s',' ','N','T','\\',
				   'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
				   'D','r','i','v','e','r','s','3','2','\0'};
    WCHAR buf[2048];
    DWORD bufLen, lRet;
    HKEY hKey;
    PWINE_ACMDRIVERID padid = NULL;
    
    /* The requested registry entry must have the format msacm.XXXXX in order to
       be recognized in any future sessions of msacm
     */
    if (0 == strncmpiW(buf, msacmW, sizeof(msacmW)/sizeof(WCHAR))) {
        lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drvkey, 0, KEY_QUERY_VALUE, &hKey);
        if (lRet != ERROR_SUCCESS) {
            WARN("unable to open registry key - 0x%08x\n", lRet);
        } else {
            bufLen = sizeof(buf);
            lRet = RegQueryValueExW(hKey, pszRegEntry, NULL, NULL, (LPBYTE)buf, &bufLen);
            if (lRet != ERROR_SUCCESS) {
                WARN("unable to query requested subkey %s - 0x%08x\n", debugstr_w(pszRegEntry), lRet);
            } else {
                MSACM_RegisterDriver(pszRegEntry, buf, 0);
            }
            RegCloseKey( hKey );
        }
    }
    return padid;
}

#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(const 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;
    unsigned int		        ntag;
    ACMDRIVERDETAILSW	        add;
    ACMFORMATTAGDETAILSW        aftd;

    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);

    for (ntag = 0; ntag < add.cFormatTags; ntag++) {
	aftd.dwFormatTagIndex = ntag;
	if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)&aftd, ACM_FORMATTAGDETAILSF_INDEX)) {
	    TRACE("IIOs (%s)\n", debugstr_w(padid->pszDriverAlias));
	    goto errCleanUp;
	}
	padid->aFormatTag[ntag].dwFormatTag = aftd.dwFormatTag;
	padid->aFormatTag[ntag].cbwfx = aftd.cbFormatSize;
    }

    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	LPWSTR	MSACM_GetRegistryKey(const WINE_ACMDRIVERID* padid)
{
    static const WCHAR	baseKey[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
                                     'A','u','d','i','o','C','o','m','p','r','e','s','s','i','o','n','M','a','n','a','g','e','r','\\',
                                     'D','r','i','v','e','r','C','a','c','h','e','\\','\0'};
    LPWSTR	ret;
    int		len;

    if (!padid->pszDriverAlias) {
	ERR("No alias needed for registry entry\n");
	return NULL;
    }
    len = strlenW(baseKey);
    ret = HeapAlloc(MSACM_hHeap, 0, (len + strlenW(padid->pszDriverAlias) + 1) * sizeof(WCHAR));
    if (!ret) return NULL;

    strcpyW(ret, baseKey);
    strcpyW(ret + len, padid->pszDriverAlias);
    CharLowerW(ret + len);
    return ret;
}

/***********************************************************************
 *           MSACM_ReadCache
 */
static BOOL MSACM_ReadCache(PWINE_ACMDRIVERID padid)
{
    LPWSTR	key = MSACM_GetRegistryKey(padid);
    HKEY	hKey;
    DWORD	type, size;

    if (!key) return FALSE;

    padid->aFormatTag = NULL;

    if (RegCreateKeyW(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(const WINE_ACMDRIVERID *padid)
{
    LPWSTR	key = MSACM_GetRegistryKey(padid);
    HKEY	hKey;

    if (!key) return FALSE;

    if (RegCreateKeyW(HKEY_LOCAL_MACHINE, key, &hKey))
	goto errCleanUp;

    if (RegSetValueExA(hKey, "cFormatTags", 0, REG_DWORD, (const void*)&padid->cFormatTags, sizeof(DWORD)))
	goto errCleanUp;
    if (RegSetValueExA(hKey, "cFilterTags", 0, REG_DWORD, (const void*)&padid->cFilterTags, sizeof(DWORD)))
	goto errCleanUp;
    if (RegSetValueExA(hKey, "fdwSupport", 0, REG_DWORD, (const 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()
 */
PWINE_ACMDRIVERID MSACM_RegisterDriver(LPCWSTR pszDriverAlias, LPCWSTR pszFileName,
				       PWINE_ACMLOCALDRIVER pLocalDriver)
{
    PWINE_ACMDRIVERID	padid;

    TRACE("(%s, %s, %p)\n", 
          debugstr_w(pszDriverAlias), debugstr_w(pszFileName), pLocalDriver);

    padid = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
    padid->obj.dwType = WINE_ACMOBJ_DRIVERID;
    padid->obj.pACMDriverID = padid;
    padid->pszDriverAlias = NULL;
    if (pszDriverAlias)
    {
        padid->pszDriverAlias = HeapAlloc( MSACM_hHeap, 0, (strlenW(pszDriverAlias)+1) * sizeof(WCHAR) );
        strcpyW( padid->pszDriverAlias, pszDriverAlias );
    }
    padid->pszFileName = NULL;
    if (pszFileName)
    {
        padid->pszFileName = HeapAlloc( MSACM_hHeap, 0, (strlenW(pszFileName)+1) * sizeof(WCHAR) );
        strcpyW( padid->pszFileName, pszFileName );
    }
    padid->pLocalDriver = pLocalDriver;

    padid->pACMDriverList = NULL;
    
    if (pLocalDriver) {
        padid->pPrevACMDriverID = NULL;
        padid->pNextACMDriverID = MSACM_pFirstACMDriverID;
        if (MSACM_pFirstACMDriverID)
            MSACM_pFirstACMDriverID->pPrevACMDriverID = padid;
        MSACM_pFirstACMDriverID = padid;
        if (!MSACM_pLastACMDriverID)
            MSACM_pLastACMDriverID = padid;
    } else {
        padid->pNextACMDriverID = NULL;
        padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
        if (MSACM_pLastACMDriverID)
	    MSACM_pLastACMDriverID->pNextACMDriverID = padid;
        MSACM_pLastACMDriverID = padid;
        if (!MSACM_pFirstACMDriverID)
	    MSACM_pFirstACMDriverID = padid;
    }
    /* disable the driver if we cannot load the cache */
    if ((!padid->pszDriverAlias || !MSACM_ReadCache(padid)) && !MSACM_FillCache(padid)) {
	WARN("Couldn't load cache for ACM driver (%s)\n", debugstr_w(pszFileName));
	MSACM_UnregisterDriver(padid);
	return NULL;
    }

    if (pLocalDriver) padid->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_LOCAL;
    return padid;
}

/***********************************************************************
 *           MSACM_RegisterAllDrivers()
 */
void MSACM_RegisterAllDrivers(void)
{
    static const WCHAR msacm32[] = {'m','s','a','c','m','3','2','.','d','l','l','\0'};
    static const WCHAR msacmW[] = {'M','S','A','C','M','.'};
    static const WCHAR drv32[] = {'d','r','i','v','e','r','s','3','2','\0'};
    static const WCHAR sys[] = {'s','y','s','t','e','m','.','i','n','i','\0'};
    static const WCHAR drvkey[] = {'S','o','f','t','w','a','r','e','\\',
				   'M','i','c','r','o','s','o','f','t','\\',
				   'W','i','n','d','o','w','s',' ','N','T','\\',
				   'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
				   'D','r','i','v','e','r','s','3','2','\0'};
    DWORD i, cnt = 0, bufLen, lRet;
    WCHAR buf[2048], *name, *s;
    FILETIME lastWrite;
    HKEY hKey;

    /* FIXME: What if the user edits system.ini while the program is running?
     * Does Windows handle that?  */
    if (MSACM_pFirstACMDriverID) return;

    lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drvkey, 0, KEY_QUERY_VALUE, &hKey);
    if (lRet == ERROR_SUCCESS) {
	RegQueryInfoKeyW( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
	for (i = 0; i < cnt; i++) {
	    bufLen = sizeof(buf) / sizeof(buf[0]);
	    lRet = RegEnumKeyExW(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
	    if (lRet != ERROR_SUCCESS) continue;
	    if (strncmpiW(buf, msacmW, sizeof(msacmW)/sizeof(msacmW[0]))) continue;
	    if (!(name = strchrW(buf, '='))) continue;
	    *name = 0;
	    MSACM_RegisterDriver(buf, name + 1, 0);
	}
    	RegCloseKey( hKey );
    }

    if (GetPrivateProfileSectionW(drv32, buf, sizeof(buf)/sizeof(buf[0]), sys))
    {
	for(s = buf; *s;  s += strlenW(s) + 1)
	{
	    if (strncmpiW(s, msacmW, sizeof(msacmW)/sizeof(msacmW[0]))) continue;
	    if (!(name = strchrW(s, '='))) continue;
	    *name = 0;
	    MSACM_RegisterDriver(s, name + 1, 0);
	    *name = '=';
	}
    }
    MSACM_ReorderDriversByPriority();
    MSACM_RegisterDriver(msacm32, msacm32, 0);
}

/***********************************************************************
 *           MSACM_RegisterNotificationWindow()
 */
PWINE_ACMNOTIFYWND MSACM_RegisterNotificationWindow(HWND hNotifyWnd, DWORD dwNotifyMsg)
{
    PWINE_ACMNOTIFYWND	panwnd;

    TRACE("(%p,0x%08x)\n", hNotifyWnd, dwNotifyMsg);

    panwnd = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMNOTIFYWND));
    panwnd->obj.dwType = WINE_ACMOBJ_NOTIFYWND;
    panwnd->obj.pACMDriverID = 0;
    panwnd->hNotifyWnd = hNotifyWnd;
    panwnd->dwNotifyMsg = dwNotifyMsg;
    panwnd->fdwSupport = 0;
    
    panwnd->pNextACMNotifyWnd = NULL;
    panwnd->pPrevACMNotifyWnd = MSACM_pLastACMNotifyWnd;
    if (MSACM_pLastACMNotifyWnd)
        MSACM_pLastACMNotifyWnd->pNextACMNotifyWnd = panwnd;
    MSACM_pLastACMNotifyWnd = panwnd;
    if (!MSACM_pFirstACMNotifyWnd)
        MSACM_pFirstACMNotifyWnd = panwnd;

    return panwnd;
}

/***********************************************************************
 *           MSACM_BroadcastNotification()
 */
void MSACM_BroadcastNotification(void)
{
    if (MSACM_suspendBroadcastCount <= 0) {
        PWINE_ACMNOTIFYWND panwnd;

        for (panwnd = MSACM_pFirstACMNotifyWnd; panwnd; panwnd = panwnd->pNextACMNotifyWnd) 
        if (!(panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED))
            SendMessageW(panwnd->hNotifyWnd, panwnd->dwNotifyMsg, 0, 0);
    } else {
        MSACM_pendingBroadcast = TRUE;
    }
}

/***********************************************************************
 *           MSACM_DisableNotifications()
 */
void MSACM_DisableNotifications(void)
{
    MSACM_suspendBroadcastCount++;
}

/***********************************************************************
 *           MSACM_EnableNotifications()
 */
void MSACM_EnableNotifications(void)
{
    if (MSACM_suspendBroadcastCount > 0) {
        MSACM_suspendBroadcastCount--;
        if (MSACM_suspendBroadcastCount == 0 && MSACM_pendingBroadcast) {
            MSACM_pendingBroadcast = FALSE;
            MSACM_BroadcastNotification();
        }
    }
}

/***********************************************************************
 *           MSACM_UnRegisterNotificationWindow()
 */
PWINE_ACMNOTIFYWND MSACM_UnRegisterNotificationWindow(const WINE_ACMNOTIFYWND *panwnd)
{
    PWINE_ACMNOTIFYWND p;

    for (p = MSACM_pFirstACMNotifyWnd; p; p = p->pNextACMNotifyWnd) {
        if (p == panwnd) {
            PWINE_ACMNOTIFYWND pNext = p->pNextACMNotifyWnd;

            if (p->pPrevACMNotifyWnd) p->pPrevACMNotifyWnd->pNextACMNotifyWnd = p->pNextACMNotifyWnd;
            if (p->pNextACMNotifyWnd) p->pNextACMNotifyWnd->pPrevACMNotifyWnd = p->pPrevACMNotifyWnd;
            if (MSACM_pFirstACMNotifyWnd == p) MSACM_pFirstACMNotifyWnd = p->pNextACMNotifyWnd;
            if (MSACM_pLastACMNotifyWnd == p) MSACM_pLastACMNotifyWnd = p->pPrevACMNotifyWnd;
            HeapFree(MSACM_hHeap, 0, p);
            
            return pNext;
        }
    }
    return NULL;
}

/***********************************************************************
 *           MSACM_RePositionDriver()
 */
void MSACM_RePositionDriver(PWINE_ACMDRIVERID padid, DWORD dwPriority)
{
    PWINE_ACMDRIVERID pTargetPosition = NULL;
                
    /* Remove selected driver from linked list */
    if (MSACM_pFirstACMDriverID == padid) {
        MSACM_pFirstACMDriverID = padid->pNextACMDriverID;
    }
    if (MSACM_pLastACMDriverID == padid) {
        MSACM_pLastACMDriverID = padid->pPrevACMDriverID;
    }
    if (padid->pPrevACMDriverID != NULL) {
        padid->pPrevACMDriverID->pNextACMDriverID = padid->pNextACMDriverID;
    }
    if (padid->pNextACMDriverID != NULL) {
        padid->pNextACMDriverID->pPrevACMDriverID = padid->pPrevACMDriverID;
    }
    
    /* Look up position where selected driver should be */
    if (dwPriority == 1) {
        pTargetPosition = padid->pPrevACMDriverID;
        while (pTargetPosition->pPrevACMDriverID != NULL &&
            !(pTargetPosition->pPrevACMDriverID->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL)) {
            pTargetPosition = pTargetPosition->pPrevACMDriverID;
        }
    } else if (dwPriority == -1) {
        pTargetPosition = padid->pNextACMDriverID;
        while (pTargetPosition->pNextACMDriverID != NULL) {
            pTargetPosition = pTargetPosition->pNextACMDriverID;
        }
    }
    
    /* Place selected driver in selected position */
    padid->pPrevACMDriverID = pTargetPosition->pPrevACMDriverID;
    padid->pNextACMDriverID = pTargetPosition;
    if (padid->pPrevACMDriverID != NULL) {
        padid->pPrevACMDriverID->pNextACMDriverID = padid;
    } else {
        MSACM_pFirstACMDriverID = padid;
    }
    if (padid->pNextACMDriverID != NULL) {
        padid->pNextACMDriverID->pPrevACMDriverID = padid;
    } else {
        MSACM_pLastACMDriverID = padid;
    }
}

/***********************************************************************
 *           MSACM_ReorderDriversByPriority()
 * Reorders all drivers based on the priority list indicated by the registry key:
 * HKCU\\Software\\Microsoft\\Multimedia\\Audio Compression Manager\\Priority v4.00
 */
static void MSACM_ReorderDriversByPriority(void)
{
    PWINE_ACMDRIVERID	padid;
    unsigned int iNumDrivers;
    PWINE_ACMDRIVERID * driverList = NULL;
    HKEY hPriorityKey = NULL;
    
    TRACE("\n");
    
    /* Count drivers && alloc corresponding memory for list */
    iNumDrivers = 0;
    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) iNumDrivers++;
    if (iNumDrivers > 1)
    {
        LONG lError;
        static const WCHAR basePriorityKey[] = {
            'S','o','f','t','w','a','r','e','\\',
            'M','i','c','r','o','s','o','f','t','\\',
            'M','u','l','t','i','m','e','d','i','a','\\',
            'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
            'P','r','i','o','r','i','t','y',' ','v','4','.','0','0','\0'
        };
        unsigned int i;
        LONG lBufferLength;
        WCHAR szBuffer[256];
        
        driverList = HeapAlloc(MSACM_hHeap, 0, iNumDrivers * sizeof(PWINE_ACMDRIVERID));
        if (!driverList)
        {
            ERR("out of memory\n");
            goto errCleanUp;
        }

        lError = RegOpenKeyW(HKEY_CURRENT_USER, basePriorityKey, &hPriorityKey);
        if (lError != ERROR_SUCCESS) {
            TRACE("RegOpenKeyW failed, possibly key does not exist yet\n");
            hPriorityKey = NULL;
            goto errCleanUp;
        } 
            
        /* Copy drivers into list to simplify linked list modification */
        for (i = 0, padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID, i++)
        {
            driverList[i] = padid;
        }

        /* Query each of the priorities in turn. Alias key is in lowercase. 
            The general form of the priority record is the following:
            "PriorityN" --> "1, msacm.driveralias"
            where N is an integer, and the value is a string of the driver
            alias, prefixed by "1, " for an enabled driver, or "0, " for a
            disabled driver.
            */
        for (i = 0; i < iNumDrivers; i++)
        {
            static const WCHAR priorityTmpl[] = {'P','r','i','o','r','i','t','y','%','l','d','\0'};
            WCHAR szSubKey[17];
            unsigned int iTargetPosition;
            unsigned int iCurrentPosition;
            WCHAR * pAlias;
            static const WCHAR sPrefix[] = {'m','s','a','c','m','.','\0'};
            
            /* Build expected entry name */
            snprintfW(szSubKey, 17, priorityTmpl, i + 1);
            lBufferLength = sizeof(szBuffer);
            lError = RegQueryValueExW(hPriorityKey, szSubKey, NULL, NULL, (LPBYTE)szBuffer, (LPDWORD)&lBufferLength);
            if (lError != ERROR_SUCCESS) continue;

            /* Recovered driver alias should be at this position */
            iTargetPosition = i;
            
            /* Locate driver alias in driver list */
            pAlias = strstrW(szBuffer, sPrefix);
            if (pAlias == NULL) continue;
            
            for (iCurrentPosition = 0; iCurrentPosition < iNumDrivers; iCurrentPosition++) {
                if (strcmpiW(driverList[iCurrentPosition]->pszDriverAlias, pAlias) == 0) 
                    break;
            }
            if (iCurrentPosition < iNumDrivers && iTargetPosition != iCurrentPosition) {
                padid = driverList[iTargetPosition];
                driverList[iTargetPosition] = driverList[iCurrentPosition];
                driverList[iCurrentPosition] = padid;

                /* Locate enabled status */
                if (szBuffer[0] == '1') {
                    driverList[iTargetPosition]->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED;
                } else if (szBuffer[0] == '0') {
                    driverList[iTargetPosition]->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
                }
            }
        }
        
        /* Re-assign pointers so that linked list traverses the ordered array */
        for (i = 0; i < iNumDrivers; i++) {
            driverList[i]->pPrevACMDriverID = (i > 0) ? driverList[i - 1] : NULL;
            driverList[i]->pNextACMDriverID = (i < iNumDrivers - 1) ? driverList[i + 1] : NULL;
        }
        MSACM_pFirstACMDriverID = driverList[0];
        MSACM_pLastACMDriverID = driverList[iNumDrivers - 1];
    }
    
errCleanUp:
    if (hPriorityKey != NULL) RegCloseKey(hPriorityKey);
    HeapFree(MSACM_hHeap, 0, driverList);
}

/***********************************************************************
 *           MSACM_WriteCurrentPriorities()
 * Writes out current order of driver priorities to registry key:
 * HKCU\\Software\\Microsoft\\Multimedia\\Audio Compression Manager\\Priority v4.00
 */
void MSACM_WriteCurrentPriorities(void)
{
    LONG lError;
    HKEY hPriorityKey;
    static const WCHAR basePriorityKey[] = {
        'S','o','f','t','w','a','r','e','\\',
        'M','i','c','r','o','s','o','f','t','\\',
        'M','u','l','t','i','m','e','d','i','a','\\',
        'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
        'P','r','i','o','r','i','t','y',' ','v','4','.','0','0','\0'
    };
    PWINE_ACMDRIVERID padid;
    DWORD dwPriorityCounter;
    static const WCHAR priorityTmpl[] = {'P','r','i','o','r','i','t','y','%','l','d','\0'};
    static const WCHAR valueTmpl[] = {'%','c',',',' ','%','s','\0'};
    static const WCHAR converterAlias[] = {'I','n','t','e','r','n','a','l',' ','P','C','M',' ','C','o','n','v','e','r','t','e','r','\0'};
    WCHAR szSubKey[17];
    WCHAR szBuffer[256];

    /* Delete ACM priority key and create it anew */
    lError = RegDeleteKeyW(HKEY_CURRENT_USER, basePriorityKey);
    if (lError != ERROR_SUCCESS && lError != ERROR_FILE_NOT_FOUND) {
        ERR("unable to remove current key %s (0x%08x) - priority changes won't persist past application end.\n",
            debugstr_w(basePriorityKey), lError);
        return;
    }
    lError = RegCreateKeyW(HKEY_CURRENT_USER, basePriorityKey, &hPriorityKey);
    if (lError != ERROR_SUCCESS) {
        ERR("unable to create key %s (0x%08x) - priority changes won't persist past application end.\n",
            debugstr_w(basePriorityKey), lError);
        return;
    }
    
    /* Write current list of priorities */
    for (dwPriorityCounter = 0, padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {        
        if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL) continue;
        if (padid->pszDriverAlias == NULL) continue;    /* internal PCM converter is last */

        /* Build required value name */
        dwPriorityCounter++;
        snprintfW(szSubKey, 17, priorityTmpl, dwPriorityCounter);
        
        /* Value has a 1 in front for enabled drivers and 0 for disabled drivers */
        snprintfW(szBuffer, 256, valueTmpl, (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ? '0' : '1', padid->pszDriverAlias);
        strlwrW(szBuffer);
        
        lError = RegSetValueExW(hPriorityKey, szSubKey, 0, REG_SZ, (BYTE *)szBuffer, (strlenW(szBuffer) + 1) * sizeof(WCHAR));
        if (lError != ERROR_SUCCESS) {
            ERR("unable to write value for %s under key %s (0x%08x)\n",
                debugstr_w(padid->pszDriverAlias), debugstr_w(basePriorityKey), lError);
        }
    }
    
    /* Build required value name */
    dwPriorityCounter++;
    snprintfW(szSubKey, 17, priorityTmpl, dwPriorityCounter);
        
    /* Value has a 1 in front for enabled drivers and 0 for disabled drivers */
    snprintfW(szBuffer, 256, valueTmpl, '1', converterAlias);
        
    lError = RegSetValueExW(hPriorityKey, szSubKey, 0, REG_SZ, (BYTE *)szBuffer, (strlenW(szBuffer) + 1) * sizeof(WCHAR));
    if (lError != ERROR_SUCCESS) {
        ERR("unable to write value for %s under key %s (0x%08x)\n",
            debugstr_w(converterAlias), debugstr_w(basePriorityKey), lError);
    }
    RegCloseKey(hPriorityKey);
}

/***********************************************************************
 *           MSACM_UnregisterDriver()
 */
PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
{
    PWINE_ACMDRIVERID pNextACMDriverID;

    while (p->pACMDriverList)
	acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);

    HeapFree(MSACM_hHeap, 0, p->pszDriverAlias);
    HeapFree(MSACM_hHeap, 0, p->pszFileName);
    HeapFree(MSACM_hHeap, 0, p->aFormatTag);

    if (p == MSACM_pFirstACMDriverID)
	MSACM_pFirstACMDriverID = p->pNextACMDriverID;
    if (p == MSACM_pLastACMDriverID)
	MSACM_pLastACMDriverID = p->pPrevACMDriverID;

    if (p->pPrevACMDriverID)
	p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
    if (p->pNextACMDriverID)
	p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;

    pNextACMDriverID = p->pNextACMDriverID;

    if (p->pLocalDriver) MSACM_UnregisterLocalDriver(p->pLocalDriver);
    HeapFree(MSACM_hHeap, 0, p);

    return pNextACMDriverID;
}

/***********************************************************************
 *           MSACM_UnregisterAllDrivers()
 */
void MSACM_UnregisterAllDrivers(void)
{
    PWINE_ACMNOTIFYWND panwnd = MSACM_pFirstACMNotifyWnd;
    PWINE_ACMDRIVERID p = MSACM_pFirstACMDriverID;

    while (p) {
	MSACM_WriteCache(p);
	p = MSACM_UnregisterDriver(p);
    }
    
    while (panwnd) {
	panwnd = MSACM_UnRegisterNotificationWindow(panwnd);
    }
}

/***********************************************************************
 *           MSACM_GetObj()
 */
PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj, DWORD type)
{
    PWINE_ACMOBJ	pao = (PWINE_ACMOBJ)hObj;

    if (pao == NULL || IsBadReadPtr(pao, sizeof(WINE_ACMOBJ)) ||
	((type != WINE_ACMOBJ_DONTCARE) && (type != pao->dwType)))
	return NULL;
    return pao;
}

/***********************************************************************
 *           MSACM_GetDriverID()
 */
PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
{
    return (PWINE_ACMDRIVERID)MSACM_GetObj((HACMOBJ)hDriverID, WINE_ACMOBJ_DRIVERID);
}

/***********************************************************************
 *           MSACM_GetDriver()
 */
PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
{
    return (PWINE_ACMDRIVER)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_DRIVER);
}

/***********************************************************************
 *           MSACM_GetNotifyWnd()
 */
PWINE_ACMNOTIFYWND MSACM_GetNotifyWnd(HACMDRIVERID hDriver)
{
    return (PWINE_ACMNOTIFYWND)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_NOTIFYWND);
}

/***********************************************************************
 *           MSACM_GetLocalDriver()
 */
/* 
PWINE_ACMLOCALDRIVER MSACM_GetLocalDriver(HACMDRIVER hDriver)
{
    return (PWINE_ACMLOCALDRIVER)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_LOCALDRIVER);
}
*/
#define MSACM_DRIVER_SendMessage(PDRVRINST, msg, lParam1, lParam2) \
        (PDRVRINST)->pLocalDriver->lpDrvProc((PDRVRINST)->dwDriverID, (HDRVR)(PDRVRINST), msg, lParam1, lParam2)

/***********************************************************************
 *           MSACM_Message()
 */
MMRESULT MSACM_Message(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
{
    PWINE_ACMDRIVER	pad = MSACM_GetDriver(had);

    if (!pad) return MMSYSERR_INVALHANDLE;
    if (pad->hDrvr) return SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2);
    if (pad->pLocalDrvrInst) return MSACM_DRIVER_SendMessage(pad->pLocalDrvrInst, uMsg, lParam1, lParam2);

    return MMSYSERR_INVALHANDLE;
}

static PWINE_ACMLOCALDRIVER MSACM_pFirstACMLocalDriver;
static PWINE_ACMLOCALDRIVER MSACM_pLastACMLocalDriver;

PWINE_ACMLOCALDRIVER MSACM_RegisterLocalDriver(HMODULE hModule, DRIVERPROC lpDriverProc)
{
    PWINE_ACMLOCALDRIVER paldrv;

    TRACE("(%p, %p)\n", hModule, lpDriverProc);
    if (!hModule || !lpDriverProc) return NULL;
    
    /* look up previous instance of local driver module */
    for (paldrv = MSACM_pFirstACMLocalDriver; paldrv; paldrv = paldrv->pNextACMLocalDrv)
    {
        if (paldrv->hModule == hModule && paldrv->lpDrvProc == lpDriverProc) return paldrv;
    }

    paldrv = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMLOCALDRIVER));
    paldrv->obj.dwType = WINE_ACMOBJ_LOCALDRIVER;
    paldrv->obj.pACMDriverID = 0;
    paldrv->hModule = hModule;
    paldrv->lpDrvProc = lpDriverProc;
    paldrv->pACMInstList = NULL;

    paldrv->pNextACMLocalDrv = NULL;
    paldrv->pPrevACMLocalDrv = MSACM_pLastACMLocalDriver;
    if (MSACM_pLastACMLocalDriver)
	MSACM_pLastACMLocalDriver->pNextACMLocalDrv = paldrv;
    MSACM_pLastACMLocalDriver = paldrv;
    if (!MSACM_pFirstACMLocalDriver)
	MSACM_pFirstACMLocalDriver = paldrv;

    return paldrv;
}

/**************************************************************************
 *			MSACM_GetNumberOfModuleRefs		[internal]
 *
 * Returns the number of open drivers which share the same module.
 * Inspired from implementation in dlls/winmm/driver.c
 */
static unsigned MSACM_GetNumberOfModuleRefs(HMODULE hModule, DRIVERPROC lpDrvProc, WINE_ACMLOCALDRIVERINST ** found)
{
    PWINE_ACMLOCALDRIVER lpDrv;
    unsigned		count = 0;

    if (found) *found = NULL;
    for (lpDrv = MSACM_pFirstACMLocalDriver; lpDrv; lpDrv = lpDrv->pNextACMLocalDrv)
    {
	if (lpDrv->hModule == hModule && lpDrv->lpDrvProc == lpDrvProc)
        {
            PWINE_ACMLOCALDRIVERINST pInst = lpDrv->pACMInstList;
        
	    while (pInst) {
                if (found && !*found) *found = pInst;
	        count++;
	        pInst = pInst->pNextACMInst;
	    }
	}
    }
    return count;
}

/**************************************************************************
 *				MSACM_RemoveFromList		[internal]
 *
 * Generates all the logic to handle driver closure / deletion
 * Removes a driver struct to the list of open drivers.
 */
static	BOOL	MSACM_RemoveFromList(PWINE_ACMLOCALDRIVERINST lpDrv)
{
    PWINE_ACMLOCALDRIVER pDriverBase = lpDrv->pLocalDriver;
    PWINE_ACMLOCALDRIVERINST pPrevInst;

    /* last of this driver in list ? */
    if (MSACM_GetNumberOfModuleRefs(pDriverBase->hModule, pDriverBase->lpDrvProc, NULL) == 1) {
        MSACM_DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
        MSACM_DRIVER_SendMessage(lpDrv, DRV_FREE,    0L, 0L);
    }
    
    pPrevInst = NULL;
    if (pDriverBase->pACMInstList != lpDrv) {
        pPrevInst = pDriverBase->pACMInstList;
        while (pPrevInst && pPrevInst->pNextACMInst != lpDrv)
            pPrevInst = pPrevInst->pNextACMInst;
        if (!pPrevInst) {
            ERR("requested to remove invalid instance %p\n", pPrevInst);
            return FALSE;
        }
    }
    if (!pPrevInst) {
        /* first driver instance on list */
        pDriverBase->pACMInstList = lpDrv->pNextACMInst;
    } else {
        pPrevInst->pNextACMInst = lpDrv->pNextACMInst;
    }
    return TRUE;
}

/**************************************************************************
 *				MSACM_AddToList		[internal]
 *
 * Adds a driver struct to the list of open drivers.
 * Generates all the logic to handle driver creation / open.
 */
static	BOOL	MSACM_AddToList(PWINE_ACMLOCALDRIVERINST lpNewDrv, LPARAM lParam2)
{
    PWINE_ACMLOCALDRIVER pDriverBase = lpNewDrv->pLocalDriver;

    /* first of this driver in list ? */
    if (MSACM_GetNumberOfModuleRefs(pDriverBase->hModule, pDriverBase->lpDrvProc, NULL) == 0) {
        if (MSACM_DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
            FIXME("DRV_LOAD failed on driver %p\n", lpNewDrv);
            return FALSE;
        }
        /* returned value is not checked */
        MSACM_DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L);
    }

    lpNewDrv->pNextACMInst = NULL;
    if (pDriverBase->pACMInstList == NULL) {
	pDriverBase->pACMInstList = lpNewDrv;
    } else {
        PWINE_ACMLOCALDRIVERINST lpDrvInst = pDriverBase->pACMInstList;
    
        while (lpDrvInst->pNextACMInst != NULL)
            lpDrvInst = lpDrvInst->pNextACMInst;

	lpDrvInst->pNextACMInst = lpNewDrv;
    }

    /* Now just open a new instance of a driver on this module */
    lpNewDrv->dwDriverID = MSACM_DRIVER_SendMessage(lpNewDrv, DRV_OPEN, 0, lParam2);

    if (lpNewDrv->dwDriverID == 0) {
        FIXME("DRV_OPEN failed on driver %p\n", lpNewDrv);
        MSACM_RemoveFromList(lpNewDrv);
        return FALSE;
    }
    return TRUE;
}

PWINE_ACMLOCALDRIVERINST MSACM_OpenLocalDriver(PWINE_ACMLOCALDRIVER paldrv, LPARAM lParam2)
{
    PWINE_ACMLOCALDRIVERINST pDrvInst;
    
    pDrvInst = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMLOCALDRIVERINST));
    pDrvInst->pLocalDriver = paldrv;
    pDrvInst->dwDriverID = 0;
    pDrvInst->pNextACMInst = NULL;
    pDrvInst->bSession = FALSE;
    
    /* Win32 installable drivers must support a two phase opening scheme:
     * + first open with NULL as lParam2 (session instance),
     * + then do a second open with the real non null lParam2)
     */
    if (MSACM_GetNumberOfModuleRefs(paldrv->hModule, paldrv->lpDrvProc, NULL) == 0 && lParam2)
    {
        PWINE_ACMLOCALDRIVERINST   ret;

        if (!MSACM_AddToList(pDrvInst, 0L))
        {
            ERR("load0 failed\n");
            goto exit;
        }
        ret = MSACM_OpenLocalDriver(paldrv, lParam2);
        if (!ret)
        {
            MSACM_CloseLocalDriver(pDrvInst);
            ERR("load1 failed\n");
            goto exit;
        }
        pDrvInst->bSession = TRUE;
        return ret;
    }
    
    if (!MSACM_AddToList(pDrvInst, lParam2))
    {
        ERR("load failed\n");
        goto exit;
    }

    TRACE("=> %p\n", pDrvInst);
    return pDrvInst;
exit:
    HeapFree(MSACM_hHeap, 0, pDrvInst);
    return NULL;
}

LRESULT MSACM_CloseLocalDriver(PWINE_ACMLOCALDRIVERINST paldrv)
{
    if (MSACM_RemoveFromList(paldrv)) {
        PWINE_ACMLOCALDRIVERINST lpDrv0;
        PWINE_ACMLOCALDRIVER pDriverBase = paldrv->pLocalDriver;
    
        MSACM_DRIVER_SendMessage(paldrv, DRV_CLOSE, 0, 0);
        paldrv->dwDriverID = 0;
    
        if (paldrv->bSession)
            ERR("should not directly close session instance (%p)\n", paldrv);

        /* if driver has an opened session instance, we have to close it too */
        if (MSACM_GetNumberOfModuleRefs(pDriverBase->hModule, pDriverBase->lpDrvProc, &lpDrv0) == 1 &&
                lpDrv0->bSession)
        {
            MSACM_DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0L, 0L);
            lpDrv0->dwDriverID = 0;
            MSACM_RemoveFromList(lpDrv0);
            HeapFree(GetProcessHeap(), 0, lpDrv0);
        }

        HeapFree(MSACM_hHeap, 0, paldrv);
        return TRUE;
    }
    ERR("unable to close driver instance\n");
    return FALSE;
}

PWINE_ACMLOCALDRIVER MSACM_UnregisterLocalDriver(PWINE_ACMLOCALDRIVER paldrv)
{
    PWINE_ACMLOCALDRIVER pNextACMLocalDriver;

    if (paldrv->pACMInstList) {
        ERR("local driver instances still present after closing all drivers - memory leak\n");
        return NULL;
    }

    if (paldrv == MSACM_pFirstACMLocalDriver)
	MSACM_pFirstACMLocalDriver = paldrv->pNextACMLocalDrv;
    if (paldrv == MSACM_pLastACMLocalDriver)
	MSACM_pLastACMLocalDriver = paldrv->pPrevACMLocalDrv;

    if (paldrv->pPrevACMLocalDrv)
	paldrv->pPrevACMLocalDrv->pNextACMLocalDrv = paldrv->pNextACMLocalDrv;
    if (paldrv->pNextACMLocalDrv)
	paldrv->pNextACMLocalDrv->pPrevACMLocalDrv = paldrv->pPrevACMLocalDrv;

    pNextACMLocalDriver = paldrv->pNextACMLocalDrv;

    HeapFree(MSACM_hHeap, 0, paldrv);

    return pNextACMLocalDriver;
}
