d2tweaks-rnd2k/include/common/ptr_wrapper.h
2024-04-16 21:45:38 -06:00

184 lines
4.9 KiB
C++

#pragma once
#include <cstdint>
#include <Windows.h>
namespace details {
template<typename TRet, typename... Args>
class wrap_func_cdecl_ {
void* m_function_ptr;
public:
explicit wrap_func_cdecl_(uintptr_t ptr, void* base) {
m_function_ptr = static_cast<char*>(base) + ptr;
}
TRet operator()(Args... args) {
return reinterpret_cast<TRet(__cdecl*)(Args...)>(m_function_ptr)(args...);
}
};
template<typename TRet, typename... Args>
class wrap_func_std_ {
void* m_function_ptr;
public:
explicit wrap_func_std_(uintptr_t ptr, void* base) {
m_function_ptr = static_cast<char*>(base) + ptr;
}
TRet operator()(Args... args) {
return reinterpret_cast<TRet(__stdcall*)(Args...)>(m_function_ptr)(args...);
}
};
template<typename TRet, typename... Args>
class wrap_func_cdecl_import_ {
void* m_base;
void* m_function_ptr;
uint32_t m_ordinal;
public:
explicit wrap_func_cdecl_import_(uint32_t ordinal, void* base) {
m_base = base;
m_function_ptr = nullptr;
m_ordinal = ordinal;
}
TRet operator()(Args... args) {
if (!m_function_ptr) {
m_function_ptr = reinterpret_cast<decltype(m_function_ptr)>(GetProcAddress(reinterpret_cast<HMODULE>(m_base),
reinterpret_cast<LPCSTR>(m_ordinal)));
}
return reinterpret_cast<TRet(__cdecl*)(Args...)>(m_function_ptr)(args...);
}
};
template<typename TRet, typename... Args>
class wrap_func_std_import_ {
void* m_base;
void* m_function_ptr;
uint32_t m_ordinal;
public:
explicit wrap_func_std_import_(uint32_t ordinal, void* base) {
m_base = base;
m_function_ptr = nullptr;
m_ordinal = ordinal;
}
TRet operator()(Args... args) {
if (!m_function_ptr) {
m_function_ptr = reinterpret_cast<decltype(m_function_ptr)>(GetProcAddress(reinterpret_cast<HMODULE>(m_base),
reinterpret_cast<LPCSTR>(m_ordinal)));
}
return reinterpret_cast<TRet(__stdcall*)(Args...)>(m_function_ptr)(args...);
}
};
template<typename TRet, typename... Args>
class wrap_func_fast_import_ {
void* m_base;
void* m_function_ptr;
uint32_t m_ordinal;
public:
explicit wrap_func_fast_import_(uint32_t ordinal, void* base) {
m_base = base;
m_function_ptr = nullptr;
m_ordinal = ordinal;
}
TRet operator()(Args... args) {
if (!m_function_ptr) {
m_function_ptr = reinterpret_cast<decltype(m_function_ptr)>(GetProcAddress(reinterpret_cast<HMODULE>(m_base),
reinterpret_cast<LPCSTR>(m_ordinal)));
}
return reinterpret_cast<TRet(__fastcall*)(Args...)>(m_function_ptr)(args...);
}
};
template<typename TRet, typename... Args>
class wrap_func_fast_ {
void* m_function_ptr;
public:
explicit wrap_func_fast_(uintptr_t ptr, void* base) {
m_function_ptr = static_cast<char*>(base) + ptr;
}
TRet operator()(Args... args) {
return reinterpret_cast<TRet(__fastcall*)(Args...)>(m_function_ptr)(args...);
}
};
}
template<typename TRet>
class wrap_func_cdecl {};
template<typename TRet, typename... Args>
class wrap_func_cdecl<TRet(Args...)> : public details::wrap_func_cdecl_<TRet, Args...> {
public:
wrap_func_cdecl(uintptr_t ptr, void* base) : wrap_func_cdecl_(ptr, base) {};
};
template<typename TRet>
class wrap_func_cdecl_import {};
template<typename TRet, typename... Args>
class wrap_func_cdecl_import<TRet(Args...)> : public details::wrap_func_cdecl_import_<TRet, Args...> {
public:
wrap_func_cdecl_import(uint32_t ordinal, void* base) : wrap_func_cdecl_import_(ordinal, base) {};
};
template<typename TRet>
class wrap_func_std {};
template<typename TRet, typename... Args>
class wrap_func_std<TRet(Args...)> : public details::wrap_func_std_<TRet, Args...> {
public:
wrap_func_std(uintptr_t ptr, void* base) : wrap_func_std_(ptr, base) {};
};
template<typename TRet>
class wrap_func_std_import {};
template<typename TRet, typename... Args>
class wrap_func_std_import<TRet(Args...)> : public details::wrap_func_std_import_<TRet, Args...> {
public:
wrap_func_std_import(uint32_t ordinal, void* base) : wrap_func_std_import_(ordinal, base) {};
};
template<typename TRet>
class wrap_func_fast_import {};
template<typename TRet, typename... Args>
class wrap_func_fast_import<TRet(Args...)> : public details::wrap_func_fast_import_<TRet, Args...> {
public:
wrap_func_fast_import(uint32_t ordinal, void* base) : wrap_func_fast_import_(ordinal, base) {};
};
template<typename TRet>
class wrap_func_fast {};
template<typename TRet, typename... Args>
class wrap_func_fast<TRet(Args...)> : public details::wrap_func_fast_<TRet, Args...> {
public:
wrap_func_fast(uintptr_t ptr, void* base) : wrap_func_fast_(ptr, base) {};
};
template<typename TType>
class wrap_value {
TType* m_value;
public:
wrap_value(uintptr_t ptr, void* base) {
// Fuck off, I'm gonna cast it in C-style because of templates
// ReSharper disable once CppCStyleCast
m_value = (TType*)(static_cast<char*>(base) + ptr);
}
operator void* () const {
return m_value;
}
operator TType* () const {
return m_value;
}
};