diff --git a/src/Util.h b/src/Util.h index 1f186ef59..9bbd60d8b 100644 --- a/src/Util.h +++ b/src/Util.h @@ -6,3 +6,4 @@ #include "Utils/GameSetting.h" #include "Utils/Serialize.h" #include "Utils/UI.h" +#include "Utils/WinApi.h" diff --git a/src/Utils/Format.cpp b/src/Utils/Format.cpp index 12e9f0bf1..875b0e2af 100644 --- a/src/Utils/Format.cpp +++ b/src/Utils/Format.cpp @@ -25,6 +25,7 @@ namespace Util } return result; } + std::string DefinesToString(const std::vector& defines) { std::string result; diff --git a/src/Utils/WinApi.cpp b/src/Utils/WinApi.cpp new file mode 100644 index 000000000..cef816e21 --- /dev/null +++ b/src/Utils/WinApi.cpp @@ -0,0 +1,30 @@ +#include "WinApi.h" + +namespace Util +{ + std::optional GetDllVersion(const std::wstring& dllPath) + { + DWORD handle = 0; + DWORD size = GetFileVersionInfoSize(dllPath.c_str(), &handle); + if (size == 0) { + return std::nullopt; + } + + std::vector buffer(size); + if (!GetFileVersionInfo(dllPath.c_str(), handle, size, buffer.data())) { + return std::nullopt; + } + + VS_FIXEDFILEINFO* fileInfo = nullptr; + UINT fileInfoSize = 0; + if (!VerQueryValue(buffer.data(), L"\\", reinterpret_cast(&fileInfo), &fileInfoSize)) { + return std::nullopt; + } + + if (fileInfoSize == sizeof(VS_FIXEDFILEINFO)) { + return REL::Version(HIWORD(fileInfo->dwFileVersionMS), LOWORD(fileInfo->dwFileVersionMS), HIWORD(fileInfo->dwFileVersionLS), LOWORD(fileInfo->dwFileVersionLS)); + } + + return std::nullopt; + } +} // namespace Util diff --git a/src/Utils/WinApi.h b/src/Utils/WinApi.h new file mode 100644 index 000000000..cf048b3d3 --- /dev/null +++ b/src/Utils/WinApi.h @@ -0,0 +1,6 @@ +#pragma once + +namespace Util +{ + std::optional GetDllVersion(const std::wstring& dllPath); +} // namespace Util diff --git a/src/XSEPlugin.cpp b/src/XSEPlugin.cpp index 255a3f893..78bc9c4d1 100644 --- a/src/XSEPlugin.cpp +++ b/src/XSEPlugin.cpp @@ -154,6 +154,11 @@ bool Load() REL::IDDatabase::get().IsVRAddressLibraryAtLeastVersion("0.158.0", true); } + auto privateProfileRedirectorVersion = Util::GetDllVersion(L"Data/SKSE/Plugins/PrivateProfileRedirector.dll"); + if (privateProfileRedirectorVersion.has_value() && privateProfileRedirectorVersion.value().compare(REL::Version(0, 6, 2)) == std::strong_ordering::less) { + stl::report_and_fail("Old version of PrivateProfileRedirector detected, 0.6.2+ required if using it."sv); + } + auto messaging = SKSE::GetMessagingInterface(); messaging->RegisterListener("SKSE", MessageHandler);