From 1e40a930a91a8775ec8a4f11a6154e904f7e0d2d Mon Sep 17 00:00:00 2001
From: Aireil <33433913+Aireil@users.noreply.github.com>
Date: Wed, 17 Aug 2022 22:13:31 +0200
Subject: [PATCH 1/4] fix: plugin config deletion context menu (#955)
---
.../PluginInstaller/PluginInstallerWindow.cs | 4 ++--
Dalamud/Plugin/Internal/PluginManager.cs | 14 +++++++++-----
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
index b658d3304..003c26105 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
@@ -2631,9 +2631,9 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
public static string PluginContext_HidePlugin => Loc.Localize("InstallerHidePlugin", "Hide from installer");
- public static string PluginContext_DeletePluginConfig => Loc.Localize("InstallerDeletePluginConfig", "Reset plugin");
+ public static string PluginContext_DeletePluginConfig => Loc.Localize("InstallerDeletePluginConfig", "Reset plugin configuration");
- public static string PluginContext_DeletePluginConfigReload => Loc.Localize("InstallerDeletePluginConfigReload", "Reset plugin settings & reload");
+ public static string PluginContext_DeletePluginConfigReload => Loc.Localize("InstallerDeletePluginConfigReload", "Reset plugin configuration and reload");
#endregion
diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index 8051cc081..2634cbd30 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -1128,17 +1128,18 @@ internal partial class PluginManager : IDisposable, IServiceType
}
///
- /// Unload the plugin, delete its configuration, and reload it.
+ /// Delete the plugin configuration, unload/reload it if loaded.
///
/// The plugin.
/// Throws if the plugin is still loading/unloading.
/// The task.
public async Task DeleteConfigurationAsync(LocalPlugin plugin)
{
- if (plugin.State == PluginState.Loading || plugin.State == PluginState.Unloaded)
+ if (plugin.State is PluginState.Loading or PluginState.Unloading)
throw new Exception("Cannot delete configuration for a loading/unloading plugin");
- if (plugin.IsLoaded)
+ var isReloading = plugin.IsLoaded;
+ if (isReloading)
await plugin.UnloadAsync();
for (var waitUntil = Environment.TickCount64 + 1000; Environment.TickCount64 < waitUntil;)
@@ -1154,8 +1155,11 @@ internal partial class PluginManager : IDisposable, IServiceType
}
}
- // Let's indicate "installer" here since this is supposed to be a fresh install
- await plugin.LoadAsync(PluginLoadReason.Installer);
+ if (isReloading)
+ {
+ // Let's indicate "installer" here since this is supposed to be a fresh install
+ await plugin.LoadAsync(PluginLoadReason.Installer);
+ }
}
///
From 38e3a8e7f5b7551641b80ffb32c51aac279ff6a2 Mon Sep 17 00:00:00 2001
From: Chivalrik <77893938+fitzchivalrik@users.noreply.github.com>
Date: Wed, 17 Aug 2022 22:17:59 +0200
Subject: [PATCH 2/4] fix: Change GamepadState interface version for
consistency (#880)
Co-authored-by: goat
---
Dalamud/Game/ClientState/GamePad/GamepadState.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dalamud/Game/ClientState/GamePad/GamepadState.cs b/Dalamud/Game/ClientState/GamePad/GamepadState.cs
index 597818975..bd4cadbc8 100644
--- a/Dalamud/Game/ClientState/GamePad/GamepadState.cs
+++ b/Dalamud/Game/ClientState/GamePad/GamepadState.cs
@@ -14,7 +14,7 @@ namespace Dalamud.Game.ClientState.GamePad
/// Will block game's gamepad input if is set.
///
[PluginInterface]
- [InterfaceVersion("1.0.0")]
+ [InterfaceVersion("1.0")]
[ServiceManager.BlockingEarlyLoadedService]
public unsafe class GamepadState : IDisposable, IServiceType
{
From e9147387c7862fdb488aef743302564549e402d4 Mon Sep 17 00:00:00 2001
From: kizer
Date: Thu, 18 Aug 2022 15:47:38 +0900
Subject: [PATCH 3/4] Fix error message on import hook fail (#957)
---
Dalamud.Boot/utils.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dalamud.Boot/utils.cpp b/Dalamud.Boot/utils.cpp
index e06e812ef..b487f398b 100644
--- a/Dalamud.Boot/utils.cpp
+++ b/Dalamud.Boot/utils.cpp
@@ -140,7 +140,7 @@ void* utils::loaded_module::get_imported_function_pointer(const char* pcszDllNam
if (void* ppImportTableItem{}; find_imported_function_pointer(pcszDllName, pcszFunctionName, hintOrOrdinal, ppImportTableItem))
return ppImportTableItem;
- throw std::runtime_error("Failed to find import for kernel32!OpenProcess.");
+ throw std::runtime_error(std::format("Failed to find import for {}!{} ({}).", pcszDllName, pcszFunctionName ? pcszFunctionName : "", hintOrOrdinal));
}
utils::loaded_module utils::loaded_module::current_process() {
From 1f1f0aaa20fb0e0f56fff5ba422ceb12b2aeba14 Mon Sep 17 00:00:00 2001
From: kizer
Date: Fri, 19 Aug 2022 04:20:45 +0900
Subject: [PATCH 4/4] Show DLL description and version into xivfixes dll load
list (#958)
---
Dalamud.Boot/hooks.cpp | 19 ++++++++-
Dalamud.Boot/utils.cpp | 83 +++++++++++++++++++++++++++++++++++++++
Dalamud.Boot/utils.h | 6 +++
Dalamud.Boot/xivfixes.cpp | 15 ++++++-
4 files changed, 120 insertions(+), 3 deletions(-)
diff --git a/Dalamud.Boot/hooks.cpp b/Dalamud.Boot/hooks.cpp
index 2619ffa72..7cf489195 100644
--- a/Dalamud.Boot/hooks.cpp
+++ b/Dalamud.Boot/hooks.cpp
@@ -103,8 +103,23 @@ void hooks::getprocaddress_singleton_import_hook::initialize() {
LdrRegisterDllNotification(0, [](ULONG notiReason, const LDR_DLL_NOTIFICATION_DATA* pData, void* context) {
if (notiReason == LDR_DLL_NOTIFICATION_REASON_LOADED) {
const auto dllName = unicode::convert(pData->Loaded.FullDllName->Buffer);
- logging::I(R"({} "{}" has been loaded at 0x{:X} ~ 0x{:X} (0x{:X}); finding import table items to hook.)",
- LogTag, dllName,
+
+ utils::loaded_module mod(pData->Loaded.DllBase);
+ std::wstring version, description;
+ try {
+ version = utils::format_file_version(mod.get_file_version());
+ } catch (...) {
+ version = L"";
+ }
+
+ try {
+ description = mod.get_description();
+ } catch (...) {
+ description = L"";
+ }
+
+ logging::I(R"({} "{}" ("{}" ver {}) has been loaded at 0x{:X} ~ 0x{:X} (0x{:X}); finding import table items to hook.)",
+ LogTag, dllName, description, version,
reinterpret_cast(pData->Loaded.DllBase),
reinterpret_cast(pData->Loaded.DllBase) + pData->Loaded.SizeOfImage,
pData->Loaded.SizeOfImage);
diff --git a/Dalamud.Boot/utils.cpp b/Dalamud.Boot/utils.cpp
index b487f398b..62b436aa2 100644
--- a/Dalamud.Boot/utils.cpp
+++ b/Dalamud.Boot/utils.cpp
@@ -143,6 +143,69 @@ void* utils::loaded_module::get_imported_function_pointer(const char* pcszDllNam
throw std::runtime_error(std::format("Failed to find import for {}!{} ({}).", pcszDllName, pcszFunctionName ? pcszFunctionName : "", hintOrOrdinal));
}
+std::unique_ptr, decltype(&FreeResource)> utils::loaded_module::get_resource(LPCWSTR lpName, LPCWSTR lpType) const {
+ const auto hres = FindResourceW(m_hModule, lpName, lpType);
+ if (!hres)
+ throw std::runtime_error("No such resource");
+
+ const auto hRes = LoadResource(m_hModule, hres);
+ if (!hRes)
+ throw std::runtime_error("LoadResource failure");
+
+ return {hRes, &FreeResource};
+}
+
+std::wstring utils::loaded_module::get_description() const {
+ const auto rsrc = get_resource(MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
+ const auto pBlock = LockResource(rsrc.get());
+
+ struct LANGANDCODEPAGE {
+ WORD wLanguage;
+ WORD wCodePage;
+ } * lpTranslate;
+ UINT cbTranslate;
+ if (!VerQueryValueW(pBlock,
+ TEXT("\\VarFileInfo\\Translation"),
+ reinterpret_cast(&lpTranslate),
+ &cbTranslate)) {
+ throw std::runtime_error("Invalid version information (1)");
+ }
+
+ for (size_t i = 0; i < (cbTranslate / sizeof(LANGANDCODEPAGE)); i++) {
+ wchar_t* buf = nullptr;
+ UINT size = 0;
+ if (!VerQueryValueW(pBlock,
+ std::format(L"\\StringFileInfo\\{:04x}{:04x}\\FileDescription",
+ lpTranslate[i].wLanguage,
+ lpTranslate[i].wCodePage).c_str(),
+ reinterpret_cast(&buf),
+ &size)) {
+ continue;
+ }
+ auto currName = std::wstring_view(buf, size);
+ while (!currName.empty() && currName.back() == L'\0')
+ currName = currName.substr(0, currName.size() - 1);
+ if (currName.empty())
+ continue;
+ return std::wstring(currName);
+ }
+
+ throw std::runtime_error("Invalid version information (2)");
+}
+
+VS_FIXEDFILEINFO utils::loaded_module::get_file_version() const {
+ const auto rsrc = get_resource(MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
+ const auto pBlock = LockResource(rsrc.get());
+ UINT size = 0;
+ LPVOID lpBuffer = nullptr;
+ if (!VerQueryValueW(pBlock, L"\\", &lpBuffer, &size))
+ throw std::runtime_error("Failed to query version information.");
+ const VS_FIXEDFILEINFO& versionInfo = *static_cast(lpBuffer);
+ if (versionInfo.dwSignature != 0xfeef04bd)
+ throw std::runtime_error("Invalid version info found.");
+ return versionInfo;
+}
+
utils::loaded_module utils::loaded_module::current_process() {
return { GetModuleHandleW(nullptr) };
}
@@ -163,6 +226,26 @@ std::vector utils::loaded_module::all_modules() {
return modules;
}
+std::wstring utils::format_file_version(const VS_FIXEDFILEINFO& v) {
+ if (v.dwFileVersionMS == v.dwProductVersionMS && v.dwFileVersionLS == v.dwProductVersionLS) {
+ return std::format(L"{}.{}.{}.{}",
+ (v.dwProductVersionMS >> 16) & 0xFFFF,
+ (v.dwProductVersionMS >> 0) & 0xFFFF,
+ (v.dwProductVersionLS >> 16) & 0xFFFF,
+ (v.dwProductVersionLS >> 0) & 0xFFFF);
+ } else {
+ return std::format(L"file={}.{}.{}.{} prod={}.{}.{}.{}",
+ (v.dwFileVersionMS >> 16) & 0xFFFF,
+ (v.dwFileVersionMS >> 0) & 0xFFFF,
+ (v.dwFileVersionLS >> 16) & 0xFFFF,
+ (v.dwFileVersionLS >> 0) & 0xFFFF,
+ (v.dwProductVersionMS >> 16) & 0xFFFF,
+ (v.dwProductVersionMS >> 0) & 0xFFFF,
+ (v.dwProductVersionLS >> 16) & 0xFFFF,
+ (v.dwProductVersionLS >> 0) & 0xFFFF);
+ }
+}
+
utils::signature_finder& utils::signature_finder::look_in(const void* pFirst, size_t length) {
if (length)
m_ranges.emplace_back(std::span(reinterpret_cast(pFirst), length));
diff --git a/Dalamud.Boot/utils.h b/Dalamud.Boot/utils.h
index ca350674a..1e29493b7 100644
--- a/Dalamud.Boot/utils.h
+++ b/Dalamud.Boot/utils.h
@@ -58,10 +58,16 @@ namespace utils {
void* get_imported_function_pointer(const char* pcszDllName, const char* pcszFunctionName, uint32_t hintOrOrdinal) const;
template TFn** get_imported_function_pointer(const char* pcszDllName, const char* pcszFunctionName, uint32_t hintOrOrdinal) { return reinterpret_cast(get_imported_function_pointer(pcszDllName, pcszFunctionName, hintOrOrdinal)); }
+ [[nodiscard]] std::unique_ptr, decltype(&FreeResource)> get_resource(LPCWSTR lpName, LPCWSTR lpType) const;
+ [[nodiscard]] std::wstring get_description() const;
+ [[nodiscard]] VS_FIXEDFILEINFO get_file_version() const;
+
static loaded_module current_process();
static std::vector all_modules();
};
+ std::wstring format_file_version(const VS_FIXEDFILEINFO& v);
+
class signature_finder {
std::vector> m_ranges;
std::vector m_patterns;
diff --git a/Dalamud.Boot/xivfixes.cpp b/Dalamud.Boot/xivfixes.cpp
index 338938fc1..c5cde28d3 100644
--- a/Dalamud.Boot/xivfixes.cpp
+++ b/Dalamud.Boot/xivfixes.cpp
@@ -26,7 +26,20 @@ void xivfixes::unhook_dll(bool bApply) {
std::filesystem::path path;
try {
path = mod.path();
- logging::I("{} [{}/{}] Module 0x{:X} ~ 0x{:X} (0x{:X}): \"{}\"", LogTagW, i + 1, mods.size(), mod.address_int(), mod.address_int() + mod.image_size(), mod.image_size(), path.wstring());
+ std::wstring version, description;
+ try {
+ version = utils::format_file_version(mod.get_file_version());
+ } catch (...) {
+ version = L"";
+ }
+
+ try {
+ description = mod.get_description();
+ } catch (...) {
+ description = L"";
+ }
+
+ logging::I(R"({} [{}/{}] Module 0x{:X} ~ 0x{:X} (0x{:X}): "{}" ("{}" ver {}))", LogTagW, i + 1, mods.size(), mod.address_int(), mod.address_int() + mod.image_size(), mod.image_size(), path.wstring(), description, version);
} catch (const std::exception& e) {
logging::W("{} [{}/{}] Module 0x{:X}: Failed to resolve path: {}", LogTag, i + 1, mods.size(), mod.address_int(), e.what());
return;