this patch correctly unloads all still opened drivers when winmm exits this allows drivers which need those specific messages to take proper action Chris Morgan needs this for the jack driver A+
Name: winmm_unload ChangeLog: now properly unloading multimedia drivers when winmm unloads License: X11 GenDate: 2002/11/10 11:45:51 UTC ModifiedFiles: dlls/winmm/driver.c dlls/winmm/lolvldrv.c dlls/winmm/winemm.h dlls/winmm/winmm.c AddedFiles: =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/driver.c,v retrieving revision 1.22 diff -u -u -r1.22 driver.c --- dlls/winmm/driver.c 31 Oct 2002 01:02:41 -0000 1.22 +++ dlls/winmm/driver.c 5 Nov 2002 20:11:38 -0000 @@ -507,3 +507,23 @@ TRACE("Done\n"); return TRUE; } + +/****************************************************************** + * DRIVER_UnloadAll + * + * + */ +void DRIVER_UnloadAll(void) +{ + LPWINE_DRIVER lpDrv; + LPWINE_DRIVER lpNextDrv = NULL; + unsigned count = 0; + + for (lpDrv = lpDrvItemList; lpDrv != NULL; lpDrv = lpNextDrv) + { + lpNextDrv = lpDrv->lpNextItem; + CloseDriver((HDRVR)lpDrv, 0, 0); + count++; + } + TRACE("Unloaded %u drivers\n", count); +} Index: dlls/winmm/lolvldrv.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/lolvldrv.c,v retrieving revision 1.38 diff -u -u -r1.38 lolvldrv.c --- dlls/winmm/lolvldrv.c 31 Oct 2002 01:02:41 -0000 1.38 +++ dlls/winmm/lolvldrv.c 5 Nov 2002 21:14:39 -0000 @@ -733,3 +733,70 @@ /* FIXME: MMDRV_InitFromRegistry shall be MMDRV_Init in a near future */ return MMDRV_InitFromRegistry() || MMDRV_InitHardcoded(); } + +/****************************************************************** + * ExitPerType + * + * + */ +static BOOL MMDRV_ExitPerType(LPWINE_MM_DRIVER lpDrv, UINT type) +{ + WINE_MM_DRIVER_PART* part = &lpDrv->parts[type]; + DWORD ret; + + if (lpDrv->bIs32 && part->u.fnMessage32) { +#if 0 + ret = part->u.fnMessage32(0, DRVM_DISABLE, 0L, 0L, 0L); + TRACE("DRVM_DISABLE => %08lx\n", ret); +#endif + ret = part->u.fnMessage32(0, DRVM_EXIT, 0L, 0L, 0L); + TRACE("DRVM_EXIT => %08lx\n", ret); + } else if (!lpDrv->bIs32 && part->u.fnMessage16 && pFnCallMMDrvFunc16) { +#if 0 + ret = pFnCallMMDrvFunc16((FARPROC16)part->u.fnMessage16, + 0, DRVM_DISABLE, 0L, 0L, 0L); + TRACE("DRVM_DISABLE => %08lx\n", ret); +#endif + ret = pFnCallMMDrvFunc16((FARPROC16)part->u.fnMessage16, + 0, DRVM_EXIT, 0L, 0L, 0L); + TRACE("DRVM_EXIT => %08lx\n", ret); + } else { + return FALSE; + } + + return TRUE; +} + +/****************************************************************** + * Exit + * + * + */ +void MMDRV_Exit(void) +{ + int i; + + for (i = 0; i < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]); i++) + { + if (MM_MLDrvs[i] != NULL) + { + FIXME("Closing while ll-driver open\n"); +#if 0 + /* FIXME: should generate a message depending on type */ + MMDRV_Free((HANDLE)(i | 0x8000), MM_MLDrvs[i]); +#endif + } + } + + /* unload driver, in reverse order of loading */ + for (i = sizeof(MMDrvs) / sizeof(MMDrvs[0]) - 1; i >= 0; i--) + { + MMDRV_ExitPerType(&MMDrvs[i], MMDRV_AUX); + MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIXER); + MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIDIIN); + MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIDIOUT); + MMDRV_ExitPerType(&MMDrvs[i], MMDRV_WAVEIN); + MMDRV_ExitPerType(&MMDrvs[i], MMDRV_WAVEOUT); + CloseDriver(MMDrvs[i].hDriver, 0, 0); + } +} Index: dlls/winmm/winemm.h =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/winemm.h,v retrieving revision 1.41 diff -u -u -r1.41 winemm.h --- dlls/winmm/winemm.h 31 Oct 2002 02:23:43 -0000 1.41 +++ dlls/winmm/winemm.h 5 Nov 2002 21:14:57 -0000 @@ -90,8 +90,6 @@ WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */ } WINE_MM_DRIVER, *LPWINE_MM_DRIVER; -typedef WINMM_MapType (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2); - typedef struct tagWINE_MLD { /* EPP struct tagWINE_MLD* lpNext; */ /* not used so far */ UINT uDeviceID; @@ -226,12 +224,15 @@ typedef LONG (*MCIPROC16)(DWORD, HDRVR16, WORD, DWORD, DWORD); typedef LONG (*MCIPROC)(DWORD, HDRVR, DWORD, DWORD, DWORD); +typedef WINMM_MapType (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2); LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr); BOOL DRIVER_GetLibName(LPCSTR keyName, LPCSTR sectName, LPSTR buf, int sz); LPWINE_DRIVER DRIVER_TryOpenDriver32(LPCSTR fn, LPARAM lParam2); +void DRIVER_UnloadAll(void); BOOL MMDRV_Init(void); +void MMDRV_Exit(void); UINT MMDRV_GetNum(UINT); LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags, DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32); Index: dlls/winmm/winmm.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/winmm.c,v retrieving revision 1.8 diff -u -u -r1.8 winmm.c --- dlls/winmm/winmm.c 4 Nov 2002 23:53:43 -0000 1.8 +++ dlls/winmm/winmm.c 6 Nov 2002 18:41:56 -0000 @@ -127,6 +127,12 @@ } break; case DLL_PROCESS_DETACH: + /* close all opened MCI drivers */ + MCI_SendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, 0L, TRUE); + MMDRV_Exit(); + /* now unload all remaining drivers... */ + DRIVER_UnloadAll(); + WINMM_DeleteIData(); break; case DLL_THREAD_ATTACH: