diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-10-05 08:11:12 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-10-05 08:11:12 -0400 |
| commit | 1467cb9955776c0e7738a93eb338321aabfda456 (patch) | |
| tree | 8339370c24f1430b83455844e1c0a0382b337ccb /src/sanitychecks.cpp | |
| parent | 897d315359718712a8e6b160c279f563f7436367 (diff) | |
sanity checks: comments, more debug logging
Diffstat (limited to 'src/sanitychecks.cpp')
| -rw-r--r-- | src/sanitychecks.cpp | 131 |
1 files changed, 106 insertions, 25 deletions
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<int>(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<SecurityZone>(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")); } |
