From: Bernhard Kölbl <bkoelbl@codeweavers.com> --- dlls/windows.media.speech/main.c | 19 +++++++ dlls/windows.media.speech/private.h | 3 + dlls/windows.media.speech/synthesizer.c | 74 +++++++++++++------------ 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/dlls/windows.media.speech/main.c b/dlls/windows.media.speech/main.c index e772a791588..6e0421a0ae3 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -24,6 +24,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(speech); +BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) +{ + HRESULT hr; + + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(instance); + if (FAILED(hr = static_installed_voices_init())) + WARN("failed to initialize synthesizer voices, hr %#lx.\n", hr); + break; + case DLL_PROCESS_DETACH: + static_installed_voices_deinit(); + break; + } + + return TRUE; +} + HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out) { FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out); diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h index e7921370f11..e5933da1811 100644 --- a/dlls/windows.media.speech/private.h +++ b/dlls/windows.media.speech/private.h @@ -86,6 +86,9 @@ HRESULT vector_hstring_create( IVector_HSTRING **out ); HRESULT vector_hstring_create_copy( IIterable_HSTRING *iterable, IVector_HSTRING **out ); HRESULT vector_inspectable_create( const struct vector_iids *iids, IVector_IInspectable **out ); +HRESULT static_installed_voices_init(void); +void static_installed_voices_deinit(void); + #define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ static inline impl_type *impl_from( iface_type *iface ) \ { \ diff --git a/dlls/windows.media.speech/synthesizer.c b/dlls/windows.media.speech/synthesizer.c index bbe6181c1d4..c68321a50bb 100644 --- a/dlls/windows.media.speech/synthesizer.c +++ b/dlls/windows.media.speech/synthesizer.c @@ -295,20 +295,7 @@ static ULONG WINAPI vector_view_voice_information_Release( IVectorView_VoiceInfo { struct voice_information_vector *impl = impl_from_IVectorView_VoiceInformation(iface); ULONG ref = InterlockedDecrement(&impl->ref); - UINT32 i; - TRACE("iface %p, ref %lu.\n", iface, ref); - - if (!ref) - { - for (i = 0; i < impl->provider.num_voices; ++i) - { - IVoiceInformation_Release(impl->provider.voices[i]); - impl->provider.voices[i] = 0; - } - impl->provider.num_voices = 0; - } - return ref; } @@ -1693,7 +1680,6 @@ static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInsp if (FAILED(hr = synthesizer_options_create(&impl->options))) goto failed; - /* make sure the provider is initialized */ if (FAILED(hr = IInstalledVoicesStatic_get_AllVoices(&statics->IInstalledVoicesStatic_iface, &voice_infos))) goto failed; @@ -1737,11 +1723,30 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, }; -static HRESULT static_installed_voices_init(void) +/* + * + * IInstalledVoicesStatic for SpeechSynthesizer runtimeclass + * + */ + +DEFINE_IINSPECTABLE(installed_voices_static, IInstalledVoicesStatic, struct synthesizer_statics, IActivationFactory_iface) + +static CRITICAL_SECTION allvoices_cs; +static CRITICAL_SECTION_DEBUG allvoices_critsect_debug = +{ + 0, 0, &allvoices_cs, + { &allvoices_critsect_debug.ProcessLocksList, &allvoices_critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": allvoices_cs") } +}; +static CRITICAL_SECTION allvoices_cs = { &allvoices_critsect_debug, -1, 0, 0, 0, 0 }; + +HRESULT static_installed_voices_init(void) { WCHAR locale[LOCALE_NAME_MAX_LENGTH]; HRESULT hr; + EnterCriticalSection(&allvoices_cs); + if (all_voices.provider.num_voices) return S_OK; @@ -1756,40 +1761,37 @@ static HRESULT static_installed_voices_init(void) else all_voices.provider.num_voices = 1; + LeaveCriticalSection(&allvoices_cs); + return hr; } -/* - * - * IInstalledVoicesStatic for SpeechSynthesizer runtimeclass - * - */ +void static_installed_voices_deinit(void) +{ + UINT32 i; -DEFINE_IINSPECTABLE(installed_voices_static, IInstalledVoicesStatic, struct synthesizer_statics, IActivationFactory_iface) + EnterCriticalSection(&allvoices_cs); -static CRITICAL_SECTION allvoices_cs; -static CRITICAL_SECTION_DEBUG allvoices_critsect_debug = -{ - 0, 0, &allvoices_cs, - { &allvoices_critsect_debug.ProcessLocksList, &allvoices_critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": allvoices_cs") } -}; -static CRITICAL_SECTION allvoices_cs = { &allvoices_critsect_debug, -1, 0, 0, 0, 0 }; + for (i = 0; i < all_voices.provider.num_voices; ++i) + { + IVoiceInformation_Release(all_voices.provider.voices[i]); + all_voices.provider.voices[i] = NULL; + } + + LeaveCriticalSection(&allvoices_cs); + + all_voices.provider.num_voices = 0; +} static HRESULT WINAPI installed_voices_static_get_AllVoices( IInstalledVoicesStatic *iface, IVectorView_VoiceInformation **value ) { - HRESULT hr; - TRACE("iface %p, value %p.\n", iface, value); EnterCriticalSection(&allvoices_cs); - - if (SUCCEEDED(hr = static_installed_voices_init())) - IVectorView_VoiceInformation_AddRef((*value = &all_voices.IVectorView_VoiceInformation_iface)); - + IVectorView_VoiceInformation_AddRef((*value = &all_voices.IVectorView_VoiceInformation_iface)); LeaveCriticalSection(&allvoices_cs); - return hr; + return S_OK; } static HRESULT WINAPI installed_voices_static_get_DefaultVoice( IInstalledVoicesStatic *iface, IVoiceInformation **value ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10275