Skip to content

Commit

Permalink
Remove std::call_once and extract lambdas to their own funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
wopss committed Dec 14, 2024
1 parent acce244 commit b0aed16
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 72 deletions.
127 changes: 55 additions & 72 deletions include/RED4ext/Relocation-inl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,62 +44,52 @@ uintptr_t RED4ext::UniversalRelocBase::Resolve(uint32_t aHash)

RED4EXT_INLINE HMODULE RED4ext::UniversalRelocBase::GetRED4extModule()
{
static HMODULE handle{nullptr};

static std::once_flag flag;
std::call_once(flag,
[]()
{
constexpr auto moduleName = L"RED4ext.dll";

handle = GetModuleHandleW(moduleName);
if (!handle)
{
auto msg =
L"The mod you are using could not locate the necessary module (i.e. RED4ext.dll) in the "
L"loaded modules, which is required by the mod to resolve addresses correctly.\n"
L"This may occur if RED4ext is not properly loaded into the current process.\n"
L"\n"
L"Please ensure that RED4ext is correctly installed.\n"
L"\n"
L"If you are the mod's developer, verify that your mod was loaded by RED4ext. "
L"Alternatively, you may need to provide your own address resolver.";

ShowErrorAndTerminateProcess(msg, GetLastError());
}
});
constexpr auto moduleName = L"RED4ext.dll";

auto handle = GetModuleHandleW(moduleName);
if (!handle)
{
auto msg = L"The mod you are using could not locate the necessary module (i.e. RED4ext.dll) in the "
L"loaded modules, which is required by the mod to resolve addresses correctly.\n"
L"This may occur if RED4ext is not properly loaded into the current process.\n"
L"\n"
L"Please ensure that RED4ext is correctly installed.\n"
L"\n"
L"If you are the mod's developer, verify that your mod was loaded by RED4ext. "
L"Alternatively, you may need to provide your own address resolver.";

ShowErrorAndTerminateProcess(msg, GetLastError());
}

return handle;
}

RED4EXT_INLINE RED4ext::UniversalRelocBase::ResolveFunc_t RED4ext::UniversalRelocBase::GetAddressResolverFunction()
RED4EXT_INLINE RED4ext::UniversalRelocBase::ResolveFunc_t RED4ext::UniversalRelocBase::
InitializeAddressResolverFunction()
{
static ResolveFunc_t func{nullptr};
constexpr auto procName = "RED4ext_ResolveAddress";

static std::once_flag flag;
std::call_once(
flag,
[]()
{
constexpr auto procName = "RED4ext_ResolveAddress";
auto handle = GetRED4extModule();

auto handle = GetRED4extModule();
auto func = reinterpret_cast<ResolveFunc_t>(GetProcAddress(handle, procName));
if (func == nullptr)
{
auto msg = L"The mod you are using is unable to find the required address resolver function from RED4ext.\n"
L"This may occur if RED4ext is not properly loaded, OR if the mod is incompatible with the current "
L"version of RED4ext.\n"
L"\n"
L"Please ensure that RED4ext is correctly installed AND that both RED4ext and the mod are "
L"up-to-date.";

ShowErrorAndTerminateProcess(msg, GetLastError());
}

func = reinterpret_cast<ResolveFunc_t>(GetProcAddress(handle, procName));
if (func == nullptr)
{
auto msg =
L"The mod you are using is unable to find the required address resolver function from RED4ext.\n"
L"This may occur if RED4ext is not properly loaded, OR if the mod is incompatible with the current "
L"version of RED4ext.\n"
L"\n"
L"Please ensure that RED4ext is correctly installed AND that both RED4ext and the mod are "
L"up-to-date.";

ShowErrorAndTerminateProcess(msg, GetLastError());
}
});
return func;
}

RED4EXT_INLINE RED4ext::UniversalRelocBase::ResolveFunc_t RED4ext::UniversalRelocBase::GetAddressResolverFunction()
{
static const ResolveFunc_t func = InitializeAddressResolverFunction();
return func;
}

Expand Down Expand Up @@ -155,29 +145,22 @@ RED4EXT_INLINE std::filesystem::path RED4ext::UniversalRelocBase::GetCurrentModu

RED4EXT_INLINE RED4ext::UniversalRelocBase::QueryFunc_t RED4ext::UniversalRelocBase::GetCurrentPluginQueryFunction()
{
static QueryFunc_t func{nullptr};

static std::once_flag flag;
std::call_once(flag,
[]()
{
constexpr auto procName = "Query";

auto handle = GetCurrentModuleHandle();

func = reinterpret_cast<QueryFunc_t>(GetProcAddress(handle, procName));
if (func == nullptr)
{
auto msg = L"Could not get the 'Query' function for the current mod.\n"
L"Normally, this issue should not happen.\n"
L"\n"
L"If you are the mod's developer, verify that your mod was loaded by RED4ext and "
L"that it exports the 'Query' function needed for the mod to interact with "
L"RED4ext. Alternatively, you may need to provide your own address resolver.";

ShowErrorAndTerminateProcess(msg, GetLastError(), false);
}
});
constexpr auto procName = "Query";

auto handle = GetCurrentModuleHandle();

auto func = reinterpret_cast<QueryFunc_t>(GetProcAddress(handle, procName));
if (func == nullptr)
{
auto msg = L"Could not get the 'Query' function for the current mod.\n"
L"Normally, this issue should not happen.\n"
L"\n"
L"If you are the mod's developer, verify that your mod was loaded by RED4ext and "
L"that it exports the 'Query' function needed for the mod to interact with "
L"RED4ext. Alternatively, you may need to provide your own address resolver.";

ShowErrorAndTerminateProcess(msg, GetLastError(), false);
}

return func;
}
Expand Down Expand Up @@ -209,7 +192,7 @@ RED4EXT_INLINE void RED4ext::UniversalRelocBase::ShowErrorAndTerminateProcess(st
auto path = GetCurrentModulePath();

std::wstring title = path.stem();
std::wstring version = L"QUERY WAS DISABLED";
std::wstring version = L"Not available (Query was intentionally disabled)";

if (aQueryPluginInfo)
{
Expand All @@ -227,7 +210,7 @@ RED4EXT_INLINE void RED4ext::UniversalRelocBase::ShowErrorAndTerminateProcess(st
}
else
{
version = L"QUERY FAILED";
version = L"Not available (Query failed)";
}
}

Expand Down
2 changes: 2 additions & 0 deletions include/RED4ext/Relocation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class UniversalRelocBase
using ResolveFunc_t = std::uintptr_t (*)(std::uint32_t);

static HMODULE GetRED4extModule();

static ResolveFunc_t InitializeAddressResolverFunction();
static ResolveFunc_t GetAddressResolverFunction();

static HMODULE GetCurrentModuleHandle();
Expand Down

0 comments on commit b0aed16

Please sign in to comment.