From 47332210dd029379f6fe8a1344225e98e8941257 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Thu, 10 May 2012 14:17:34 -0500 Subject: [PATCH] winmm: Don't call MMDevAPI during process exit. --- dlls/winmm/waveform.c | 80 +++++++++++++++++++++++++++++++++---------- dlls/winmm/winmm.c | 33 +++++------------- 2 files changed, 71 insertions(+), 42 deletions(-) diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c index a985ee8b3f..602eb0637f 100644 --- a/dlls/winmm/waveform.c +++ b/dlls/winmm/waveform.c @@ -139,6 +139,8 @@ static UINT g_inmmdevices_count; static IMMDeviceEnumerator *g_devenum; +#define WINMM_WM_QUIT WM_USER + static CRITICAL_SECTION g_devthread_lock; static CRITICAL_SECTION_DEBUG g_devthread_lock_debug = { @@ -185,25 +187,64 @@ void WINMM_DeleteWaveform(void) { UINT i, j; - for(i = 0; i < g_outmmdevices_count; ++i){ - WINMM_MMDevice *mmdevice = &g_out_mmdevices[i]; - for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){ - WINMM_Device *device = mmdevice->devices[j]; - if(device->open) + if(g_devices_hwnd){ + for(i = 0; i < g_outmmdevices_count; ++i){ + WINMM_MMDevice *mmdevice = &g_out_mmdevices[i]; + for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){ + WINMM_Device *device = mmdevice->devices[j]; SendMessageW(g_devices_hwnd, WODM_CLOSE, (WPARAM)device->handle, 0); + } } - } - for(i = 0; i < g_inmmdevices_count; ++i){ - WINMM_MMDevice *mmdevice = &g_in_mmdevices[i]; - for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){ - WINMM_Device *device = mmdevice->devices[j]; - if(device->open) + for(i = 0; i < g_inmmdevices_count; ++i){ + WINMM_MMDevice *mmdevice = &g_in_mmdevices[i]; + for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){ + WINMM_Device *device = mmdevice->devices[j]; SendMessageW(g_devices_hwnd, WIDM_CLOSE, (WPARAM)device->handle, 0); + } + } + + SendMessageW(g_devices_hwnd, WINMM_WM_QUIT, 0, 0); + + for(i = 0; i < g_outmmdevices_count; ++i){ + WINMM_MMDevice *mmdevice = &g_out_mmdevices[i]; + + for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){ + WINMM_Device *device = mmdevice->devices[j]; + if(device->handle) + CloseHandle(device->handle); + DeleteCriticalSection(&device->lock); + } + + if(mmdevice->volume) + ISimpleAudioVolume_Release(mmdevice->volume); + CoTaskMemFree(mmdevice->dev_id); + DeleteCriticalSection(&mmdevice->lock); + } + + for(i = 0; i < g_inmmdevices_count; ++i){ + WINMM_MMDevice *mmdevice = &g_in_mmdevices[i]; + + for(j = 0; j < MAX_DEVICES && mmdevice->devices[j]; ++j){ + WINMM_Device *device = mmdevice->devices[j]; + if(device->handle) + CloseHandle(device->handle); + DeleteCriticalSection(&device->lock); + } + + if(mmdevice->volume) + ISimpleAudioVolume_Release(mmdevice->volume); + CoTaskMemFree(mmdevice->dev_id); + DeleteCriticalSection(&mmdevice->lock); } + + HeapFree(GetProcessHeap(), 0, g_out_mmdevices); + HeapFree(GetProcessHeap(), 0, g_in_mmdevices); + + HeapFree(GetProcessHeap(), 0, g_device_handles); + HeapFree(GetProcessHeap(), 0, g_handle_devices); } - /* FIXME: Free g_(in,out)_mmdevices? */ DeleteCriticalSection(&g_devthread_lock); } @@ -2146,6 +2187,13 @@ static LRESULT CALLBACK WINMM_DevicesMsgProc(HWND hwnd, UINT msg, WPARAM wparam, case DRV_QUERYDEVICEINTERFACESIZE: case DRV_QUERYDEVICEINTERFACE: return DRV_QueryDeviceInterface((WINMM_QueryInterfaceInfo*)wparam); + case WINMM_WM_QUIT: + TRACE("QUIT message received\n"); + DestroyWindow(g_devices_hwnd); + g_devices_hwnd = NULL; + IMMDeviceEnumerator_Release(g_devenum); + CoUninitialize(); + return 0; } return DefWindowProcW(hwnd, msg, wparam, lparam); } @@ -2200,6 +2248,8 @@ static DWORD WINAPI WINMM_DevicesThreadProc(void *arg) MSG msg; if(PeekMessageW(&msg, g_devices_hwnd, 0, 0, PM_REMOVE)) WARN("Unexpected message: 0x%x\n", msg.message); + if(!g_devices_hwnd) + break; }else if(wait < g_devhandle_count + WAIT_OBJECT_0){ WINMM_Device *device = g_handle_devices[wait - WAIT_OBJECT_0]; if(device->render) @@ -2211,12 +2261,6 @@ static DWORD WINAPI WINMM_DevicesThreadProc(void *arg) GetLastError()); } - DestroyWindow(g_devices_hwnd); - - IMMDeviceEnumerator_Release(g_devenum); - - CoUninitialize(); - return 0; } diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c index 714a84e1c2..26ac410e8d 100644 --- a/dlls/winmm/winmm.c +++ b/dlls/winmm/winmm.c @@ -82,18 +82,6 @@ static BOOL WINMM_CreateIData(HINSTANCE hInstDLL) return TRUE; } -/************************************************************************** - * WINMM_DeleteIData [internal] - */ -static void WINMM_DeleteIData(void) -{ - TIME_MMTimeStop(); - - WINMM_DeleteWaveform(); - CloseHandle(psLastEvent); - DeleteCriticalSection(&WINMM_cs); -} - /****************************************************************** * WINMM_ErrorToString */ @@ -153,20 +141,17 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad) return FALSE; break; case DLL_PROCESS_DETACH: - /* close all opened MCI drivers */ + if(fImpLoad) + break; + MCI_SendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, 0L); MMDRV_Exit(); - /* There's no guarantee the drivers haven't already been unloaded on - * process shutdown. - */ - if (!fImpLoad) - { - /* now unload all remaining drivers... */ - DRIVER_UnloadAll(); - } - - WINMM_DeleteIData(); - break; + DRIVER_UnloadAll(); + WINMM_DeleteWaveform(); + TIME_MMTimeStop(); + CloseHandle(psLastEvent); + DeleteCriticalSection(&WINMM_cs); + break; } return TRUE; } -- 2.32.0.93.g670b81a890