1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
22 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(msacm);
26 /**********************************************************************/
28 HANDLE MSACM_hHeap = (HANDLE) NULL;
29 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
30 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
33 /***********************************************************************
36 static void MSACM_DumpCache(PWINE_ACMDRIVERID padid)
40 TRACE("cFilterTags=%lu cFormatTags=%lu fdwSupport=%08lx\n",
41 padid->cFilterTags, padid->cFormatTags, padid->fdwSupport);
42 for (i = 0; i < padid->cache->cFormatTags; i++) {
43 TRACE("\tdwFormatTag=%lu cbwfx=%lu\n",
44 padid->aFormatTag[i].dwFormatTag, padid->aFormatTag[i].cbwfx);
49 /***********************************************************************
50 * MSACM_FindFormatTagInCache [internal]
52 * Returns TRUE is the format tag fmtTag is present in the cache.
53 * If so, idx is set to its index.
55 BOOL MSACM_FindFormatTagInCache(WINE_ACMDRIVERID* padid, DWORD fmtTag, LPDWORD idx)
59 for (i = 0; i < padid->cFormatTags; i++) {
60 if (padid->aFormatTag[i].dwFormatTag == fmtTag) {
68 /***********************************************************************
71 static BOOL MSACM_FillCache(PWINE_ACMDRIVERID padid)
75 ACMDRIVERDETAILSW add;
76 ACMFORMATTAGDETAILSW aftd;
78 if (acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != 0)
81 padid->aFormatTag = NULL;
82 add.cbStruct = sizeof(add);
83 if (MSACM_Message(had, ACMDM_DRIVER_DETAILS, (LPARAM)&add, 0))
86 if (add.cFormatTags > 0) {
87 padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY,
88 add.cFormatTags * sizeof(padid->aFormatTag[0]));
89 if (!padid->aFormatTag) goto errCleanUp;
92 padid->cFormatTags = add.cFormatTags;
93 padid->cFilterTags = add.cFilterTags;
94 padid->fdwSupport = add.fdwSupport;
96 aftd.cbStruct = sizeof(aftd);
98 for (ntag = 0; ntag < add.cFormatTags; ntag++) {
99 aftd.dwFormatTagIndex = ntag;
100 if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)&aftd, ACM_FORMATTAGDETAILSF_INDEX)) {
101 TRACE("IIOs (%s)\n", padid->pszDriverAlias);
104 padid->aFormatTag[ntag].dwFormatTag = aftd.dwFormatTag;
105 padid->aFormatTag[ntag].cbwfx = aftd.cbFormatSize;
108 acmDriverClose(had, 0);
113 if (had) acmDriverClose(had, 0);
114 HeapFree(MSACM_hHeap, 0, padid->aFormatTag);
115 padid->aFormatTag = NULL;
119 /***********************************************************************
120 * MSACM_GetRegistryKey
122 static LPSTR MSACM_GetRegistryKey(const WINE_ACMDRIVERID* padid)
124 static const char* baseKey = "Software\\Microsoft\\AudioCompressionManager\\DriverCache\\";
128 if (!padid->pszDriverAlias) {
129 ERR("No alias needed for registry entry\n");
132 len = strlen(baseKey);
133 ret = HeapAlloc(MSACM_hHeap, 0, len + strlen(padid->pszDriverAlias) + 1);
134 if (!ret) return NULL;
136 strcpy(ret, baseKey);
137 strcpy(ret + len, padid->pszDriverAlias);
138 CharLowerA(ret + len);
142 /***********************************************************************
145 static BOOL MSACM_ReadCache(PWINE_ACMDRIVERID padid)
147 LPSTR key = MSACM_GetRegistryKey(padid);
151 if (!key) return FALSE;
153 padid->aFormatTag = NULL;
155 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, key, &hKey))
158 size = sizeof(padid->cFormatTags);
159 if (RegQueryValueExA(hKey, "cFormatTags", 0, &type, (void*)&padid->cFormatTags, &size))
161 size = sizeof(padid->cFilterTags);
162 if (RegQueryValueExA(hKey, "cFilterTags", 0, &type, (void*)&padid->cFilterTags, &size))
164 size = sizeof(padid->fdwSupport);
165 if (RegQueryValueExA(hKey, "fdwSupport", 0, &type, (void*)&padid->fdwSupport, &size))
168 if (padid->cFormatTags > 0) {
169 size = padid->cFormatTags * sizeof(padid->aFormatTag[0]);
170 padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY, size);
171 if (!padid->aFormatTag) goto errCleanUp;
172 if (RegQueryValueExA(hKey, "aFormatTagCache", 0, &type, (void*)padid->aFormatTag, &size))
175 HeapFree(MSACM_hHeap, 0, key);
179 HeapFree(MSACM_hHeap, 0, key);
180 HeapFree(MSACM_hHeap, 0, padid->aFormatTag);
181 padid->aFormatTag = NULL;
186 /***********************************************************************
189 static BOOL MSACM_WriteCache(PWINE_ACMDRIVERID padid)
191 LPSTR key = MSACM_GetRegistryKey(padid);
194 if (!key) return FALSE;
196 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, key, &hKey))
199 if (RegSetValueExA(hKey, "cFormatTags", 0, REG_DWORD, (void*)&padid->cFormatTags, sizeof(DWORD)))
201 if (RegSetValueExA(hKey, "cFilterTags", 0, REG_DWORD, (void*)&padid->cFilterTags, sizeof(DWORD)))
203 if (RegSetValueExA(hKey, "fdwSupport", 0, REG_DWORD, (void*)&padid->fdwSupport, sizeof(DWORD)))
205 if (RegSetValueExA(hKey, "aFormatTagCache", 0, REG_BINARY,
206 (void*)padid->aFormatTag,
207 padid->cFormatTags * sizeof(padid->aFormatTag[0])))
209 HeapFree(MSACM_hHeap, 0, key);
213 HeapFree(MSACM_hHeap, 0, key);
217 /***********************************************************************
218 * MSACM_RegisterDriver()
220 PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName,
221 HINSTANCE hinstModule)
223 PWINE_ACMDRIVERID padid;
225 TRACE("('%s', '%s', 0x%08x)\n", pszDriverAlias, pszFileName, hinstModule);
227 padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
228 padid->obj.dwType = WINE_ACMOBJ_DRIVERID;
229 padid->obj.pACMDriverID = padid;
230 padid->pszDriverAlias = NULL;
233 padid->pszDriverAlias = HeapAlloc( MSACM_hHeap, 0, strlen(pszDriverAlias)+1 );
234 strcpy( padid->pszDriverAlias, pszDriverAlias );
236 padid->pszFileName = NULL;
239 padid->pszFileName = HeapAlloc( MSACM_hHeap, 0, strlen(pszFileName)+1 );
240 strcpy( padid->pszFileName, pszFileName );
242 padid->hInstModule = hinstModule;
244 padid->pACMDriverList = NULL;
245 padid->pNextACMDriverID = NULL;
246 padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
247 if (MSACM_pLastACMDriverID)
248 MSACM_pLastACMDriverID->pNextACMDriverID = padid;
249 MSACM_pLastACMDriverID = padid;
250 if (!MSACM_pFirstACMDriverID)
251 MSACM_pFirstACMDriverID = padid;
252 /* disable the driver if we cannot load the cache */
253 if (!MSACM_ReadCache(padid) && !MSACM_FillCache(padid)) {
254 WARN("Couldn't load cache for ACM driver (%s)\n", pszFileName);
255 MSACM_UnregisterDriver(padid);
261 /***********************************************************************
262 * MSACM_RegisterAllDrivers()
264 void MSACM_RegisterAllDrivers(void)
267 DWORD dwBufferLength;
270 * What if the user edits system.ini while the program is running?
271 * Does Windows handle that?
273 if (MSACM_pFirstACMDriverID)
276 /* FIXME: Does not work! How do I determine the section length? */
277 dwBufferLength = 1024;
278 /* EPP GetPrivateProfileSectionA("drivers32", NULL, 0, "system.ini"); */
280 pszBuffer = (LPSTR) HeapAlloc(MSACM_hHeap, 0, dwBufferLength);
281 if (GetPrivateProfileSectionA("drivers32", pszBuffer, dwBufferLength, "system.ini")) {
284 if (!strncasecmp("MSACM.", s, 6)) {
286 while (*s2 != '\0' && *s2 != '=') s2++;
289 MSACM_RegisterDriver(s, s2 + 1, 0);
293 s += strlen(s) + 1; /* Either next char or \0 */
297 HeapFree(MSACM_hHeap, 0, pszBuffer);
299 MSACM_RegisterDriver("msacm32.dll", "msacm32.dll", 0);
302 /***********************************************************************
303 * MSACM_UnregisterDriver()
305 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
307 PWINE_ACMDRIVERID pNextACMDriverID;
309 while (p->pACMDriverList)
310 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
312 if (p->pszDriverAlias)
313 HeapFree(MSACM_hHeap, 0, p->pszDriverAlias);
315 HeapFree(MSACM_hHeap, 0, p->pszFileName);
316 HeapFree(MSACM_hHeap, 0, p->aFormatTag);
318 if (p == MSACM_pFirstACMDriverID)
319 MSACM_pFirstACMDriverID = p->pNextACMDriverID;
320 if (p == MSACM_pLastACMDriverID)
321 MSACM_pLastACMDriverID = p->pPrevACMDriverID;
323 if (p->pPrevACMDriverID)
324 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
325 if (p->pNextACMDriverID)
326 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
328 pNextACMDriverID = p->pNextACMDriverID;
330 HeapFree(MSACM_hHeap, 0, p);
332 return pNextACMDriverID;
335 /***********************************************************************
336 * MSACM_UnregisterAllDrivers()
338 void MSACM_UnregisterAllDrivers(void)
340 PWINE_ACMDRIVERID p = MSACM_pFirstACMDriverID;
344 p = MSACM_UnregisterDriver(p);
348 /***********************************************************************
351 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj, DWORD type)
353 PWINE_ACMOBJ pao = (PWINE_ACMOBJ)hObj;
355 if (pao == NULL || IsBadReadPtr(pao, sizeof(WINE_ACMOBJ)) ||
356 ((type != WINE_ACMOBJ_DONTCARE) && (type != pao->dwType)))
361 /***********************************************************************
362 * MSACM_GetDriverID()
364 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
366 return (PWINE_ACMDRIVERID)MSACM_GetObj((HACMOBJ)hDriverID, WINE_ACMOBJ_DRIVERID);
369 /***********************************************************************
372 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
374 return (PWINE_ACMDRIVER)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_DRIVER);
377 /***********************************************************************
380 MMRESULT MSACM_Message(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
382 PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
384 return pad ? SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2) : MMSYSERR_INVALHANDLE;