[PATCH 0/2] MR10168: winmm: Call WINMM_InitMMDevices once on systems without sound devices.
From: Piotr Caban <piotr@codeweavers.com> --- dlls/winmm/waveform.c | 50 ++++++++++++------------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c index fa1c446ff91..e75ce0a2151 100644 --- a/dlls/winmm/waveform.c +++ b/dlls/winmm/waveform.c @@ -132,6 +132,7 @@ struct _WINMM_MMDevice { WINMM_Device *devices[MAX_DEVICES]; }; +static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; static WINMM_MMDevice *g_out_mmdevices; static WINMM_MMDevice **g_out_map; static UINT g_outmmdevices_count; @@ -830,14 +831,11 @@ static IMMNotificationClientVtbl g_notif_vtbl = { static IMMNotificationClient g_notif = { &g_notif_vtbl }; -static HRESULT WINMM_InitMMDevices(void) +static BOOL WINAPI WINMM_InitMMDevices(INIT_ONCE *once, void *param, void **context) { HRESULT hr, init_hr; IMMDeviceEnumerator *devenum = NULL; - if(g_outmmdevices_count || g_inmmdevices_count) - return S_FALSE; - init_hr = CoInitialize(NULL); hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, @@ -870,7 +868,7 @@ exit: if(SUCCEEDED(init_hr)) CoUninitialize(); - return hr; + return SUCCEEDED(hr); } static inline BOOL WINMM_IsMapper(UINT device) @@ -2441,8 +2439,7 @@ static DWORD WINAPI WINMM_DevicesThreadProc(void *arg) FreeLibraryAndExitThread(g_devthread_module, 1); } - hr = WINMM_InitMMDevices(); - if(FAILED(hr)){ + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)){ CoUninitialize(); FreeLibraryAndExitThread(g_devthread_module, 1); } @@ -2573,8 +2570,7 @@ static BOOL WINMM_StartDevicesThread(void) */ UINT WINAPI waveOutGetNumDevs(void) { - HRESULT hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return 0; TRACE("count: %u\n", g_outmmdevices_count); @@ -2621,12 +2617,10 @@ UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, UINT uSize) { WAVEOUTCAPSW mapper_caps, *caps; - HRESULT hr; TRACE("(%Iu, %p, %u)\n", uDeviceID, lpCaps, uSize); - hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return MMSYSERR_NODRIVER; if (lpCaps == NULL) return MMSYSERR_INVALPARAM; @@ -3291,8 +3285,7 @@ UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, */ UINT WINAPI waveInGetNumDevs(void) { - HRESULT hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return 0; TRACE("count: %u\n", g_inmmdevices_count); @@ -3306,12 +3299,10 @@ UINT WINAPI waveInGetNumDevs(void) UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize) { WAVEINCAPSW mapper_caps, *caps; - HRESULT hr; TRACE("(%Iu, %p, %u)\n", uDeviceID, lpCaps, uSize); - hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return MMSYSERR_NODRIVER; if(!lpCaps) @@ -3694,12 +3685,9 @@ UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, UINT WINAPI mixerGetNumDevs(void) { - HRESULT hr; - TRACE("\n"); - hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return 0; return g_outmmdevices_count + g_inmmdevices_count; @@ -3741,12 +3729,10 @@ UINT WINAPI mixerGetDevCapsW(UINT_PTR uDeviceID, LPMIXERCAPSW lpCaps, UINT uSize { WINMM_MMDevice *mmdevice; MIXERCAPSW caps; - HRESULT hr; TRACE("(%Iu, %p, %u)\n", uDeviceID, lpCaps, uSize); - hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return MMSYSERR_NODRIVER; if(!lpCaps) @@ -3790,13 +3776,11 @@ UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback, { WINMM_MMDevice *mmdevice; MMRESULT mr; - HRESULT hr; TRACE("(%p, %d, %Ix, %Ix, %lx)\n", lphMix, uDeviceID, dwCallback, dwInstance, fdwOpen); - hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return MMSYSERR_NODRIVER; if(!lphMix) @@ -3840,12 +3824,10 @@ UINT WINAPI mixerClose(HMIXER hMix) UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID) { WINMM_MMDevice *mmdevice; - HRESULT hr; TRACE("(%p, %p, %lx)\n", hmix, lpid, fdwID); - hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return MMSYSERR_NODRIVER; if(!lpid) @@ -4052,12 +4034,10 @@ UINT WINAPI mixerGetLineControlsW(HMIXEROBJ hmix, LPMIXERLINECONTROLSW lpmlcW, DWORD fdwControls) { WINMM_MMDevice *mmdevice; - HRESULT hr; TRACE("(%p, %p, %08lx)\n", hmix, lpmlcW, fdwControls); - hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return MMSYSERR_NODRIVER; if(fdwControls & ~(MIXER_GETLINECONTROLSF_ALL | @@ -4270,12 +4250,10 @@ UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW, DWORD fdwInfo { UINT mmdev_index; WINMM_MMDevice *mmdevice; - HRESULT hr; TRACE("(%p, %p, %lx)\n", hmix, lpmliW, fdwInfo); - hr = WINMM_InitMMDevices(); - if(FAILED(hr)) + if(!InitOnceExecuteOnce(&init_once, WINMM_InitMMDevices, NULL, NULL)) return MMSYSERR_NODRIVER; if(!lpmliW || lpmliW->cbStruct < sizeof(MIXERLINEW)) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10168
From: Piotr Caban <piotr@codeweavers.com> --- dlls/winmm/waveform.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c index e75ce0a2151..e280c999860 100644 --- a/dlls/winmm/waveform.c +++ b/dlls/winmm/waveform.c @@ -192,6 +192,8 @@ static LRESULT WID_Close(HWAVEIN hwave); static MMRESULT WINMM_BeginPlaying(WINMM_Device *device); static void WOD_PushData(WINMM_Device *device); +static IMMNotificationClient g_notif; + void WINMM_DeleteWaveform(void) { UINT i, j; @@ -235,6 +237,11 @@ void WINMM_DeleteWaveform(void) DeleteCriticalSection(&mmdevice->lock); } + if (g_devenum){ + IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(g_devenum, &g_notif); + IMMDeviceEnumerator_Release(g_devenum); + } + free(g_out_mmdevices); free(g_in_mmdevices); @@ -834,21 +841,20 @@ static IMMNotificationClient g_notif = { &g_notif_vtbl }; static BOOL WINAPI WINMM_InitMMDevices(INIT_ONCE *once, void *param, void **context) { HRESULT hr, init_hr; - IMMDeviceEnumerator *devenum = NULL; init_hr = CoInitialize(NULL); hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, - CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&devenum); + CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&g_devenum); if(FAILED(hr)) goto exit; - hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(devenum, &g_notif); + hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(g_devenum, &g_notif); if(FAILED(hr)) - WARN("RegisterEndpointNotificationCallback failed: %08lx\n", hr); + goto exit; hr = WINMM_EnumDevices(&g_out_mmdevices, &g_out_map, &g_outmmdevices_count, - eRender, devenum); + eRender, g_devenum); if(FAILED(hr)){ g_outmmdevices_count = 0; g_inmmdevices_count = 0; @@ -856,15 +862,18 @@ static BOOL WINAPI WINMM_InitMMDevices(INIT_ONCE *once, void *param, void **cont } hr = WINMM_EnumDevices(&g_in_mmdevices, &g_in_map, &g_inmmdevices_count, - eCapture, devenum); + eCapture, g_devenum); if(FAILED(hr)){ g_inmmdevices_count = 0; goto exit; } exit: - if(devenum) - IMMDeviceEnumerator_Release(devenum); + if(FAILED(hr) && g_devenum){ + IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(g_devenum, &g_notif); + IMMDeviceEnumerator_Release(g_devenum); + g_devenum = NULL; + } if(SUCCEEDED(init_hr)) CoUninitialize(); @@ -2419,8 +2428,6 @@ static BOOL WINMM_DevicesThreadDone(void) DestroyWindow(g_devices_hwnd); g_devices_hwnd = NULL; - IMMDeviceEnumerator_Release(g_devenum); - g_devenum = NULL; CoUninitialize(); LeaveCriticalSection(&g_devthread_lock); @@ -2444,14 +2451,6 @@ static DWORD WINAPI WINMM_DevicesThreadProc(void *arg) FreeLibraryAndExitThread(g_devthread_module, 1); } - hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, - CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&g_devenum); - if(FAILED(hr)){ - WARN("CoCreateInstance failed: %08lx\n", hr); - CoUninitialize(); - FreeLibraryAndExitThread(g_devthread_module, 1); - } - g_devices_hwnd = CreateWindowW(L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); if(!g_devices_hwnd){ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10168
This merge request was approved by Huw Davies. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10168
participants (3)
-
Huw Davies (@huw) -
Piotr Caban -
Piotr Caban (@piotr)