Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninternal.c
Go to the documentation of this file.
00001 /* -*- tab-width: 8; c-basic-offset: 4 -*- */ 00002 00003 /* 00004 * MSACM32 library 00005 * 00006 * Copyright 1998 Patrik Stridvall 00007 * 1999 Eric Pouech 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00022 */ 00023 00024 #include <stdarg.h> 00025 #include <string.h> 00026 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "wingdi.h" 00030 #include "winuser.h" 00031 #include "winerror.h" 00032 #include "winreg.h" 00033 #include "mmsystem.h" 00034 #include "mmreg.h" 00035 #include "msacm.h" 00036 #include "msacmdrv.h" 00037 #include "wineacm.h" 00038 #include "wine/debug.h" 00039 #include "wine/unicode.h" 00040 00041 WINE_DEFAULT_DEBUG_CHANNEL(msacm); 00042 00043 /**********************************************************************/ 00044 00045 HANDLE MSACM_hHeap = NULL; 00046 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL; 00047 static PWINE_ACMDRIVERID MSACM_pLastACMDriverID; 00048 00049 static DWORD MSACM_suspendBroadcastCount = 0; 00050 static BOOL MSACM_pendingBroadcast = FALSE; 00051 static PWINE_ACMNOTIFYWND MSACM_pFirstACMNotifyWnd = NULL; 00052 static PWINE_ACMNOTIFYWND MSACM_pLastACMNotifyWnd = NULL; 00053 00054 static void MSACM_ReorderDriversByPriority(void); 00055 00056 /*********************************************************************** 00057 * MSACM_RegisterDriverFromRegistry() 00058 */ 00059 PWINE_ACMDRIVERID MSACM_RegisterDriverFromRegistry(LPCWSTR pszRegEntry) 00060 { 00061 static const WCHAR msacmW[] = {'M','S','A','C','M','.'}; 00062 static const WCHAR drvkey[] = {'S','o','f','t','w','a','r','e','\\', 00063 'M','i','c','r','o','s','o','f','t','\\', 00064 'W','i','n','d','o','w','s',' ','N','T','\\', 00065 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 00066 'D','r','i','v','e','r','s','3','2','\0'}; 00067 WCHAR buf[2048]; 00068 DWORD bufLen, lRet; 00069 HKEY hKey; 00070 PWINE_ACMDRIVERID padid = NULL; 00071 00072 /* The requested registry entry must have the format msacm.XXXXX in order to 00073 be recognized in any future sessions of msacm 00074 */ 00075 if (0 == strncmpiW(pszRegEntry, msacmW, sizeof(msacmW)/sizeof(WCHAR))) { 00076 lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drvkey, 0, KEY_QUERY_VALUE, &hKey); 00077 if (lRet != ERROR_SUCCESS) { 00078 WARN("unable to open registry key - 0x%08x\n", lRet); 00079 } else { 00080 bufLen = sizeof(buf); 00081 lRet = RegQueryValueExW(hKey, pszRegEntry, NULL, NULL, (LPBYTE)buf, &bufLen); 00082 if (lRet != ERROR_SUCCESS) { 00083 WARN("unable to query requested subkey %s - 0x%08x\n", debugstr_w(pszRegEntry), lRet); 00084 } else { 00085 MSACM_RegisterDriver(pszRegEntry, buf, 0); 00086 } 00087 RegCloseKey( hKey ); 00088 } 00089 } 00090 return padid; 00091 } 00092 00093 #if 0 00094 /*********************************************************************** 00095 * MSACM_DumpCache 00096 */ 00097 static void MSACM_DumpCache(PWINE_ACMDRIVERID padid) 00098 { 00099 unsigned i; 00100 00101 TRACE("cFilterTags=%lu cFormatTags=%lu fdwSupport=%08lx\n", 00102 padid->cFilterTags, padid->cFormatTags, padid->fdwSupport); 00103 for (i = 0; i < padid->cache->cFormatTags; i++) { 00104 TRACE("\tdwFormatTag=%lu cbwfx=%lu\n", 00105 padid->aFormatTag[i].dwFormatTag, padid->aFormatTag[i].cbwfx); 00106 } 00107 } 00108 #endif 00109 00110 /*********************************************************************** 00111 * MSACM_FindFormatTagInCache [internal] 00112 * 00113 * Returns TRUE is the format tag fmtTag is present in the cache. 00114 * If so, idx is set to its index. 00115 */ 00116 BOOL MSACM_FindFormatTagInCache(const WINE_ACMDRIVERID* padid, DWORD fmtTag, LPDWORD idx) 00117 { 00118 unsigned i; 00119 00120 for (i = 0; i < padid->cFormatTags; i++) { 00121 if (padid->aFormatTag[i].dwFormatTag == fmtTag) { 00122 if (idx) *idx = i; 00123 return TRUE; 00124 } 00125 } 00126 return FALSE; 00127 } 00128 00129 /*********************************************************************** 00130 * MSACM_FillCache 00131 */ 00132 static BOOL MSACM_FillCache(PWINE_ACMDRIVERID padid) 00133 { 00134 HACMDRIVER had = 0; 00135 unsigned int ntag; 00136 ACMDRIVERDETAILSW add; 00137 ACMFORMATTAGDETAILSW aftd; 00138 00139 if (acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != 0) 00140 return FALSE; 00141 00142 padid->aFormatTag = NULL; 00143 add.cbStruct = sizeof(add); 00144 if (MSACM_Message(had, ACMDM_DRIVER_DETAILS, (LPARAM)&add, 0)) 00145 goto errCleanUp; 00146 00147 if (add.cFormatTags > 0) { 00148 padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY, 00149 add.cFormatTags * sizeof(padid->aFormatTag[0])); 00150 if (!padid->aFormatTag) goto errCleanUp; 00151 } 00152 00153 padid->cFormatTags = add.cFormatTags; 00154 padid->cFilterTags = add.cFilterTags; 00155 padid->fdwSupport = add.fdwSupport; 00156 00157 aftd.cbStruct = sizeof(aftd); 00158 00159 for (ntag = 0; ntag < add.cFormatTags; ntag++) { 00160 aftd.dwFormatTagIndex = ntag; 00161 if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)&aftd, ACM_FORMATTAGDETAILSF_INDEX)) { 00162 TRACE("IIOs (%s)\n", debugstr_w(padid->pszDriverAlias)); 00163 goto errCleanUp; 00164 } 00165 padid->aFormatTag[ntag].dwFormatTag = aftd.dwFormatTag; 00166 padid->aFormatTag[ntag].cbwfx = aftd.cbFormatSize; 00167 } 00168 00169 acmDriverClose(had, 0); 00170 00171 return TRUE; 00172 00173 errCleanUp: 00174 if (had) acmDriverClose(had, 0); 00175 HeapFree(MSACM_hHeap, 0, padid->aFormatTag); 00176 padid->aFormatTag = NULL; 00177 return FALSE; 00178 } 00179 00180 /*********************************************************************** 00181 * MSACM_GetRegistryKey 00182 */ 00183 static LPWSTR MSACM_GetRegistryKey(const WINE_ACMDRIVERID* padid) 00184 { 00185 static const WCHAR baseKey[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\', 00186 'A','u','d','i','o','C','o','m','p','r','e','s','s','i','o','n','M','a','n','a','g','e','r','\\', 00187 'D','r','i','v','e','r','C','a','c','h','e','\\','\0'}; 00188 LPWSTR ret; 00189 int len; 00190 00191 if (!padid->pszDriverAlias) { 00192 ERR("No alias needed for registry entry\n"); 00193 return NULL; 00194 } 00195 len = strlenW(baseKey); 00196 ret = HeapAlloc(MSACM_hHeap, 0, (len + strlenW(padid->pszDriverAlias) + 1) * sizeof(WCHAR)); 00197 if (!ret) return NULL; 00198 00199 strcpyW(ret, baseKey); 00200 strcpyW(ret + len, padid->pszDriverAlias); 00201 CharLowerW(ret + len); 00202 return ret; 00203 } 00204 00205 /*********************************************************************** 00206 * MSACM_ReadCache 00207 */ 00208 static BOOL MSACM_ReadCache(PWINE_ACMDRIVERID padid) 00209 { 00210 LPWSTR key = MSACM_GetRegistryKey(padid); 00211 HKEY hKey; 00212 DWORD type, size; 00213 00214 if (!key) return FALSE; 00215 00216 padid->aFormatTag = NULL; 00217 00218 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, key, &hKey)) 00219 goto errCleanUp; 00220 00221 size = sizeof(padid->cFormatTags); 00222 if (RegQueryValueExA(hKey, "cFormatTags", 0, &type, (void*)&padid->cFormatTags, &size)) 00223 goto errCleanUp; 00224 size = sizeof(padid->cFilterTags); 00225 if (RegQueryValueExA(hKey, "cFilterTags", 0, &type, (void*)&padid->cFilterTags, &size)) 00226 goto errCleanUp; 00227 size = sizeof(padid->fdwSupport); 00228 if (RegQueryValueExA(hKey, "fdwSupport", 0, &type, (void*)&padid->fdwSupport, &size)) 00229 goto errCleanUp; 00230 00231 if (padid->cFormatTags > 0) { 00232 size = padid->cFormatTags * sizeof(padid->aFormatTag[0]); 00233 padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY, size); 00234 if (!padid->aFormatTag) goto errCleanUp; 00235 if (RegQueryValueExA(hKey, "aFormatTagCache", 0, &type, (void*)padid->aFormatTag, &size)) 00236 goto errCleanUp; 00237 } 00238 HeapFree(MSACM_hHeap, 0, key); 00239 return TRUE; 00240 00241 errCleanUp: 00242 HeapFree(MSACM_hHeap, 0, key); 00243 HeapFree(MSACM_hHeap, 0, padid->aFormatTag); 00244 padid->aFormatTag = NULL; 00245 RegCloseKey(hKey); 00246 return FALSE; 00247 } 00248 00249 /*********************************************************************** 00250 * MSACM_WriteCache 00251 */ 00252 static BOOL MSACM_WriteCache(const WINE_ACMDRIVERID *padid) 00253 { 00254 LPWSTR key = MSACM_GetRegistryKey(padid); 00255 HKEY hKey; 00256 00257 if (!key) return FALSE; 00258 00259 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, key, &hKey)) 00260 goto errCleanUp; 00261 00262 if (RegSetValueExA(hKey, "cFormatTags", 0, REG_DWORD, (const void*)&padid->cFormatTags, sizeof(DWORD))) 00263 goto errCleanUp; 00264 if (RegSetValueExA(hKey, "cFilterTags", 0, REG_DWORD, (const void*)&padid->cFilterTags, sizeof(DWORD))) 00265 goto errCleanUp; 00266 if (RegSetValueExA(hKey, "fdwSupport", 0, REG_DWORD, (const void*)&padid->fdwSupport, sizeof(DWORD))) 00267 goto errCleanUp; 00268 if (RegSetValueExA(hKey, "aFormatTagCache", 0, REG_BINARY, 00269 (void*)padid->aFormatTag, 00270 padid->cFormatTags * sizeof(padid->aFormatTag[0]))) 00271 goto errCleanUp; 00272 HeapFree(MSACM_hHeap, 0, key); 00273 return TRUE; 00274 00275 errCleanUp: 00276 HeapFree(MSACM_hHeap, 0, key); 00277 return FALSE; 00278 } 00279 00280 /*********************************************************************** 00281 * MSACM_RegisterDriver() 00282 */ 00283 PWINE_ACMDRIVERID MSACM_RegisterDriver(LPCWSTR pszDriverAlias, LPCWSTR pszFileName, 00284 PWINE_ACMLOCALDRIVER pLocalDriver) 00285 { 00286 PWINE_ACMDRIVERID padid; 00287 00288 TRACE("(%s, %s, %p)\n", 00289 debugstr_w(pszDriverAlias), debugstr_w(pszFileName), pLocalDriver); 00290 00291 padid = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID)); 00292 if (!padid) 00293 return NULL; 00294 padid->obj.dwType = WINE_ACMOBJ_DRIVERID; 00295 padid->obj.pACMDriverID = padid; 00296 padid->pszDriverAlias = NULL; 00297 if (pszDriverAlias) 00298 { 00299 padid->pszDriverAlias = HeapAlloc( MSACM_hHeap, 0, (strlenW(pszDriverAlias)+1) * sizeof(WCHAR) ); 00300 if (!padid->pszDriverAlias) { 00301 HeapFree(MSACM_hHeap, 0, padid); 00302 return NULL; 00303 } 00304 strcpyW( padid->pszDriverAlias, pszDriverAlias ); 00305 } 00306 padid->pszFileName = NULL; 00307 if (pszFileName) 00308 { 00309 padid->pszFileName = HeapAlloc( MSACM_hHeap, 0, (strlenW(pszFileName)+1) * sizeof(WCHAR) ); 00310 if (!padid->pszFileName) { 00311 HeapFree(MSACM_hHeap, 0, padid->pszDriverAlias); 00312 HeapFree(MSACM_hHeap, 0, padid); 00313 return NULL; 00314 } 00315 strcpyW( padid->pszFileName, pszFileName ); 00316 } 00317 padid->pLocalDriver = pLocalDriver; 00318 00319 padid->pACMDriverList = NULL; 00320 00321 if (pLocalDriver) { 00322 padid->pPrevACMDriverID = NULL; 00323 padid->pNextACMDriverID = MSACM_pFirstACMDriverID; 00324 if (MSACM_pFirstACMDriverID) 00325 MSACM_pFirstACMDriverID->pPrevACMDriverID = padid; 00326 MSACM_pFirstACMDriverID = padid; 00327 if (!MSACM_pLastACMDriverID) 00328 MSACM_pLastACMDriverID = padid; 00329 } else { 00330 padid->pNextACMDriverID = NULL; 00331 padid->pPrevACMDriverID = MSACM_pLastACMDriverID; 00332 if (MSACM_pLastACMDriverID) 00333 MSACM_pLastACMDriverID->pNextACMDriverID = padid; 00334 MSACM_pLastACMDriverID = padid; 00335 if (!MSACM_pFirstACMDriverID) 00336 MSACM_pFirstACMDriverID = padid; 00337 } 00338 /* disable the driver if we cannot load the cache */ 00339 if ((!padid->pszDriverAlias || !MSACM_ReadCache(padid)) && !MSACM_FillCache(padid)) { 00340 WARN("Couldn't load cache for ACM driver (%s)\n", debugstr_w(pszFileName)); 00341 MSACM_UnregisterDriver(padid); 00342 return NULL; 00343 } 00344 00345 if (pLocalDriver) padid->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_LOCAL; 00346 return padid; 00347 } 00348 00349 /*********************************************************************** 00350 * MSACM_RegisterAllDrivers() 00351 */ 00352 void MSACM_RegisterAllDrivers(void) 00353 { 00354 static const WCHAR msacm32[] = {'m','s','a','c','m','3','2','.','d','l','l','\0'}; 00355 static const WCHAR msacmW[] = {'M','S','A','C','M','.'}; 00356 static const WCHAR drv32[] = {'d','r','i','v','e','r','s','3','2','\0'}; 00357 static const WCHAR sys[] = {'s','y','s','t','e','m','.','i','n','i','\0'}; 00358 static const WCHAR drvkey[] = {'S','o','f','t','w','a','r','e','\\', 00359 'M','i','c','r','o','s','o','f','t','\\', 00360 'W','i','n','d','o','w','s',' ','N','T','\\', 00361 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 00362 'D','r','i','v','e','r','s','3','2','\0'}; 00363 DWORD i, cnt = 0, bufLen, lRet; 00364 WCHAR buf[2048], *name, *s; 00365 FILETIME lastWrite; 00366 HKEY hKey; 00367 00368 /* FIXME: What if the user edits system.ini while the program is running? 00369 * Does Windows handle that? */ 00370 if (MSACM_pFirstACMDriverID) return; 00371 00372 lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drvkey, 0, KEY_QUERY_VALUE, &hKey); 00373 if (lRet == ERROR_SUCCESS) { 00374 RegQueryInfoKeyW( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0); 00375 for (i = 0; i < cnt; i++) { 00376 bufLen = sizeof(buf) / sizeof(buf[0]); 00377 lRet = RegEnumKeyExW(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite); 00378 if (lRet != ERROR_SUCCESS) continue; 00379 if (strncmpiW(buf, msacmW, sizeof(msacmW)/sizeof(msacmW[0]))) continue; 00380 if (!(name = strchrW(buf, '='))) continue; 00381 *name = 0; 00382 MSACM_RegisterDriver(buf, name + 1, 0); 00383 } 00384 RegCloseKey( hKey ); 00385 } 00386 00387 if (GetPrivateProfileSectionW(drv32, buf, sizeof(buf)/sizeof(buf[0]), sys)) 00388 { 00389 for(s = buf; *s; s += strlenW(s) + 1) 00390 { 00391 if (strncmpiW(s, msacmW, sizeof(msacmW)/sizeof(msacmW[0]))) continue; 00392 if (!(name = strchrW(s, '='))) continue; 00393 *name = 0; 00394 MSACM_RegisterDriver(s, name + 1, 0); 00395 *name = '='; 00396 } 00397 } 00398 MSACM_ReorderDriversByPriority(); 00399 MSACM_RegisterDriver(msacm32, msacm32, 0); 00400 } 00401 00402 /*********************************************************************** 00403 * MSACM_RegisterNotificationWindow() 00404 */ 00405 PWINE_ACMNOTIFYWND MSACM_RegisterNotificationWindow(HWND hNotifyWnd, DWORD dwNotifyMsg) 00406 { 00407 PWINE_ACMNOTIFYWND panwnd; 00408 00409 TRACE("(%p,0x%08x)\n", hNotifyWnd, dwNotifyMsg); 00410 00411 panwnd = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMNOTIFYWND)); 00412 panwnd->obj.dwType = WINE_ACMOBJ_NOTIFYWND; 00413 panwnd->obj.pACMDriverID = 0; 00414 panwnd->hNotifyWnd = hNotifyWnd; 00415 panwnd->dwNotifyMsg = dwNotifyMsg; 00416 panwnd->fdwSupport = 0; 00417 00418 panwnd->pNextACMNotifyWnd = NULL; 00419 panwnd->pPrevACMNotifyWnd = MSACM_pLastACMNotifyWnd; 00420 if (MSACM_pLastACMNotifyWnd) 00421 MSACM_pLastACMNotifyWnd->pNextACMNotifyWnd = panwnd; 00422 MSACM_pLastACMNotifyWnd = panwnd; 00423 if (!MSACM_pFirstACMNotifyWnd) 00424 MSACM_pFirstACMNotifyWnd = panwnd; 00425 00426 return panwnd; 00427 } 00428 00429 /*********************************************************************** 00430 * MSACM_BroadcastNotification() 00431 */ 00432 void MSACM_BroadcastNotification(void) 00433 { 00434 if (MSACM_suspendBroadcastCount <= 0) { 00435 PWINE_ACMNOTIFYWND panwnd; 00436 00437 for (panwnd = MSACM_pFirstACMNotifyWnd; panwnd; panwnd = panwnd->pNextACMNotifyWnd) 00438 if (!(panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) 00439 SendMessageW(panwnd->hNotifyWnd, panwnd->dwNotifyMsg, 0, 0); 00440 } else { 00441 MSACM_pendingBroadcast = TRUE; 00442 } 00443 } 00444 00445 /*********************************************************************** 00446 * MSACM_DisableNotifications() 00447 */ 00448 void MSACM_DisableNotifications(void) 00449 { 00450 MSACM_suspendBroadcastCount++; 00451 } 00452 00453 /*********************************************************************** 00454 * MSACM_EnableNotifications() 00455 */ 00456 void MSACM_EnableNotifications(void) 00457 { 00458 if (MSACM_suspendBroadcastCount > 0) { 00459 MSACM_suspendBroadcastCount--; 00460 if (MSACM_suspendBroadcastCount == 0 && MSACM_pendingBroadcast) { 00461 MSACM_pendingBroadcast = FALSE; 00462 MSACM_BroadcastNotification(); 00463 } 00464 } 00465 } 00466 00467 /*********************************************************************** 00468 * MSACM_UnRegisterNotificationWindow() 00469 */ 00470 PWINE_ACMNOTIFYWND MSACM_UnRegisterNotificationWindow(const WINE_ACMNOTIFYWND *panwnd) 00471 { 00472 PWINE_ACMNOTIFYWND p; 00473 00474 for (p = MSACM_pFirstACMNotifyWnd; p; p = p->pNextACMNotifyWnd) { 00475 if (p == panwnd) { 00476 PWINE_ACMNOTIFYWND pNext = p->pNextACMNotifyWnd; 00477 00478 if (p->pPrevACMNotifyWnd) p->pPrevACMNotifyWnd->pNextACMNotifyWnd = p->pNextACMNotifyWnd; 00479 if (p->pNextACMNotifyWnd) p->pNextACMNotifyWnd->pPrevACMNotifyWnd = p->pPrevACMNotifyWnd; 00480 if (MSACM_pFirstACMNotifyWnd == p) MSACM_pFirstACMNotifyWnd = p->pNextACMNotifyWnd; 00481 if (MSACM_pLastACMNotifyWnd == p) MSACM_pLastACMNotifyWnd = p->pPrevACMNotifyWnd; 00482 HeapFree(MSACM_hHeap, 0, p); 00483 00484 return pNext; 00485 } 00486 } 00487 return NULL; 00488 } 00489 00490 /*********************************************************************** 00491 * MSACM_RePositionDriver() 00492 */ 00493 void MSACM_RePositionDriver(PWINE_ACMDRIVERID padid, DWORD dwPriority) 00494 { 00495 PWINE_ACMDRIVERID pTargetPosition = NULL; 00496 00497 /* Remove selected driver from linked list */ 00498 if (MSACM_pFirstACMDriverID == padid) { 00499 MSACM_pFirstACMDriverID = padid->pNextACMDriverID; 00500 } 00501 if (MSACM_pLastACMDriverID == padid) { 00502 MSACM_pLastACMDriverID = padid->pPrevACMDriverID; 00503 } 00504 if (padid->pPrevACMDriverID != NULL) { 00505 padid->pPrevACMDriverID->pNextACMDriverID = padid->pNextACMDriverID; 00506 } 00507 if (padid->pNextACMDriverID != NULL) { 00508 padid->pNextACMDriverID->pPrevACMDriverID = padid->pPrevACMDriverID; 00509 } 00510 00511 /* Look up position where selected driver should be */ 00512 if (dwPriority == 1) { 00513 pTargetPosition = padid->pPrevACMDriverID; 00514 while (pTargetPosition->pPrevACMDriverID != NULL && 00515 !(pTargetPosition->pPrevACMDriverID->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL)) { 00516 pTargetPosition = pTargetPosition->pPrevACMDriverID; 00517 } 00518 } else if (dwPriority == -1) { 00519 pTargetPosition = padid->pNextACMDriverID; 00520 while (pTargetPosition->pNextACMDriverID != NULL) { 00521 pTargetPosition = pTargetPosition->pNextACMDriverID; 00522 } 00523 } 00524 00525 /* Place selected driver in selected position */ 00526 padid->pPrevACMDriverID = pTargetPosition->pPrevACMDriverID; 00527 padid->pNextACMDriverID = pTargetPosition; 00528 if (padid->pPrevACMDriverID != NULL) { 00529 padid->pPrevACMDriverID->pNextACMDriverID = padid; 00530 } else { 00531 MSACM_pFirstACMDriverID = padid; 00532 } 00533 if (padid->pNextACMDriverID != NULL) { 00534 padid->pNextACMDriverID->pPrevACMDriverID = padid; 00535 } else { 00536 MSACM_pLastACMDriverID = padid; 00537 } 00538 } 00539 00540 /*********************************************************************** 00541 * MSACM_ReorderDriversByPriority() 00542 * Reorders all drivers based on the priority list indicated by the registry key: 00543 * HKCU\\Software\\Microsoft\\Multimedia\\Audio Compression Manager\\Priority v4.00 00544 */ 00545 static void MSACM_ReorderDriversByPriority(void) 00546 { 00547 PWINE_ACMDRIVERID padid; 00548 unsigned int iNumDrivers; 00549 PWINE_ACMDRIVERID * driverList = NULL; 00550 HKEY hPriorityKey = NULL; 00551 00552 TRACE("\n"); 00553 00554 /* Count drivers && alloc corresponding memory for list */ 00555 iNumDrivers = 0; 00556 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) iNumDrivers++; 00557 if (iNumDrivers > 1) 00558 { 00559 LONG lError; 00560 static const WCHAR basePriorityKey[] = { 00561 'S','o','f','t','w','a','r','e','\\', 00562 'M','i','c','r','o','s','o','f','t','\\', 00563 'M','u','l','t','i','m','e','d','i','a','\\', 00564 'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\', 00565 'P','r','i','o','r','i','t','y',' ','v','4','.','0','0','\0' 00566 }; 00567 unsigned int i; 00568 LONG lBufferLength; 00569 WCHAR szBuffer[256]; 00570 00571 driverList = HeapAlloc(MSACM_hHeap, 0, iNumDrivers * sizeof(PWINE_ACMDRIVERID)); 00572 if (!driverList) 00573 { 00574 ERR("out of memory\n"); 00575 goto errCleanUp; 00576 } 00577 00578 lError = RegOpenKeyW(HKEY_CURRENT_USER, basePriorityKey, &hPriorityKey); 00579 if (lError != ERROR_SUCCESS) { 00580 TRACE("RegOpenKeyW failed, possibly key does not exist yet\n"); 00581 hPriorityKey = NULL; 00582 goto errCleanUp; 00583 } 00584 00585 /* Copy drivers into list to simplify linked list modification */ 00586 for (i = 0, padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID, i++) 00587 { 00588 driverList[i] = padid; 00589 } 00590 00591 /* Query each of the priorities in turn. Alias key is in lowercase. 00592 The general form of the priority record is the following: 00593 "PriorityN" --> "1, msacm.driveralias" 00594 where N is an integer, and the value is a string of the driver 00595 alias, prefixed by "1, " for an enabled driver, or "0, " for a 00596 disabled driver. 00597 */ 00598 for (i = 0; i < iNumDrivers; i++) 00599 { 00600 static const WCHAR priorityTmpl[] = {'P','r','i','o','r','i','t','y','%','l','d','\0'}; 00601 WCHAR szSubKey[17]; 00602 unsigned int iTargetPosition; 00603 unsigned int iCurrentPosition; 00604 WCHAR * pAlias; 00605 static const WCHAR sPrefix[] = {'m','s','a','c','m','.','\0'}; 00606 00607 /* Build expected entry name */ 00608 snprintfW(szSubKey, 17, priorityTmpl, i + 1); 00609 lBufferLength = sizeof(szBuffer); 00610 lError = RegQueryValueExW(hPriorityKey, szSubKey, NULL, NULL, (LPBYTE)szBuffer, (LPDWORD)&lBufferLength); 00611 if (lError != ERROR_SUCCESS) continue; 00612 00613 /* Recovered driver alias should be at this position */ 00614 iTargetPosition = i; 00615 00616 /* Locate driver alias in driver list */ 00617 pAlias = strstrW(szBuffer, sPrefix); 00618 if (pAlias == NULL) continue; 00619 00620 for (iCurrentPosition = 0; iCurrentPosition < iNumDrivers; iCurrentPosition++) { 00621 if (strcmpiW(driverList[iCurrentPosition]->pszDriverAlias, pAlias) == 0) 00622 break; 00623 } 00624 if (iCurrentPosition < iNumDrivers && iTargetPosition != iCurrentPosition) { 00625 padid = driverList[iTargetPosition]; 00626 driverList[iTargetPosition] = driverList[iCurrentPosition]; 00627 driverList[iCurrentPosition] = padid; 00628 00629 /* Locate enabled status */ 00630 if (szBuffer[0] == '1') { 00631 driverList[iTargetPosition]->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED; 00632 } else if (szBuffer[0] == '0') { 00633 driverList[iTargetPosition]->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; 00634 } 00635 } 00636 } 00637 00638 /* Re-assign pointers so that linked list traverses the ordered array */ 00639 for (i = 0; i < iNumDrivers; i++) { 00640 driverList[i]->pPrevACMDriverID = (i > 0) ? driverList[i - 1] : NULL; 00641 driverList[i]->pNextACMDriverID = (i < iNumDrivers - 1) ? driverList[i + 1] : NULL; 00642 } 00643 MSACM_pFirstACMDriverID = driverList[0]; 00644 MSACM_pLastACMDriverID = driverList[iNumDrivers - 1]; 00645 } 00646 00647 errCleanUp: 00648 if (hPriorityKey != NULL) RegCloseKey(hPriorityKey); 00649 HeapFree(MSACM_hHeap, 0, driverList); 00650 } 00651 00652 /*********************************************************************** 00653 * MSACM_WriteCurrentPriorities() 00654 * Writes out current order of driver priorities to registry key: 00655 * HKCU\\Software\\Microsoft\\Multimedia\\Audio Compression Manager\\Priority v4.00 00656 */ 00657 void MSACM_WriteCurrentPriorities(void) 00658 { 00659 LONG lError; 00660 HKEY hPriorityKey; 00661 static const WCHAR basePriorityKey[] = { 00662 'S','o','f','t','w','a','r','e','\\', 00663 'M','i','c','r','o','s','o','f','t','\\', 00664 'M','u','l','t','i','m','e','d','i','a','\\', 00665 'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\', 00666 'P','r','i','o','r','i','t','y',' ','v','4','.','0','0','\0' 00667 }; 00668 PWINE_ACMDRIVERID padid; 00669 DWORD dwPriorityCounter; 00670 static const WCHAR priorityTmpl[] = {'P','r','i','o','r','i','t','y','%','l','d','\0'}; 00671 static const WCHAR valueTmpl[] = {'%','c',',',' ','%','s','\0'}; 00672 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'}; 00673 WCHAR szSubKey[17]; 00674 WCHAR szBuffer[256]; 00675 00676 /* Delete ACM priority key and create it anew */ 00677 lError = RegDeleteKeyW(HKEY_CURRENT_USER, basePriorityKey); 00678 if (lError != ERROR_SUCCESS && lError != ERROR_FILE_NOT_FOUND) { 00679 ERR("unable to remove current key %s (0x%08x) - priority changes won't persist past application end.\n", 00680 debugstr_w(basePriorityKey), lError); 00681 return; 00682 } 00683 lError = RegCreateKeyW(HKEY_CURRENT_USER, basePriorityKey, &hPriorityKey); 00684 if (lError != ERROR_SUCCESS) { 00685 ERR("unable to create key %s (0x%08x) - priority changes won't persist past application end.\n", 00686 debugstr_w(basePriorityKey), lError); 00687 return; 00688 } 00689 00690 /* Write current list of priorities */ 00691 for (dwPriorityCounter = 0, padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 00692 if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL) continue; 00693 if (padid->pszDriverAlias == NULL) continue; /* internal PCM converter is last */ 00694 00695 /* Build required value name */ 00696 dwPriorityCounter++; 00697 snprintfW(szSubKey, 17, priorityTmpl, dwPriorityCounter); 00698 00699 /* Value has a 1 in front for enabled drivers and 0 for disabled drivers */ 00700 snprintfW(szBuffer, 256, valueTmpl, (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ? '0' : '1', padid->pszDriverAlias); 00701 strlwrW(szBuffer); 00702 00703 lError = RegSetValueExW(hPriorityKey, szSubKey, 0, REG_SZ, (BYTE *)szBuffer, (strlenW(szBuffer) + 1) * sizeof(WCHAR)); 00704 if (lError != ERROR_SUCCESS) { 00705 ERR("unable to write value for %s under key %s (0x%08x)\n", 00706 debugstr_w(padid->pszDriverAlias), debugstr_w(basePriorityKey), lError); 00707 } 00708 } 00709 00710 /* Build required value name */ 00711 dwPriorityCounter++; 00712 snprintfW(szSubKey, 17, priorityTmpl, dwPriorityCounter); 00713 00714 /* Value has a 1 in front for enabled drivers and 0 for disabled drivers */ 00715 snprintfW(szBuffer, 256, valueTmpl, '1', converterAlias); 00716 00717 lError = RegSetValueExW(hPriorityKey, szSubKey, 0, REG_SZ, (BYTE *)szBuffer, (strlenW(szBuffer) + 1) * sizeof(WCHAR)); 00718 if (lError != ERROR_SUCCESS) { 00719 ERR("unable to write value for %s under key %s (0x%08x)\n", 00720 debugstr_w(converterAlias), debugstr_w(basePriorityKey), lError); 00721 } 00722 RegCloseKey(hPriorityKey); 00723 } 00724 00725 static PWINE_ACMLOCALDRIVER MSACM_pFirstACMLocalDriver; 00726 static PWINE_ACMLOCALDRIVER MSACM_pLastACMLocalDriver; 00727 00728 static PWINE_ACMLOCALDRIVER MSACM_UnregisterLocalDriver(PWINE_ACMLOCALDRIVER paldrv) 00729 { 00730 PWINE_ACMLOCALDRIVER pNextACMLocalDriver; 00731 00732 if (paldrv->pACMInstList) { 00733 ERR("local driver instances still present after closing all drivers - memory leak\n"); 00734 return NULL; 00735 } 00736 00737 if (paldrv == MSACM_pFirstACMLocalDriver) 00738 MSACM_pFirstACMLocalDriver = paldrv->pNextACMLocalDrv; 00739 if (paldrv == MSACM_pLastACMLocalDriver) 00740 MSACM_pLastACMLocalDriver = paldrv->pPrevACMLocalDrv; 00741 00742 if (paldrv->pPrevACMLocalDrv) 00743 paldrv->pPrevACMLocalDrv->pNextACMLocalDrv = paldrv->pNextACMLocalDrv; 00744 if (paldrv->pNextACMLocalDrv) 00745 paldrv->pNextACMLocalDrv->pPrevACMLocalDrv = paldrv->pPrevACMLocalDrv; 00746 00747 pNextACMLocalDriver = paldrv->pNextACMLocalDrv; 00748 00749 HeapFree(MSACM_hHeap, 0, paldrv); 00750 00751 return pNextACMLocalDriver; 00752 } 00753 00754 /*********************************************************************** 00755 * MSACM_UnregisterDriver() 00756 */ 00757 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) 00758 { 00759 PWINE_ACMDRIVERID pNextACMDriverID; 00760 00761 while (p->pACMDriverList) 00762 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0); 00763 00764 HeapFree(MSACM_hHeap, 0, p->pszDriverAlias); 00765 HeapFree(MSACM_hHeap, 0, p->pszFileName); 00766 HeapFree(MSACM_hHeap, 0, p->aFormatTag); 00767 00768 if (p == MSACM_pFirstACMDriverID) 00769 MSACM_pFirstACMDriverID = p->pNextACMDriverID; 00770 if (p == MSACM_pLastACMDriverID) 00771 MSACM_pLastACMDriverID = p->pPrevACMDriverID; 00772 00773 if (p->pPrevACMDriverID) 00774 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID; 00775 if (p->pNextACMDriverID) 00776 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID; 00777 00778 pNextACMDriverID = p->pNextACMDriverID; 00779 00780 if (p->pLocalDriver) MSACM_UnregisterLocalDriver(p->pLocalDriver); 00781 HeapFree(MSACM_hHeap, 0, p); 00782 00783 return pNextACMDriverID; 00784 } 00785 00786 /*********************************************************************** 00787 * MSACM_UnregisterAllDrivers() 00788 */ 00789 void MSACM_UnregisterAllDrivers(void) 00790 { 00791 PWINE_ACMNOTIFYWND panwnd = MSACM_pFirstACMNotifyWnd; 00792 PWINE_ACMDRIVERID p = MSACM_pFirstACMDriverID; 00793 00794 while (p) { 00795 MSACM_WriteCache(p); 00796 p = MSACM_UnregisterDriver(p); 00797 } 00798 00799 while (panwnd) { 00800 panwnd = MSACM_UnRegisterNotificationWindow(panwnd); 00801 } 00802 } 00803 00804 /*********************************************************************** 00805 * MSACM_GetObj() 00806 */ 00807 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj, DWORD type) 00808 { 00809 PWINE_ACMOBJ pao = (PWINE_ACMOBJ)hObj; 00810 00811 if (pao == NULL || IsBadReadPtr(pao, sizeof(WINE_ACMOBJ)) || 00812 ((type != WINE_ACMOBJ_DONTCARE) && (type != pao->dwType))) 00813 return NULL; 00814 return pao; 00815 } 00816 00817 /*********************************************************************** 00818 * MSACM_GetDriverID() 00819 */ 00820 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID) 00821 { 00822 return (PWINE_ACMDRIVERID)MSACM_GetObj((HACMOBJ)hDriverID, WINE_ACMOBJ_DRIVERID); 00823 } 00824 00825 /*********************************************************************** 00826 * MSACM_GetDriver() 00827 */ 00828 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver) 00829 { 00830 return (PWINE_ACMDRIVER)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_DRIVER); 00831 } 00832 00833 /*********************************************************************** 00834 * MSACM_GetNotifyWnd() 00835 */ 00836 PWINE_ACMNOTIFYWND MSACM_GetNotifyWnd(HACMDRIVERID hDriver) 00837 { 00838 return (PWINE_ACMNOTIFYWND)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_NOTIFYWND); 00839 } 00840 00841 /*********************************************************************** 00842 * MSACM_GetLocalDriver() 00843 */ 00844 /* 00845 PWINE_ACMLOCALDRIVER MSACM_GetLocalDriver(HACMDRIVER hDriver) 00846 { 00847 return (PWINE_ACMLOCALDRIVER)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_LOCALDRIVER); 00848 } 00849 */ 00850 #define MSACM_DRIVER_SendMessage(PDRVRINST, msg, lParam1, lParam2) \ 00851 (PDRVRINST)->pLocalDriver->lpDrvProc((PDRVRINST)->dwDriverID, (HDRVR)(PDRVRINST), msg, lParam1, lParam2) 00852 00853 /*********************************************************************** 00854 * MSACM_Message() 00855 */ 00856 MMRESULT MSACM_Message(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2) 00857 { 00858 PWINE_ACMDRIVER pad = MSACM_GetDriver(had); 00859 00860 if (!pad) return MMSYSERR_INVALHANDLE; 00861 if (pad->hDrvr) return SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2); 00862 if (pad->pLocalDrvrInst) return MSACM_DRIVER_SendMessage(pad->pLocalDrvrInst, uMsg, lParam1, lParam2); 00863 00864 return MMSYSERR_INVALHANDLE; 00865 } 00866 00867 PWINE_ACMLOCALDRIVER MSACM_RegisterLocalDriver(HMODULE hModule, DRIVERPROC lpDriverProc) 00868 { 00869 PWINE_ACMLOCALDRIVER paldrv; 00870 00871 TRACE("(%p, %p)\n", hModule, lpDriverProc); 00872 if (!hModule || !lpDriverProc) return NULL; 00873 00874 /* look up previous instance of local driver module */ 00875 for (paldrv = MSACM_pFirstACMLocalDriver; paldrv; paldrv = paldrv->pNextACMLocalDrv) 00876 { 00877 if (paldrv->hModule == hModule && paldrv->lpDrvProc == lpDriverProc) return paldrv; 00878 } 00879 00880 paldrv = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMLOCALDRIVER)); 00881 paldrv->obj.dwType = WINE_ACMOBJ_LOCALDRIVER; 00882 paldrv->obj.pACMDriverID = 0; 00883 paldrv->hModule = hModule; 00884 paldrv->lpDrvProc = lpDriverProc; 00885 paldrv->pACMInstList = NULL; 00886 00887 paldrv->pNextACMLocalDrv = NULL; 00888 paldrv->pPrevACMLocalDrv = MSACM_pLastACMLocalDriver; 00889 if (MSACM_pLastACMLocalDriver) 00890 MSACM_pLastACMLocalDriver->pNextACMLocalDrv = paldrv; 00891 MSACM_pLastACMLocalDriver = paldrv; 00892 if (!MSACM_pFirstACMLocalDriver) 00893 MSACM_pFirstACMLocalDriver = paldrv; 00894 00895 return paldrv; 00896 } 00897 00898 /************************************************************************** 00899 * MSACM_GetNumberOfModuleRefs [internal] 00900 * 00901 * Returns the number of open drivers which share the same module. 00902 * Inspired from implementation in dlls/winmm/driver.c 00903 */ 00904 static unsigned MSACM_GetNumberOfModuleRefs(HMODULE hModule, DRIVERPROC lpDrvProc, WINE_ACMLOCALDRIVERINST ** found) 00905 { 00906 PWINE_ACMLOCALDRIVER lpDrv; 00907 unsigned count = 0; 00908 00909 if (found) *found = NULL; 00910 for (lpDrv = MSACM_pFirstACMLocalDriver; lpDrv; lpDrv = lpDrv->pNextACMLocalDrv) 00911 { 00912 if (lpDrv->hModule == hModule && lpDrv->lpDrvProc == lpDrvProc) 00913 { 00914 PWINE_ACMLOCALDRIVERINST pInst = lpDrv->pACMInstList; 00915 00916 while (pInst) { 00917 if (found && !*found) *found = pInst; 00918 count++; 00919 pInst = pInst->pNextACMInst; 00920 } 00921 } 00922 } 00923 return count; 00924 } 00925 00926 /************************************************************************** 00927 * MSACM_RemoveFromList [internal] 00928 * 00929 * Generates all the logic to handle driver closure / deletion 00930 * Removes a driver struct to the list of open drivers. 00931 */ 00932 static BOOL MSACM_RemoveFromList(PWINE_ACMLOCALDRIVERINST lpDrv) 00933 { 00934 PWINE_ACMLOCALDRIVER pDriverBase = lpDrv->pLocalDriver; 00935 PWINE_ACMLOCALDRIVERINST pPrevInst; 00936 00937 /* last of this driver in list ? */ 00938 if (MSACM_GetNumberOfModuleRefs(pDriverBase->hModule, pDriverBase->lpDrvProc, NULL) == 1) { 00939 MSACM_DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L); 00940 MSACM_DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L); 00941 } 00942 00943 pPrevInst = NULL; 00944 if (pDriverBase->pACMInstList != lpDrv) { 00945 pPrevInst = pDriverBase->pACMInstList; 00946 while (pPrevInst && pPrevInst->pNextACMInst != lpDrv) 00947 pPrevInst = pPrevInst->pNextACMInst; 00948 if (!pPrevInst) { 00949 ERR("requested to remove invalid instance %p\n", pPrevInst); 00950 return FALSE; 00951 } 00952 } 00953 if (!pPrevInst) { 00954 /* first driver instance on list */ 00955 pDriverBase->pACMInstList = lpDrv->pNextACMInst; 00956 } else { 00957 pPrevInst->pNextACMInst = lpDrv->pNextACMInst; 00958 } 00959 return TRUE; 00960 } 00961 00962 /************************************************************************** 00963 * MSACM_AddToList [internal] 00964 * 00965 * Adds a driver struct to the list of open drivers. 00966 * Generates all the logic to handle driver creation / open. 00967 */ 00968 static BOOL MSACM_AddToList(PWINE_ACMLOCALDRIVERINST lpNewDrv, LPARAM lParam2) 00969 { 00970 PWINE_ACMLOCALDRIVER pDriverBase = lpNewDrv->pLocalDriver; 00971 00972 /* first of this driver in list ? */ 00973 if (MSACM_GetNumberOfModuleRefs(pDriverBase->hModule, pDriverBase->lpDrvProc, NULL) == 0) { 00974 if (MSACM_DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) { 00975 FIXME("DRV_LOAD failed on driver %p\n", lpNewDrv); 00976 return FALSE; 00977 } 00978 /* returned value is not checked */ 00979 MSACM_DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L); 00980 } 00981 00982 lpNewDrv->pNextACMInst = NULL; 00983 if (pDriverBase->pACMInstList == NULL) { 00984 pDriverBase->pACMInstList = lpNewDrv; 00985 } else { 00986 PWINE_ACMLOCALDRIVERINST lpDrvInst = pDriverBase->pACMInstList; 00987 00988 while (lpDrvInst->pNextACMInst != NULL) 00989 lpDrvInst = lpDrvInst->pNextACMInst; 00990 00991 lpDrvInst->pNextACMInst = lpNewDrv; 00992 } 00993 00994 /* Now just open a new instance of a driver on this module */ 00995 lpNewDrv->dwDriverID = MSACM_DRIVER_SendMessage(lpNewDrv, DRV_OPEN, 0, lParam2); 00996 00997 if (lpNewDrv->dwDriverID == 0) { 00998 FIXME("DRV_OPEN failed on driver %p\n", lpNewDrv); 00999 MSACM_RemoveFromList(lpNewDrv); 01000 return FALSE; 01001 } 01002 return TRUE; 01003 } 01004 01005 PWINE_ACMLOCALDRIVERINST MSACM_OpenLocalDriver(PWINE_ACMLOCALDRIVER paldrv, LPARAM lParam2) 01006 { 01007 PWINE_ACMLOCALDRIVERINST pDrvInst; 01008 01009 pDrvInst = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMLOCALDRIVERINST)); 01010 if (!pDrvInst) 01011 return NULL; 01012 01013 pDrvInst->pLocalDriver = paldrv; 01014 pDrvInst->dwDriverID = 0; 01015 pDrvInst->pNextACMInst = NULL; 01016 pDrvInst->bSession = FALSE; 01017 01018 /* Win32 installable drivers must support a two phase opening scheme: 01019 * + first open with NULL as lParam2 (session instance), 01020 * + then do a second open with the real non null lParam2) 01021 */ 01022 if (MSACM_GetNumberOfModuleRefs(paldrv->hModule, paldrv->lpDrvProc, NULL) == 0 && lParam2) 01023 { 01024 PWINE_ACMLOCALDRIVERINST ret; 01025 01026 if (!MSACM_AddToList(pDrvInst, 0L)) 01027 { 01028 ERR("load0 failed\n"); 01029 goto exit; 01030 } 01031 ret = MSACM_OpenLocalDriver(paldrv, lParam2); 01032 if (!ret) 01033 { 01034 ERR("load1 failed\n"); 01035 /* If MSACM_CloseLocalDriver returns TRUE, 01036 * then pDrvInst has been freed 01037 */ 01038 if (!MSACM_CloseLocalDriver(pDrvInst)) 01039 goto exit; 01040 01041 return NULL; 01042 } 01043 pDrvInst->bSession = TRUE; 01044 return ret; 01045 } 01046 01047 if (!MSACM_AddToList(pDrvInst, lParam2)) 01048 { 01049 ERR("load failed\n"); 01050 goto exit; 01051 } 01052 01053 TRACE("=> %p\n", pDrvInst); 01054 return pDrvInst; 01055 exit: 01056 HeapFree(MSACM_hHeap, 0, pDrvInst); 01057 return NULL; 01058 } 01059 01060 LRESULT MSACM_CloseLocalDriver(PWINE_ACMLOCALDRIVERINST paldrv) 01061 { 01062 if (MSACM_RemoveFromList(paldrv)) { 01063 PWINE_ACMLOCALDRIVERINST lpDrv0; 01064 PWINE_ACMLOCALDRIVER pDriverBase = paldrv->pLocalDriver; 01065 01066 MSACM_DRIVER_SendMessage(paldrv, DRV_CLOSE, 0, 0); 01067 paldrv->dwDriverID = 0; 01068 01069 if (paldrv->bSession) 01070 ERR("should not directly close session instance (%p)\n", paldrv); 01071 01072 /* if driver has an opened session instance, we have to close it too */ 01073 if (MSACM_GetNumberOfModuleRefs(pDriverBase->hModule, pDriverBase->lpDrvProc, &lpDrv0) == 1 && 01074 lpDrv0->bSession) 01075 { 01076 MSACM_DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0L, 0L); 01077 lpDrv0->dwDriverID = 0; 01078 MSACM_RemoveFromList(lpDrv0); 01079 HeapFree(GetProcessHeap(), 0, lpDrv0); 01080 } 01081 01082 HeapFree(MSACM_hHeap, 0, paldrv); 01083 return TRUE; 01084 } 01085 ERR("unable to close driver instance\n"); 01086 return FALSE; 01087 } Generated on Sat May 26 2012 04:17:03 for ReactOS by
1.7.6.1
|