diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-10-05 08:33:01 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-05 08:33:01 -0400 |
| commit | 4921d2a0dd1726e48b520e341e10b775be0174ce (patch) | |
| tree | 13806af16ad83f80bc7aa740ac8df7c275e9c478 /src | |
| parent | 8aa298b606900d62cdd01f5c762a334799625763 (diff) | |
| parent | 93423f63512f7d7e6d21bc8e75fc1a17bdba28aa (diff) | |
Merge pull request #850 from isanae/blocked-files
Blocked files
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/envsecurity.cpp | 7 | ||||
| -rw-r--r-- | src/main.cpp | 46 | ||||
| -rw-r--r-- | src/profile.cpp | 5 | ||||
| -rw-r--r-- | src/profile.h | 7 | ||||
| -rw-r--r-- | src/sanitychecks.cpp | 256 | ||||
| -rw-r--r-- | src/settingsutilities.h | 4 |
7 files changed, 277 insertions, 50 deletions
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/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); } 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 <http://www.gnu.org/licenses/>. 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/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/sanitychecks.cpp b/src/sanitychecks.cpp new file mode 100644 index 00000000..3b4185a7 --- /dev/null +++ b/src/sanitychecks.cpp @@ -0,0 +1,256 @@ +#include "env.h" +#include "envmodule.h" +#include <log.h> + +using namespace MOBase; + +enum class SecurityZone +{ + NoZone = -1, + MyComputer = 0, + Intranet = 1, + Trusted = 2, + Internet = 3, + Untrusted = 4, +}; + +QString toCodeName(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 "Unknown zone"; + } +} + +QString toString(SecurityZone z) +{ + return QString("%1 (%2)") + .arg(toCodeName(z)) + .arg(static_cast<int>(z)); +} + +// whether the given zone is considered blocked +// +bool isZoneBlocked(SecurityZone z) +{ + 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; + } + + log::debug("'{}' has an ADS for {}", path, adsPath); + + 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<SecurityZone>(v.toInt(&ok)); + + if (!ok) { + log::debug("'{}': key '{}' is not an int (value is '{}')", adsPath, key, v); + return false; + } + + if (!isZoneBlocked(z)) { + // that zone is not a blocked zone + log::debug("'{}': zone id is {}, which is fine", adsPath, toString(z)); + return false; + } + + // file is blocked + log::warn("'{}': file is blocked, zone id is {}", path, toString(z)); + return true; +} + +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 1; + } + + 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 1; + } + + int n = 0; + + // checking each file in this directory + for (auto&& fi : files) { + if (isFileBlocked(fi)) { + ++n; + } + } + + return n; +} + +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(); + + int n = 0; + + for (const auto& d : dirs) { + const auto path = QDir(appDir + "/" + d).canonicalPath(); + n += checkBlockedFiles(path); + } + + return n; +} + +int 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" + }); + + log::debug(" . missing files"); + const auto dir = QCoreApplication::applicationDirPath(); + + int n = 0; + + for (const auto& name : files) { + const QFileInfo file(dir + "/" + name); + + if (!file.exists()) { + log::warn( + "'{}' seems to be missing, an antivirus may have deleted it", + file.absoluteFilePath()); + + ++n; + } + } + + return n; +} + +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()); + + 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."); + + 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..."); + + int n = 0; + + n += checkBlocked(); + n += checkMissingFiles(); + n += checkIncompatibilities(e); + + log::debug( + "sanity checks done, {}", + (n > 0 ? "problems were found" : "everything looks okay")); +} 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<T>; 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)); } |
