ChangeLog: - revisited mmsystem/winmm loading mechanism - added WINMM_CheckMMSystem function (helps 32 bit code detect presence of our own mmsystem DLL) - some internal renaming (MULTIMEDIA => WINMM) the WINMM_CheckMMSystem kludge is needed because: - we only set up our own 16 bit hooks when mmsystem is loaded - as we allow loading of 16 bit drivers (even if only 32 APIs are used), we need to force somehow the loading of mmsystem - we don't do it by default, only when it's needed (thru WINMM_CheckMMSystem) - implementation should gracefully fails if we're not using wine's kernel32 (for example on Mingw) A+
--- winmm_8/mmsystem.c Tue Oct 29 15:04:10 2002 +++ winmm_9/mmsystem.c Tue Oct 29 14:19:36 2002 @@ -66,32 +66,27 @@ BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds, WORD wHeapSize, DWORD dwReserved1, WORD wReserved2) { - HANDLE hndl; - TRACE("0x%x 0x%lx\n", hinstDLL, fdwReason); switch (fdwReason) { case DLL_PROCESS_ATTACH: /* need to load WinMM in order to: - * - initiate correctly shared variables (MULTIMEDIA_Init()) - * - create correctly the per process WINE_MM_IDATA chunk + * - initiate correctly shared variables (WINMM_Init()) */ - hndl = LoadLibraryA("WINMM.DLL"); - - if (!hndl) { - ERR("Could not load sibling WinMM.dll\n"); - return FALSE; + if (!GetModuleHandleA("WINMM.DLL") && !LoadLibraryA("WINMM.DLL")) + { + ERR("Could not load sibling WinMM.dll\n"); + return FALSE; } WINMM_IData->hWinMM16Instance = hinstDLL; - WINMM_IData->h16Module32 = hndl; /* hook in our 16 bit function pointers */ - pFnMmioCallback16 = MMIO_Callback16; pFnGetMMThread16 = WINMM_GetmmThread; + pFnMmioCallback16 = MMIO_Callback16; break; case DLL_PROCESS_DETACH: - FreeLibrary(WINMM_IData->h16Module32); - pFnMmioCallback16 = NULL; + WINMM_IData->hWinMM16Instance = 0; pFnGetMMThread16 = NULL; + pFnMmioCallback16 = NULL; break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: --- winmm_8/winemm.h Tue Oct 29 16:09:24 2002 +++ winmm_9/winemm.h Tue Oct 29 16:10:12 2002 @@ -254,6 +254,8 @@ DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2); DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2); +BOOL WINMM_CheckForMMSystem(void); + void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16); void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32); --- winmm_8/winmm.c Sat Oct 26 15:06:40 2002 +++ winmm_9/winmm.c Tue Oct 29 14:00:19 2002 @@ -75,9 +75,9 @@ LPWINE_MM_IDATA WINMM_IData /* = NULL */; /************************************************************************** - * MULTIMEDIA_CreateIData [internal] + * WINMM_CreateIData [internal] */ -static BOOL MULTIMEDIA_CreateIData(HINSTANCE hInstDLL) +static BOOL WINMM_CreateIData(HINSTANCE hInstDLL) { WINMM_IData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MM_IDATA)); @@ -93,9 +93,9 @@ } /************************************************************************** - * MULTIMEDIA_DeleteIData [internal] + * WINMM_DeleteIData [internal] */ -static void MULTIMEDIA_DeleteIData(void) +static void WINMM_DeleteIData(void) { if (WINMM_IData) { TIME_MMTimeStop(); @@ -110,6 +110,30 @@ } } +/****************************************************************** + * WINMM_LoadMMSystem + * + */ +BOOL WINMM_CheckForMMSystem(void) +{ + /* 0 is not checked yet, -1 is not present, 1 is present */ + static int loaded /* = 0 */; + + if (loaded == 0) + { + HANDLE h = GetModuleHandleA("kernel32"); + loaded = -1; + if (h) + { + HANDLE (WINAPI *gmh)(LPCSTR) = (void*)GetProcAddress(h, "GetModuleHandle16"); + DWORD (WINAPI *ll)(LPCSTR) = (void*)GetProcAddress(h, "LoadLibrary16"); + if (gmh && ll && (gmh("MMSYSTEM.DLL") || ll("MMSYSTEM.DLL"))) + loaded = 1; + } + } + return loaded > 0; +} + /************************************************************************** * DllEntryPoint (WINMM.init) * @@ -122,15 +146,15 @@ switch (fdwReason) { case DLL_PROCESS_ATTACH: - if (!MULTIMEDIA_CreateIData(hInstDLL)) + if (!WINMM_CreateIData(hInstDLL)) return FALSE; if (!MULTIMEDIA_MciInit() || !MMDRV_Init()) { - MULTIMEDIA_DeleteIData(); + WINMM_DeleteIData(); return FALSE; } break; case DLL_PROCESS_DETACH: - MULTIMEDIA_DeleteIData(); + WINMM_DeleteIData(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: