From da5f6e9e7d4cbf4ba74a63b82b67008541bdfcdb Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 7 Jun 2021 22:24:48 +0200 Subject: [PATCH] Always initialize Microsoft COM unconditionally --- CHANGELOG.md | 4 ++++ src/wine-host/bridges/vst2.cpp | 15 --------------- src/wine-host/bridges/vst3.cpp | 19 ++----------------- src/wine-host/group-host.cpp | 5 +++++ src/wine-host/individual-host.cpp | 5 +++++ 5 files changed, 16 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eb5cad6..4b42b1ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Fixed +- Fixed _Shattered Glass Audio Code Red (Free)_ crashing when opening the plugin + editor because the plugin doesn't initialize Microsoft COM before using it. We + now always initialize Microsoft COM unconditionally, instead of only doing it + when a plugin fails to initialize the first time without it. - Fixed mouse clicks in VST2 editors in **Tracktion Waveform** being offset vertically because of the way Waveform embeds VST2 editors. diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index 6adf3125..318072bc 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -137,21 +137,6 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context, logger(generic_logger), plugin_handle(LoadLibrary(plugin_dll_path.c_str()), FreeLibrary), sockets(main_context.context, endpoint_base_dir, false) { - // HACK: If the plugin library was unable to load, then there's a tiny - // chance that the plugin expected the COM library to already be - // initialized. I've only seen PSPaudioware's InfiniStrip do this. In - // that case, we'll initialize the COM library for them and try again. - if (!plugin_handle) { - OleInitialize(nullptr); - plugin_handle.reset(LoadLibrary(plugin_dll_path.c_str())); - if (plugin_handle) { - std::cerr << "WARNING: '" << plugin_dll_path << "'" << std::endl; - std::cerr << " could only load after we manually" - << std::endl; - std::cerr << " initialized the COM library." << std::endl; - } - } - if (!plugin_handle) { throw std::runtime_error("Could not load the Windows .dll file at '" + plugin_dll_path + "'"); diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index 004848b4..ce3be9b9 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -87,22 +87,6 @@ Vst3Bridge::Vst3Bridge(MainContext& main_context, sockets(main_context.context, endpoint_base_dir, false) { std::string error; module = VST3::Hosting::Win32Module::create(plugin_dll_path, error); - - // HACK: If the plugin library was unable to load, then there's a tiny - // chance that the plugin expected the COM library to already be - // initialized. I've only seen PSPaudioware's InfiniStrip do this. In - // that case, we'll initialize the COM library for them and try again. - if (!module) { - OleInitialize(nullptr); - module = VST3::Hosting::Win32Module::create(plugin_dll_path, error); - if (module) { - std::cerr << "WARNING: '" << plugin_dll_path << "'" << std::endl; - std::cerr << " could only load after we manually" - << std::endl; - std::cerr << " initialized the COM library." << std::endl; - } - } - if (!module) { throw std::runtime_error("Could not load the VST3 module for '" + plugin_dll_path + "': " + error); @@ -1187,7 +1171,8 @@ size_t Vst3Bridge::register_object_instance( // thread names from different plugins will clash. Not a huge // deal probably, since duplicate thread names are still more // useful than no thread names. - const std::string thread_name = "audio-" + std::to_string(instance_id); + const std::string thread_name = + "audio-" + std::to_string(instance_id); pthread_setname_np(pthread_self(), thread_name.c_str()); sockets.add_audio_processor_and_listen( diff --git a/src/wine-host/group-host.cpp b/src/wine-host/group-host.cpp index a38a56e4..d2cee47b 100644 --- a/src/wine-host/group-host.cpp +++ b/src/wine-host/group-host.cpp @@ -65,6 +65,11 @@ __cdecl #endif << std::endl; + // NOTE: Some plugins use Microsoft COM, but don't initialize it first and + // just pray the host does it for them. Examples of this are + // PSPaudioware's InfiniStrip and Shattered Glass Audio Code Red Free. + OleInitialize(nullptr); + try { GroupBridge bridge(group_socket_endpoint_path); diff --git a/src/wine-host/individual-host.cpp b/src/wine-host/individual-host.cpp index 04c7e44d..158e40b1 100644 --- a/src/wine-host/individual-host.cpp +++ b/src/wine-host/individual-host.cpp @@ -69,6 +69,11 @@ __cdecl std::cerr << "Preparing to load " << plugin_type_to_string(plugin_type) << " plugin at '" << plugin_location << "'" << std::endl; + // NOTE: Some plugins use Microsoft COM, but don't initialize it first and + // just pray the host does it for them. Examples of this are + // PSPaudioware's InfiniStrip and Shattered Glass Audio Code Red Free. + OleInitialize(nullptr); + // As explained in `Vst2Bridge`, the plugin has to be initialized in the // same thread as the one that calls `io_context.run()`. This setup is // slightly more convoluted than it has to be, but doing it this way we