summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-11-26 08:39:22 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2019-11-26 08:39:22 -0500
commitc3068ce50ab6e25e21452c2ea2f83086ddf555d5 (patch)
tree0e4f7c67852256a9847a8deccae8226d292b7969
parent2c2c47c21502db6471fe7d727f942c2400b150c1 (diff)
added rivatuner to sanity checks
now also checks modules loaded after startup fixed crash on w7 when checking some modules
-rw-r--r--src/env.cpp44
-rw-r--r--src/env.h11
-rw-r--r--src/main.cpp4
-rw-r--r--src/sanitychecks.cpp37
4 files changed, 63 insertions, 33 deletions
diff --git a/src/env.cpp b/src/env.cpp
index 51631607..f9507dc1 100644
--- a/src/env.cpp
+++ b/src/env.cpp
@@ -56,8 +56,8 @@ Console::~Console()
}
-ModuleNotification::ModuleNotification(std::function<void (Module)> f)
- : m_cookie(nullptr), m_f(std::move(f))
+ModuleNotification::ModuleNotification(QObject* o, std::function<void (Module)> f)
+ : m_cookie(nullptr), m_object(o), m_f(std::move(f))
{
}
@@ -97,10 +97,26 @@ void ModuleNotification::setCookie(void* c)
m_cookie = c;
}
-void ModuleNotification::fire(const Module& m)
+void ModuleNotification::fire(QString path, std::size_t fileSize)
{
+ if (m_loaded.contains(path)) {
+ // don't notify if it's been loaded before
+ }
+
+ m_loaded.insert(path);
+
+ // constructing a Module will query the version info of the file, which seems
+ // to generate an access violation for at least plugin_python.dll on Windows 7
+ //
+ // it's not clear what the problem is, but making sure this is deferred until
+ // _after_ the dll is loaded seems to fix it
+ //
+ // so this queues the callback in the main thread
+
if (m_f) {
- m_f(m);
+ QMetaObject::invokeMethod(m_object, [path, fileSize, f=m_f] {
+ f(Module(path, fileSize));
+ }, Qt::QueuedConnection);
}
}
@@ -196,7 +212,7 @@ QString Environment::timezone() const
}
std::unique_ptr<ModuleNotification> Environment::onModuleLoaded(
- std::function<void (Module)> f)
+ QObject* o, std::function<void (Module)> f)
{
typedef struct _UNICODE_STRING {
USHORT Length;
@@ -263,19 +279,19 @@ std::unique_ptr<ModuleNotification> Environment::onModuleLoaded(
}
- auto context = std::make_unique<ModuleNotification>(f);
+ auto context = std::make_unique<ModuleNotification>(o, f);
void* cookie = nullptr;
auto OnDllLoaded = [](ULONG reason, const PLDR_DLL_NOTIFICATION_DATA data, void* context) {
if (reason == LDR_DLL_NOTIFICATION_REASON_LOADED) {
- const Module m(
- QString::fromWCharArray(
- data->Loaded.FullDllName->Buffer,
- data->Loaded.FullDllName->Length / sizeof(wchar_t)),
- data->Loaded.SizeOfImage);
-
- if (context) {
- static_cast<ModuleNotification*>(context)->fire(m);
+ if (data && data->Loaded.FullDllName) {
+ if (context) {
+ static_cast<ModuleNotification*>(context)->fire(
+ QString::fromWCharArray(
+ data->Loaded.FullDllName->Buffer,
+ data->Loaded.FullDllName->Length / sizeof(wchar_t)),
+ data->Loaded.SizeOfImage);
+ }
}
}
};
diff --git a/src/env.h b/src/env.h
index 946cb13b..dc0fd864 100644
--- a/src/env.h
+++ b/src/env.h
@@ -122,7 +122,7 @@ private:
class ModuleNotification
{
public:
- ModuleNotification(std::function<void (Module)> f);
+ ModuleNotification(QObject* o, std::function<void (Module)> f);
~ModuleNotification();
ModuleNotification(const ModuleNotification&) = delete;
@@ -132,10 +132,12 @@ public:
ModuleNotification& operator=(ModuleNotification&&) = default;
void setCookie(void* c);
- void fire(const Module& m);
+ void fire(QString path, std::size_t fileSize);
private:
void* m_cookie;
+ QObject* m_object;
+ std::set<QString> m_loaded;
std::function<void (Module)> m_f;
};
@@ -172,8 +174,11 @@ public:
//
QString timezone() const;
+ // will call `f` on the same thread `o` is running on every time a module
+ // is loaded in the process
+ //
std::unique_ptr<ModuleNotification> onModuleLoaded(
- std::function<void (Module)> f);
+ QObject* o, std::function<void (Module)> f);
// logs the environment
//
diff --git a/src/main.cpp b/src/main.cpp
index 6e112479..3cccf365 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -93,6 +93,7 @@ using namespace MOShared;
void sanityChecks(const env::Environment& env);
+int checkIncompatibleModule(const env::Module& m);
bool createAndMakeWritable(const std::wstring &subPath) {
QString const dataPath = qApp->property("dataPath").toString();
@@ -547,8 +548,9 @@ int runApplication(MOApplication &application, SingleInstance &instance,
settings.dump();
sanityChecks(env);
- const auto moduleNotification = env.onModuleLoaded([](auto&& m) {
+ const auto moduleNotification = env.onModuleLoaded(qApp, [](auto&& m) {
log::debug("loaded module {}", m.toString());
+ checkIncompatibleModule(m);
});
log::debug("initializing core");
diff --git a/src/sanitychecks.cpp b/src/sanitychecks.cpp
index 3b4185a7..495795f2 100644
--- a/src/sanitychecks.cpp
+++ b/src/sanitychecks.cpp
@@ -202,29 +202,36 @@ int checkMissingFiles()
return n;
}
-bool checkNahimic(const env::Environment& e)
+int checkIncompatibleModule(const env::Module& m)
{
- // Nahimic seems to interfere mostly with dialogs, like the mod info dialog:
- // it renders dialogs fully white and makes it impossible to interact with
- // them
+ // these dlls seems to interfere mostly with dialogs, like the mod info
+ // dialog: it renders dialogs fully white and makes it impossible to interact
+ // with them
//
- // NahimicOSD.dll is usually loaded on startup, but there has been some
- // reports where it got loaded later, so this check is not entirely accurate
+ // the dlls is usually loaded on startup, but there has been some reports
+ // where it got loaded later, so this is also called every time a new module
+ // is loaded into this process
- for (auto&& m : e.loadedModules()) {
- const QFileInfo file(m.path());
+ static const std::map<QString, QString> names = {
+ {"NahimicOSD.dll", "Nahimic"},
+ {"RTSSHooks64.dll", "RivaTuner Statistics Server"}
+ };
+
+ const QFileInfo file(m.path());
+ int n = 0;
- if (file.fileName().compare("NahimicOSD.dll", Qt::CaseInsensitive) == 0) {
+ for (auto&& p : names) {
+ if (file.fileName().compare(p.first, Qt::CaseInsensitive) == 0) {
log::warn(
- "NahimicOSD.dll is loaded. Nahimic is known to cause issues with "
+ "{} is loaded. This program is known to cause issues with "
"Mod Organizer, such as freezing or blank windows. Consider "
- "uninstalling it.");
+ "uninstalling it. ({})", p.second, file.absoluteFilePath());
- return true;
+ ++n;
}
}
- return false;
+ return n;
}
int checkIncompatibilities(const env::Environment& e)
@@ -233,8 +240,8 @@ int checkIncompatibilities(const env::Environment& e)
int n = 0;
- if (checkNahimic(e)) {
- ++n;
+ for (auto&& m : e.loadedModules()) {
+ n += checkIncompatibleModule(m);
}
return n;