diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 706ac038..92ca70a4 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -51,9 +51,11 @@ find_package(Qt${QT_VERSION_MAJOR} set(SRC_EXE_MAIN source/scwx/qt/main/main.cpp) set(HDR_MAIN source/scwx/qt/main/application.hpp - source/scwx/qt/main/main_window.hpp) + source/scwx/qt/main/main_window.hpp + source/scwx/qt/main/process_validation.hpp) set(SRC_MAIN source/scwx/qt/main/application.cpp - source/scwx/qt/main/main_window.cpp) + source/scwx/qt/main/main_window.cpp + source/scwx/qt/main/process_validation.cpp) set(UI_MAIN source/scwx/qt/main/main_window.ui) set(HDR_CONFIG source/scwx/qt/config/county_database.hpp source/scwx/qt/config/radar_site.hpp) diff --git a/scwx-qt/source/scwx/qt/main/main.cpp b/scwx-qt/source/scwx/qt/main/main.cpp index 0e379961..7d66c80d 100644 --- a/scwx-qt/source/scwx/qt/main/main.cpp +++ b/scwx-qt/source/scwx/qt/main/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -113,6 +114,9 @@ int main(int argc, char* argv[]) // Theme ConfigureTheme(args); + // Check process modules for compatibility + scwx::qt::main::CheckProcessModules(); + // Run initial setup if required if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired()) { @@ -170,7 +174,8 @@ static void ConfigureTheme(const std::vector& args) QGuiApplication::styleHints()->setColorScheme(qtColorScheme); std::optional paletteFile; - if (uiStyle == scwx::qt::types::UiStyle::FusionCustom) { + if (uiStyle == scwx::qt::types::UiStyle::FusionCustom) + { paletteFile = generalSettings.theme_file().GetValue(); } else diff --git a/scwx-qt/source/scwx/qt/main/process_validation.cpp b/scwx-qt/source/scwx/qt/main/process_validation.cpp new file mode 100644 index 00000000..61f2cb29 --- /dev/null +++ b/scwx-qt/source/scwx/qt/main/process_validation.cpp @@ -0,0 +1,109 @@ +#include +#include + +#if defined(_WIN32) +# include + +# include +# include + +# include +# include +# include +# include +# include +#endif + +namespace scwx::qt::main +{ + +static const std::string logPrefix_ = "scwx::qt::main::process_validation"; +static const auto logger_ = util::Logger::Create(logPrefix_); + +void CheckProcessModules() +{ +#if defined(_WIN32) + HANDLE process = GetCurrentProcess(); + HMODULE modules[1024]; + DWORD cbNeeded = 0; + + std::vector incompatibleDlls {}; + std::vector descriptions {}; + + auto& processModuleWarningsEnabled = + settings::GeneralSettings::Instance().process_module_warnings_enabled(); + + if (EnumProcessModules(process, modules, sizeof(modules), &cbNeeded)) + { + std::uint32_t numModules = cbNeeded / sizeof(HMODULE); + for (std::uint32_t i = 0; i < numModules; ++i) + { + char modulePath[MAX_PATH]; + if (GetModuleFileNameExA(process, modules[i], modulePath, MAX_PATH)) + { + std::string path = modulePath; + + logger_->trace("DLL Found: {}", path); + + if (boost::algorithm::iends_with(path, "NahimicOSD.dll")) + { + std::string description = + QObject::tr( + "ASUS Sonic Studio injects a Nahimic driver, which causes " + "Supercell Wx to hang. It is suggested to disable the " + "Nahimic service, or to uninstall ASUS Sonic Studio and " + "the Nahimic driver.") + .toStdString(); + + logger_->warn("Incompatible DLL found: {}", path); + logger_->warn("{}", description); + + // Only populate vectors for the message box if warnings are + // enabled + if (processModuleWarningsEnabled.GetValue()) + { + incompatibleDlls.push_back(path); + descriptions.push_back(description); + } + } + } + } + } + + if (!incompatibleDlls.empty()) + { + const std::string header = + QObject::tr( + "The following DLLs have been injected into the Supercell Wx " + "process:") + .toStdString(); + const std::string defaultMessage = + QObject::tr( + "Supercell Wx is known to not run correctly with these DLLs " + "injected. We suggest stopping or uninstalling these services if " + "you experience crashes or unexpected behavior while using " + "Supercell Wx.") + .toStdString(); + + std::string message = fmt::format("{}\n\n{}\n\n{}\n\n{}", + header, + fmt::join(incompatibleDlls, "\n"), + defaultMessage, + fmt::join(descriptions, "\n")); + + QMessageBox dialog(QMessageBox::Icon::Warning, + QObject::tr("Supercell Wx"), + QString::fromStdString(message)); + QCheckBox* checkBox = + new QCheckBox(QObject::tr("Don't show this message again"), &dialog); + dialog.setCheckBox(checkBox); + dialog.exec(); + + // Stage the result of the checkbox. This value will be committed on + // shutdown. + processModuleWarningsEnabled.StageValue(!checkBox->isChecked()); + } +#endif +} + +} // namespace scwx::qt::main diff --git a/scwx-qt/source/scwx/qt/main/process_validation.hpp b/scwx-qt/source/scwx/qt/main/process_validation.hpp new file mode 100644 index 00000000..fb8fabaf --- /dev/null +++ b/scwx-qt/source/scwx/qt/main/process_validation.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace scwx::qt::main +{ + +void CheckProcessModules(); + +} // namespace scwx::qt::main diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.cpp b/scwx-qt/source/scwx/qt/settings/general_settings.cpp index ccd7e886..77ca764e 100644 --- a/scwx-qt/source/scwx/qt/settings/general_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/general_settings.cpp @@ -69,6 +69,7 @@ class GeneralSettings::Impl nmeaBaudRate_.SetDefault(9600); nmeaSource_.SetDefault(""); positioningPlugin_.SetDefault(defaultPositioningPlugin); + processModuleWarningsEnabled_.SetDefault(true); showMapAttribution_.SetDefault(true); showMapCenter_.SetDefault(false); showMapLogo_.SetDefault(true); @@ -162,12 +163,14 @@ class GeneralSettings::Impl SettingsVariable nmeaBaudRate_ {"nmea_baud_rate"}; SettingsVariable nmeaSource_ {"nmea_source"}; SettingsVariable positioningPlugin_ {"positioning_plugin"}; - SettingsVariable showMapAttribution_ {"show_map_attribution"}; - SettingsVariable showMapCenter_ {"show_map_center"}; - SettingsVariable showMapLogo_ {"show_map_logo"}; - SettingsVariable theme_ {"theme"}; - SettingsVariable themeFile_ {"theme_file"}; - SettingsVariable trackLocation_ {"track_location"}; + SettingsVariable processModuleWarningsEnabled_ { + "process_module_warnings_enabled"}; + SettingsVariable showMapAttribution_ {"show_map_attribution"}; + SettingsVariable showMapCenter_ {"show_map_center"}; + SettingsVariable showMapLogo_ {"show_map_logo"}; + SettingsVariable theme_ {"theme"}; + SettingsVariable themeFile_ {"theme_file"}; + SettingsVariable trackLocation_ {"track_location"}; SettingsVariable updateNotificationsEnabled_ {"update_notifications"}; SettingsVariable warningsProvider_ {"warnings_provider"}; SettingsVariable cursorIconAlwaysOn_ {"cursor_icon_always_on"}; @@ -197,6 +200,7 @@ GeneralSettings::GeneralSettings() : &p->nmeaBaudRate_, &p->nmeaSource_, &p->positioningPlugin_, + &p->processModuleWarningsEnabled_, &p->showMapAttribution_, &p->showMapCenter_, &p->showMapLogo_, @@ -316,6 +320,11 @@ SettingsVariable& GeneralSettings::positioning_plugin() const return p->positioningPlugin_; } +SettingsVariable& GeneralSettings::process_module_warnings_enabled() const +{ + return p->processModuleWarningsEnabled_; +} + SettingsVariable& GeneralSettings::show_map_attribution() const { return p->showMapAttribution_; @@ -374,6 +383,7 @@ bool GeneralSettings::Shutdown() dataChanged |= p->loopDelay_.Commit(); dataChanged |= p->loopSpeed_.Commit(); dataChanged |= p->loopTime_.Commit(); + dataChanged |= p->processModuleWarningsEnabled_.Commit(); dataChanged |= p->trackLocation_.Commit(); return dataChanged; @@ -407,6 +417,8 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs) lhs.p->nmeaBaudRate_ == rhs.p->nmeaBaudRate_ && lhs.p->nmeaSource_ == rhs.p->nmeaSource_ && lhs.p->positioningPlugin_ == rhs.p->positioningPlugin_ && + lhs.p->processModuleWarningsEnabled_ == + rhs.p->processModuleWarningsEnabled_ && lhs.p->showMapAttribution_ == rhs.p->showMapAttribution_ && lhs.p->showMapCenter_ == rhs.p->showMapCenter_ && lhs.p->showMapLogo_ == rhs.p->showMapLogo_ && diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.hpp b/scwx-qt/source/scwx/qt/settings/general_settings.hpp index 46b342d7..6a49566b 100644 --- a/scwx-qt/source/scwx/qt/settings/general_settings.hpp +++ b/scwx-qt/source/scwx/qt/settings/general_settings.hpp @@ -45,12 +45,13 @@ class GeneralSettings : public SettingsCategory SettingsVariable& nmea_baud_rate() const; SettingsVariable& nmea_source() const; SettingsVariable& positioning_plugin() const; - SettingsVariable& show_map_attribution() const; - SettingsVariable& show_map_center() const; - SettingsVariable& show_map_logo() const; - SettingsVariable& theme() const; - SettingsVariable& theme_file() const; - SettingsVariable& track_location() const; + SettingsVariable& process_module_warnings_enabled() const; + SettingsVariable& show_map_attribution() const; + SettingsVariable& show_map_center() const; + SettingsVariable& show_map_logo() const; + SettingsVariable& theme() const; + SettingsVariable& theme_file() const; + SettingsVariable& track_location() const; SettingsVariable& update_notifications_enabled() const; SettingsVariable& warnings_provider() const; SettingsVariable& cursor_icon_always_on() const; diff --git a/test/data b/test/data index 0d085b1d..24ececcd 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 0d085b1df59045e14ca996982b4907b1a0da4fdb +Subproject commit 24ececcd183d3b8961e5638da89f0eb36309cd6b