From 633ef81972139f3c082429ada10ffb27d9f07898 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 27 Sep 2019 17:07:04 -0400
Subject: moved checks to sanitychecks.cpp added check for blocked files, only
logs
---
src/CMakeLists.txt | 2 +
src/main.cpp | 46 +-------------
src/sanitychecks.cpp | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 179 insertions(+), 43 deletions(-)
create mode 100644 src/sanitychecks.cpp
(limited to 'src')
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b21d1a8b..180422ef 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -142,6 +142,7 @@ SET(organizer_SRCS
envshortcut.cpp
envwindows.cpp
colortable.cpp
+ sanitychecks.cpp
shared/windows_error.cpp
shared/error_report.cpp
@@ -324,6 +325,7 @@ set(application
mainwindow
moapplication
moshortcut
+ sanitychecks
selfupdater
singleinstance
statusbar
diff --git a/src/main.cpp b/src/main.cpp
index ba988ae3..fe5fd87a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -91,6 +91,9 @@ along with Mod Organizer. If not, see .
using namespace MOBase;
using namespace MOShared;
+
+void sanityChecks(const env::Environment& env);
+
bool createAndMakeWritable(const std::wstring &subPath) {
QString const dataPath = qApp->property("dataPath").toString();
QString fullPath = dataPath + "/" + QString::fromStdWString(subPath);
@@ -496,49 +499,6 @@ static QString getVersionDisplayString()
return createVersionInfo().displayString(3);
}
-void checkMissingFiles()
-{
- // files that are likely to be eaten
- static const QStringList files({
- "helper.exe", "nxmhandler.exe",
- "usvfs_proxy_x64.exe", "usvfs_proxy_x86.exe",
- "usvfs_x64.dll", "usvfs_x86.dll"
- });
-
- const auto dir = QCoreApplication::applicationDirPath();
-
- for (const auto& name : files) {
- const QFileInfo file(dir + QDir::separator() + name);
- if (!file.exists()) {
- log::warn(
- "'{}' seems to be missing, an antivirus may have deleted it",
- file.absoluteFilePath());
- }
- }
-}
-
-void checkNahimic(const env::Environment& e)
-{
- for (auto&& m : e.loadedModules()) {
- const QFileInfo file(m.path());
-
- if (file.fileName().compare("NahimicOSD.dll", Qt::CaseInsensitive) == 0) {
- log::warn(
- "NahimicOSD.dll is loaded. Nahimic is known to cause issues with "
- "Mod Organizer, such as freezing or blank windows. Consider "
- "uninstalling it.");
-
- break;
- }
- }
-}
-
-void sanityChecks(const env::Environment& e)
-{
- checkMissingFiles();
- checkNahimic(e);
-}
-
int runApplication(MOApplication &application, SingleInstance &instance,
const QString &splashPath)
diff --git a/src/sanitychecks.cpp b/src/sanitychecks.cpp
new file mode 100644
index 00000000..5f9705b8
--- /dev/null
+++ b/src/sanitychecks.cpp
@@ -0,0 +1,174 @@
+#include "env.h"
+#include "envmodule.h"
+#include
+
+using namespace MOBase;
+
+enum class SecurityZone
+{
+ NoZone = -1,
+ MyComputer = 0,
+ Intranet = 1,
+ Trusted = 2,
+ Internet = 3,
+ Untrusted = 4,
+};
+
+QString toString(SecurityZone z)
+{
+ switch (z)
+ {
+ case SecurityZone::NoZone: return "NoZone";
+ case SecurityZone::MyComputer: return "MyComputer";
+ case SecurityZone::Intranet: return "Intranet";
+ case SecurityZone::Trusted: return "Trusted";
+ case SecurityZone::Internet: return "Internet";
+ case SecurityZone::Untrusted: return "Untrusted";
+ default: return QString("unknown (%1)").arg(static_cast(z));
+ }
+}
+
+bool isZoneBlocked(SecurityZone z)
+{
+ return (z == SecurityZone::Internet || z == SecurityZone::Untrusted);
+}
+
+bool isFileBlocked(const QFileInfo& fi)
+{
+ const QString ads = "Zone.Identifier";
+ const auto key = "ZoneTransfer/ZoneId";
+
+ const auto path = fi.absoluteFilePath();
+ const auto adsPath = path + ":" + ads;
+
+ QFile f(adsPath);
+ if (!f.exists()) {
+ return false;
+ }
+
+ log::debug("file '{}' has an ADS for {}", path, adsPath);
+
+ QSettings qs(adsPath, QSettings::IniFormat);
+
+ if (!qs.contains(key)) {
+ log::debug("but key '{}' is not found", key);
+ return false;
+ }
+
+ const auto v = qs.value(key);
+ if (v.isNull()) {
+ log::debug("but key '{}' is null", key);
+ return false;
+ }
+
+ bool ok = false;
+ const auto z = static_cast(v.toInt(&ok));
+
+ if (!ok) {
+ log::debug(
+ "but key '{}' is not an int (value is '{}')",
+ key, v);
+
+ return false;
+ }
+
+ if (!isZoneBlocked(z)) {
+ log::debug(
+ "but zone id is {}, {}, which is fine",
+ static_cast(z), toString(z));
+
+ return false;
+ }
+
+ log::warn(
+ "file '{}' is blocked (zone id is {}, {})",
+ path, static_cast(z), toString(z));
+
+ return true;
+}
+
+void checkBlockedFiles(const QDir& dir)
+{
+ if (!dir.exists()) {
+ log::error(
+ "while checking for blocked files, directory '{}' not found",
+ dir.absolutePath());
+
+ return;
+ }
+
+ const auto files = dir.entryInfoList({"*.dll", "*.exe"}, QDir::Files);
+ if (files.empty()) {
+ log::error(
+ "while checking for blocked files, directory '{}' is empty",
+ dir.absolutePath());
+
+ return;
+ }
+
+ for (auto&& fi : files) {
+ isFileBlocked(fi);
+ }
+}
+
+void checkBlocked()
+{
+ const QString appDir = QCoreApplication::applicationDirPath();
+
+ const QDir dirs[] = {
+ appDir,
+ appDir + "/dlls",
+ appDir + "/loot",
+ appDir + "/NCC",
+ appDir + "/platforms",
+ appDir + "/plugins"
+ };
+
+ for (const auto& d : dirs) {
+ checkBlockedFiles(d);
+ }
+}
+
+void checkMissingFiles()
+{
+ // files that are likely to be eaten
+ static const QStringList files({
+ "helper.exe", "nxmhandler.exe",
+ "usvfs_proxy_x64.exe", "usvfs_proxy_x86.exe",
+ "usvfs_x64.dll", "usvfs_x86.dll"
+ });
+
+ const auto dir = QCoreApplication::applicationDirPath();
+
+ for (const auto& name : files) {
+ const QFileInfo file(dir + QDir::separator() + name);
+ if (!file.exists()) {
+ log::warn(
+ "'{}' seems to be missing, an antivirus may have deleted it",
+ file.absoluteFilePath());
+ }
+ }
+}
+
+void checkNahimic(const env::Environment& e)
+{
+ for (auto&& m : e.loadedModules()) {
+ const QFileInfo file(m.path());
+
+ if (file.fileName().compare("NahimicOSD.dll", Qt::CaseInsensitive) == 0) {
+ log::warn(
+ "NahimicOSD.dll is loaded. Nahimic is known to cause issues with "
+ "Mod Organizer, such as freezing or blank windows. Consider "
+ "uninstalling it.");
+
+ break;
+ }
+ }
+}
+
+void sanityChecks(const env::Environment& e)
+{
+ checkBlocked();
+ checkMissingFiles();
+ checkNahimic(e);
+}
--
cgit v1.3.1
From 1dc39621998457ab09765520f6cce4e266eaa8db Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 5 Oct 2019 07:03:41 -0400
Subject: changed some of blocked files logging
---
src/sanitychecks.cpp | 39 ++++++++++++++++++++-------------------
1 file changed, 20 insertions(+), 19 deletions(-)
(limited to 'src')
diff --git a/src/sanitychecks.cpp b/src/sanitychecks.cpp
index 5f9705b8..185b1f9c 100644
--- a/src/sanitychecks.cpp
+++ b/src/sanitychecks.cpp
@@ -14,7 +14,7 @@ enum class SecurityZone
Untrusted = 4,
};
-QString toString(SecurityZone z)
+QString toCodeName(SecurityZone z)
{
switch (z)
{
@@ -24,10 +24,17 @@ QString toString(SecurityZone z)
case SecurityZone::Trusted: return "Trusted";
case SecurityZone::Internet: return "Internet";
case SecurityZone::Untrusted: return "Untrusted";
- default: return QString("unknown (%1)").arg(static_cast(z));
+ default: return "Unknown";
}
}
+QString toString(SecurityZone z)
+{
+ return QString("%1 (%2)")
+ .arg(toCodeName(z))
+ .arg(static_cast(z));
+}
+
bool isZoneBlocked(SecurityZone z)
{
return (z == SecurityZone::Internet || z == SecurityZone::Untrusted);
@@ -46,18 +53,18 @@ bool isFileBlocked(const QFileInfo& fi)
return false;
}
- log::debug("file '{}' has an ADS for {}", path, adsPath);
+ log::debug("'{}' has an ADS for {}", path, adsPath);
- QSettings qs(adsPath, QSettings::IniFormat);
+ const QSettings qs(adsPath, QSettings::IniFormat);
if (!qs.contains(key)) {
- log::debug("but key '{}' is not found", key);
+ log::debug("'{}': key '{}' not found", adsPath, key);
return false;
}
const auto v = qs.value(key);
if (v.isNull()) {
- log::debug("but key '{}' is null", key);
+ log::debug("'{}': key '{}' is null", adsPath, key);
return false;
}
@@ -65,25 +72,16 @@ bool isFileBlocked(const QFileInfo& fi)
const auto z = static_cast(v.toInt(&ok));
if (!ok) {
- log::debug(
- "but key '{}' is not an int (value is '{}')",
- key, v);
-
+ log::debug("'{}': key '{}' is not an int (value is '{}')", adsPath, key, v);
return false;
}
if (!isZoneBlocked(z)) {
- log::debug(
- "but zone id is {}, {}, which is fine",
- static_cast(z), toString(z));
-
+ log::debug("'{}': zone id is {}, which is fine", adsPath, toString(z));
return false;
}
- log::warn(
- "file '{}' is blocked (zone id is {}, {})",
- path, static_cast(z), toString(z));
-
+ log::warn("'{}': file is blocked (zone id is {})", path, toString(z));
return true;
}
@@ -141,7 +139,8 @@ void checkMissingFiles()
const auto dir = QCoreApplication::applicationDirPath();
for (const auto& name : files) {
- const QFileInfo file(dir + QDir::separator() + name);
+ const QFileInfo file(dir + "/" + name);
+
if (!file.exists()) {
log::warn(
"'{}' seems to be missing, an antivirus may have deleted it",
@@ -168,6 +167,8 @@ void checkNahimic(const env::Environment& e)
void sanityChecks(const env::Environment& e)
{
+ log::debug("running sanity checks");
+
checkBlocked();
checkMissingFiles();
checkNahimic(e);
--
cgit v1.3.1
From 897d315359718712a8e6b160c279f563f7436367 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 5 Oct 2019 07:38:14 -0400
Subject: fixes for VS preview: missing namespace, missing setting() with two
parameters
---
src/profile.cpp | 5 +++++
src/profile.h | 7 +++++--
src/settingsutilities.h | 4 ++--
3 files changed, 12 insertions(+), 4 deletions(-)
(limited to 'src')
diff --git a/src/profile.cpp b/src/profile.cpp
index e76060b9..f2360674 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -917,6 +917,11 @@ QVariant Profile::setting(const QString §ion, const QString &name,
return m_Settings->value(section + "/" + name, fallback);
}
+QVariant Profile::setting(const QString &name, const QVariant &fallback) const
+{
+ return m_Settings->value(name, fallback);
+}
+
void Profile::storeSetting(const QString §ion, const QString &name,
const QVariant &value)
{
diff --git a/src/profile.h b/src/profile.h
index bc7964f8..85d929ac 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -313,8 +313,11 @@ public:
void dumpModStatus() const;
- QVariant setting(const QString §ion, const QString &name = QString(),
- const QVariant &fallback = QVariant()) const;
+ QVariant setting(
+ const QString §ion, const QString &name,
+ const QVariant &fallback) const;
+
+ QVariant setting(const QString &name, const QVariant &fallback={}) const;
void storeSetting(const QString §ion, const QString &name,
const QVariant &value);
diff --git a/src/settingsutilities.h b/src/settingsutilities.h
index a6737144..ac6aeb29 100644
--- a/src/settingsutilities.h
+++ b/src/settingsutilities.h
@@ -39,11 +39,11 @@ void logChange(
using VC = ValueConverter;
if (oldValue) {
- log::debug(
+ MOBase::log::debug(
"setting '{}' changed from '{}' to '{}'",
displayName, VC::convert(*oldValue), VC::convert(newValue));
} else {
- log::debug(
+ MOBase::log::debug(
"setting '{}' set to '{}'",
displayName, VC::convert(newValue));
}
--
cgit v1.3.1
From 1467cb9955776c0e7738a93eb338321aabfda456 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 5 Oct 2019 08:11:12 -0400
Subject: sanity checks: comments, more debug logging
---
src/sanitychecks.cpp | 131 +++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 106 insertions(+), 25 deletions(-)
(limited to 'src')
diff --git a/src/sanitychecks.cpp b/src/sanitychecks.cpp
index 185b1f9c..3b4185a7 100644
--- a/src/sanitychecks.cpp
+++ b/src/sanitychecks.cpp
@@ -24,7 +24,7 @@ QString toCodeName(SecurityZone z)
case SecurityZone::Trusted: return "Trusted";
case SecurityZone::Internet: return "Internet";
case SecurityZone::Untrusted: return "Untrusted";
- default: return "Unknown";
+ default: return "Unknown zone";
}
}
@@ -35,21 +35,42 @@ QString toString(SecurityZone z)
.arg(static_cast(z));
}
+// whether the given zone is considered blocked
+//
bool isZoneBlocked(SecurityZone z)
{
- return (z == SecurityZone::Internet || z == SecurityZone::Untrusted);
+ switch (z)
+ {
+ case SecurityZone::Internet:
+ case SecurityZone::Untrusted:
+ return true;
+
+ case SecurityZone::NoZone:
+ case SecurityZone::MyComputer:
+ case SecurityZone::Intranet:
+ case SecurityZone::Trusted:
+ default:
+ return false;
+ }
}
+// whether the given file is blocked
+//
bool isFileBlocked(const QFileInfo& fi)
{
+ // name of the alternate data stream containing the zone identifier ini
const QString ads = "Zone.Identifier";
+
+ // key in the ini
const auto key = "ZoneTransfer/ZoneId";
+ // the path to the ADS is always `filename:Zone.Identifier`
const auto path = fi.absoluteFilePath();
const auto adsPath = path + ":" + ads;
QFile f(adsPath);
if (!f.exists()) {
+ // no ADS for this file
return false;
}
@@ -57,17 +78,20 @@ bool isFileBlocked(const QFileInfo& fi)
const QSettings qs(adsPath, QSettings::IniFormat);
+ // looking for key
if (!qs.contains(key)) {
log::debug("'{}': key '{}' not found", adsPath, key);
return false;
}
+ // getting value
const auto v = qs.value(key);
if (v.isNull()) {
log::debug("'{}': key '{}' is null", adsPath, key);
return false;
}
+ // should be an int
bool ok = false;
const auto z = static_cast(v.toInt(&ok));
@@ -77,57 +101,79 @@ bool isFileBlocked(const QFileInfo& fi)
}
if (!isZoneBlocked(z)) {
+ // that zone is not a blocked zone
log::debug("'{}': zone id is {}, which is fine", adsPath, toString(z));
return false;
}
- log::warn("'{}': file is blocked (zone id is {})", path, toString(z));
+ // file is blocked
+ log::warn("'{}': file is blocked, zone id is {}", path, toString(z));
return true;
}
-void checkBlockedFiles(const QDir& dir)
+int checkBlockedFiles(const QDir& dir)
{
+ // executables file types
+ const QStringList FileTypes = {"*.dll", "*.exe"};
+
if (!dir.exists()) {
+ // shouldn't happen
log::error(
"while checking for blocked files, directory '{}' not found",
dir.absolutePath());
- return;
+ return 1;
}
- const auto files = dir.entryInfoList({"*.dll", "*.exe"}, QDir::Files);
+ const auto files = dir.entryInfoList(FileTypes, QDir::Files);
if (files.empty()) {
+ // shouldn't happen
log::error(
"while checking for blocked files, directory '{}' is empty",
dir.absolutePath());
- return;
+ return 1;
}
+ int n = 0;
+
+ // checking each file in this directory
for (auto&& fi : files) {
- isFileBlocked(fi);
+ if (isFileBlocked(fi)) {
+ ++n;
+ }
}
+
+ return n;
}
-void checkBlocked()
+int checkBlocked()
{
+ // directories that contain executables; these need to be explicit because
+ // portable instances might add billions of files in MO's directory
+ const QString dirs[] = {
+ ".",
+ "/dlls",
+ "/loot",
+ "/NCC",
+ "/platforms",
+ "/plugins"
+ };
+
+ log::debug(" . blocked files");
const QString appDir = QCoreApplication::applicationDirPath();
- const QDir dirs[] = {
- appDir,
- appDir + "/dlls",
- appDir + "/loot",
- appDir + "/NCC",
- appDir + "/platforms",
- appDir + "/plugins"
- };
+ int n = 0;
for (const auto& d : dirs) {
- checkBlockedFiles(d);
+ const auto path = QDir(appDir + "/" + d).canonicalPath();
+ n += checkBlockedFiles(path);
}
+
+ return n;
}
-void checkMissingFiles()
+int checkMissingFiles()
{
// files that are likely to be eaten
static const QStringList files({
@@ -136,8 +182,11 @@ void checkMissingFiles()
"usvfs_x64.dll", "usvfs_x86.dll"
});
+ log::debug(" . missing files");
const auto dir = QCoreApplication::applicationDirPath();
+ int n = 0;
+
for (const auto& name : files) {
const QFileInfo file(dir + "/" + name);
@@ -145,12 +194,23 @@ void checkMissingFiles()
log::warn(
"'{}' seems to be missing, an antivirus may have deleted it",
file.absoluteFilePath());
+
+ ++n;
}
}
+
+ return n;
}
-void checkNahimic(const env::Environment& e)
+bool checkNahimic(const env::Environment& e)
{
+ // 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
+ //
+ // 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
+
for (auto&& m : e.loadedModules()) {
const QFileInfo file(m.path());
@@ -160,16 +220,37 @@ void checkNahimic(const env::Environment& e)
"Mod Organizer, such as freezing or blank windows. Consider "
"uninstalling it.");
- break;
+ return true;
}
}
+
+ return false;
+}
+
+int checkIncompatibilities(const env::Environment& e)
+{
+ log::debug(" . incompatibilities");
+
+ int n = 0;
+
+ if (checkNahimic(e)) {
+ ++n;
+ }
+
+ return n;
}
void sanityChecks(const env::Environment& e)
{
- log::debug("running sanity checks");
+ log::debug("running sanity checks...");
+
+ int n = 0;
+
+ n += checkBlocked();
+ n += checkMissingFiles();
+ n += checkIncompatibilities(e);
- checkBlocked();
- checkMissingFiles();
- checkNahimic(e);
+ log::debug(
+ "sanity checks done, {}",
+ (n > 0 ? "problems were found" : "everything looks okay"));
}
--
cgit v1.3.1
From 93423f63512f7d7e6d21bc8e75fc1a17bdba28aa Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 5 Oct 2019 08:21:59 -0400
Subject: don't log "(no guid"), happens all the time for the windows firewall
---
src/envsecurity.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/envsecurity.cpp b/src/envsecurity.cpp
index ffb17c42..786291c6 100644
--- a/src/envsecurity.cpp
+++ b/src/envsecurity.cpp
@@ -206,9 +206,10 @@ QString SecurityProduct::toString() const
s += ", definitions outdated";
}
- if (m_guid.isNull()) {
- s += ", (no guid)";
- } else {
+ // all products have a guid, but the windows firewall is not actually a real
+ // one from wmi, it's queried independently in getWindowsFirewall() and has a
+ // null guid, so just don't log it
+ if (!m_guid.isNull()) {
s += ", " + m_guid.toString(QUuid::QUuid::WithoutBraces);
}
--
cgit v1.3.1