Skip to content

Commit

Permalink
feat: improve WinAPI and its usage (#51)
Browse files Browse the repository at this point in the history
This is essentially a port of the work I did for the WinAPI helper in
CommonLibF4-NG, with a few minor tweaks. This also involves removing all
other windows includes and using WinAPI directly.

I'm not sure why but several files had their formatting busted from an
older commit, resulting in gigantic one liners.
  • Loading branch information
qudix authored Sep 15, 2023
1 parent 1778524 commit 29af8b5
Show file tree
Hide file tree
Showing 11 changed files with 1,976 additions and 449 deletions.
23 changes: 16 additions & 7 deletions CommonLibSF/include/REL/Relocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ namespace REL
inline void safe_write(std::uintptr_t a_dst, const void* a_src, std::size_t a_count)
{
std::uint32_t old{ 0 };
auto success = WinAPI::VirtualProtect(reinterpret_cast<void*>(a_dst), a_count, (PAGE_EXECUTE_READWRITE), std::addressof(old));
auto success = WinAPI::VirtualProtect(reinterpret_cast<void*>(a_dst), a_count, WinAPI::PAGE_EXECUTE_READWRITE, std::addressof(old));
if (success != 0) {
std::memcpy(reinterpret_cast<void*>(a_dst), a_src, a_count);
success = WinAPI::VirtualProtect(reinterpret_cast<void*>(a_dst), a_count, old, std::addressof(old));
Expand All @@ -181,7 +181,7 @@ namespace REL
inline void safe_fill(std::uintptr_t a_dst, std::uint8_t a_value, std::size_t a_count)
{
std::uint32_t old{ 0 };
auto success = WinAPI::VirtualProtect(reinterpret_cast<void*>(a_dst), a_count, (PAGE_EXECUTE_READWRITE), std::addressof(old));
auto success = WinAPI::VirtualProtect(reinterpret_cast<void*>(a_dst), a_count, WinAPI::PAGE_EXECUTE_READWRITE, std::addressof(old));
if (success != 0) {
std::fill_n(reinterpret_cast<std::uint8_t*>(a_dst), a_count, a_value);
success = WinAPI::VirtualProtect(reinterpret_cast<void*>(a_dst), a_count, old, std::addressof(old));
Expand Down Expand Up @@ -339,18 +339,18 @@ namespace REL
[[nodiscard]] inline std::optional<Version> get_file_version(stl::zwstring a_filename)
{
std::uint32_t dummy{ 0 };
std::vector<char> buf(GetFileVersionInfoSize(a_filename.data(), std::addressof(dummy)));
std::vector<char> buf(WinAPI::GetFileVersionInfoSize(a_filename.data(), std::addressof(dummy)));
if (buf.empty()) {
return std::nullopt;
}

if (!GetFileVersionInfo(a_filename.data(), 0, static_cast<std::uint32_t>(buf.size()), buf.data())) {
if (!WinAPI::GetFileVersionInfo(a_filename.data(), 0, static_cast<std::uint32_t>(buf.size()), buf.data())) {
return std::nullopt;
}

void* verBuf{ nullptr };
std::uint32_t verLen{ 0 };
if (!VerQueryValue(buf.data(), L"\\StringFileInfo\\040904B0\\ProductVersion", std::addressof(verBuf), std::addressof(verLen))) {
if (!WinAPI::VerQueryValue(buf.data(), L"\\StringFileInfo\\040904B0\\ProductVersion", std::addressof(verBuf), std::addressof(verLen))) {
return std::nullopt;
}

Expand Down Expand Up @@ -438,12 +438,21 @@ namespace REL

[[nodiscard]] static Module& get(std::string_view a_filePath = {}) noexcept
{
const auto base = AsAddress(GetModuleHandle(a_filePath.empty() ? WinAPI::GetProcPath().data() : a_filePath.data()));
const auto base = AsAddress(WinAPI::GetModuleHandle(a_filePath.empty() ? WinAPI::GetProcPath(nullptr).data() : a_filePath.data()));
return get(base);
}

private:
static constexpr std::array SEGMENTS{ std::make_pair(".text"sv, IMAGE_SCN_MEM_EXECUTE), std::make_pair(".idata"sv, static_cast<std::uint32_t>(0)), std::make_pair(".rdata"sv, static_cast<std::uint32_t>(0)), std::make_pair(".data"sv, static_cast<std::uint32_t>(0)), std::make_pair(".pdata"sv, static_cast<std::uint32_t>(0)), std::make_pair(".tls"sv, static_cast<std::uint32_t>(0)), std::make_pair(".text"sv, IMAGE_SCN_MEM_WRITE), std::make_pair(".gfids"sv, static_cast<std::uint32_t>(0)) };
static constexpr std::array SEGMENTS{
std::make_pair(".text"sv, WinAPI::IMAGE_SCN_MEM_EXECUTE),
std::make_pair(".idata"sv, static_cast<std::uint32_t>(0)),
std::make_pair(".rdata"sv, static_cast<std::uint32_t>(0)),
std::make_pair(".data"sv, static_cast<std::uint32_t>(0)),
std::make_pair(".pdata"sv, static_cast<std::uint32_t>(0)),
std::make_pair(".tls"sv, static_cast<std::uint32_t>(0)),
std::make_pair(".text"sv, WinAPI::IMAGE_SCN_MEM_WRITE),
std::make_pair(".gfids"sv, static_cast<std::uint32_t>(0))
};

std::uintptr_t _base;
std::array<Segment, Segment::total> _segments;
Expand Down
15 changes: 7 additions & 8 deletions CommonLibSF/include/SFSE/Impl/DInputAPI.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include "WinAPI.h"
#include <cstdint>

// TODO: This should probably be behind some sort of pragma that allows linking with dinput and dinput8
namespace RE::DirectInput8
Expand Down Expand Up @@ -234,8 +233,8 @@ namespace RE::DirectInput8
GUID guidInstance;
GUID guidProduct;
DWORD dwDevType;
CHAR tszInstanceName[MAX_PATH];
CHAR tszProductName[MAX_PATH];
CHAR tszInstanceName[SFSE::WinAPI::MAX_PATH];
CHAR tszProductName[SFSE::WinAPI::MAX_PATH];
GUID guidFFDriver; // DIRECTINPUT_VERSION >= 0x0500
WORD wUsagePage;
WORD wUsage;
Expand All @@ -252,7 +251,7 @@ namespace RE::DirectInput8
DWORD dwOfs;
DWORD dwType;
DWORD dwFlags;
CHAR tszName[MAX_PATH];
CHAR tszName[SFSE::WinAPI::MAX_PATH];
// #if(DIRECTINPUT_VERSION >= 0x0500)
DWORD dwFFMaxForce;
DWORD dwFFForceResolution;
Expand Down Expand Up @@ -306,7 +305,7 @@ namespace RE::DirectInput8

struct _DIDEVICEIMAGEINFOA
{
CHAR tszImagePath[MAX_PATH];
CHAR tszImagePath[SFSE::WinAPI::MAX_PATH];
DWORD dwFlags;
DWORD dwViewID;
RECT rcOverlay;
Expand Down Expand Up @@ -367,7 +366,7 @@ namespace RE::DirectInput8
DWORD dwEffType;
DWORD dwStaticParams;
DWORD dwDynamicParams;
CHAR tszName[MAX_PATH];
CHAR tszName[SFSE::WinAPI::MAX_PATH];
};

using DIEFFECTINFOA = DIEFFECTINFOA__;
Expand Down Expand Up @@ -417,7 +416,7 @@ namespace RE::DirectInput8
DWORD dwSize;
GUID GuidEffect;
LPCDIEFFECT lpDiEffect;
CHAR szFriendlyName[MAX_PATH];
CHAR szFriendlyName[SFSE::WinAPI::MAX_PATH];
};

using DIFILEEFFECT = DIFILEEFFECT__;
Expand Down Expand Up @@ -459,7 +458,7 @@ namespace RE::DirectInput8
HINSTANCE hInstString;
FILETIME ftTimeStamp;
DWORD dwCRC;
CHAR tszActionMap[MAX_PATH];
CHAR tszActionMap[SFSE::WinAPI::MAX_PATH];
};

using DIACTIONFORMATA = _DIACTIONFORMATA;
Expand Down
14 changes: 10 additions & 4 deletions CommonLibSF/include/SFSE/Impl/PCH.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,10 @@ namespace SFSE

[[nodiscard]] inline auto utf8_to_utf16(std::string_view a_in) noexcept -> std::optional<std::wstring>
{
const auto cvt = [&](wchar_t* a_dst, std::size_t a_length) { return WinAPI::MultiByteToWideChar(CP_UTF8, 0, a_in.data(), static_cast<int>(a_in.length()), a_dst, static_cast<int>(a_length)); };
const auto cvt = [&](wchar_t* a_dst, std::size_t a_length) {
return WinAPI::MultiByteToWideChar(
WinAPI::CP_UTF8, 0, a_in.data(), static_cast<int>(a_in.length()), a_dst, static_cast<int>(a_length));
};

const auto len = cvt(nullptr, 0);
if (len == 0) {
Expand All @@ -541,7 +544,10 @@ namespace SFSE

[[nodiscard]] inline auto utf16_to_utf8(std::wstring_view a_in) noexcept -> std::optional<std::string>
{
const auto cvt = [&](char* a_dst, std::size_t a_length) { return WinAPI::WideCharToMultiByte(CP_UTF8, 0, a_in.data(), static_cast<int>(a_in.length()), a_dst, static_cast<int>(a_length), nullptr, nullptr); };
const auto cvt = [&](char* a_dst, std::size_t a_length) {
return WinAPI::WideCharToMultiByte(
WinAPI::CP_UTF8, 0, a_in.data(), static_cast<int>(a_in.length()), a_dst, static_cast<int>(a_length), nullptr, nullptr);
};

const auto len = cvt(nullptr, 0);
if (len == 0) {
Expand Down Expand Up @@ -579,7 +585,7 @@ namespace SFSE
std::uint32_t result = 0;
do {
buf.resize(buf.size() * 2);
result = GetModuleFileName(WinAPI::GetCurrentModule(), buf.data(), static_cast<std::uint32_t>(buf.size()));
result = WinAPI::GetModuleFileName(WinAPI::GetCurrentModule(), buf.data(), static_cast<std::uint32_t>(buf.size()));
} while (result && result == buf.size() && buf.size() <= (std::numeric_limits<std::uint32_t>::max)());

if (result && result != buf.size()) {
Expand All @@ -593,7 +599,7 @@ namespace SFSE
spdlog::log(spdlog::source_loc{ a_loc.file_name(), static_cast<int>(a_loc.line()), a_loc.function_name() }, spdlog::level::critical, a_msg);

if (a_fail) {
MessageBox(nullptr, body.c_str(), (caption.empty() ? nullptr : caption.c_str()), 0);
WinAPI::MessageBox(nullptr, body.c_str(), (caption.empty() ? nullptr : caption.c_str()), 0);
WinAPI::TerminateProcess(WinAPI::GetCurrentProcess(), EXIT_FAILURE);
}
return true;
Expand Down
Loading

0 comments on commit 29af8b5

Please sign in to comment.