wine support

closes #80 #97
This commit is contained in:
m 2024-01-20 21:03:11 -06:00
parent 4df8505c04
commit f9af95be10
7 changed files with 78 additions and 17 deletions

View File

@ -32,20 +32,34 @@ namespace resources
public: public:
~component() ~component()
{ {
if (utils::nt::is_wine())
{
return;
}
if (icon) DestroyIcon(icon); if (icon) DestroyIcon(icon);
if (splash) DeleteObject(splash); if (splash) DeleteObject(splash);
} }
void post_start() override void post_start() override
{ {
const utils::nt::library self; if (utils::nt::is_wine())
{
return;
}
const utils::nt::library self;
icon = LoadIconA(self.get_handle(), MAKEINTRESOURCEA(ID_ICON)); icon = LoadIconA(self.get_handle(), MAKEINTRESOURCEA(ID_ICON));
splash = LoadImageA(self.get_handle(), MAKEINTRESOURCEA(IMAGE_SPLASH), 0, 0, 0, LR_COPYFROMRESOURCE); splash = LoadImageA(self.get_handle(), MAKEINTRESOURCEA(IMAGE_SPLASH), 0, 0, 0, LR_COPYFROMRESOURCE);
} }
void* load_import(const std::string& library, const std::string& function) override void* load_import(const std::string& library, const std::string& function) override
{ {
if (utils::nt::is_wine())
{
return nullptr;
}
if (library == "USER32.dll") if (library == "USER32.dll")
{ {
if (function == "LoadIconA") if (function == "LoadIconA")

View File

@ -13,13 +13,18 @@ namespace splash
public: public:
void post_start() override void post_start() override
{ {
if (utils::nt::is_wine())
{
return;
}
const utils::nt::library self; const utils::nt::library self;
image_ = LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); image_ = LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
} }
void post_load() override void post_load() override
{ {
if (game::environment::is_dedi()) if (utils::nt::is_wine() || game::environment::is_dedi())
{ {
return; return;
} }
@ -31,12 +36,20 @@ namespace splash
{ {
// Disable native splash screen // Disable native splash screen
utils::hook::set<uint8_t>(0xD58240_b, 0xC3); utils::hook::set<uint8_t>(0xD58240_b, 0xC3);
utils::hook::jump(0xD584F0_b, destroy_stub, true); if (!utils::nt::is_wine())
utils::hook::jump(0xD58530_b, destroy_stub, true); {
utils::hook::jump(0xD584F0_b, destroy_stub, true);
utils::hook::jump(0xD58530_b, destroy_stub, true);
}
} }
void pre_destroy() override void pre_destroy() override
{ {
if (utils::nt::is_wine() || game::environment::is_dedi())
{
return;
}
this->destroy(); this->destroy();
MSG msg; MSG msg;

View File

@ -40,6 +40,12 @@ namespace steam_proxy
error, error,
}; };
bool is_disabled()
{
static const auto disabled = utils::flags::has_flag("nosteam");
return disabled;
}
void* load_client_engine() void* load_client_engine()
{ {
if (!steam_client_module_) return nullptr; if (!steam_client_module_) return nullptr;
@ -175,13 +181,18 @@ namespace steam_proxy
public: public:
void post_load() override void post_load() override
{ {
if (game::environment::is_dedi() || is_disabled() || !FindWindowA(0, "Steam"))
{
return;
}
load_client(); load_client();
perform_cleanup_if_needed(); perform_cleanup_if_needed();
} }
void post_unpack() override void post_unpack() override
{ {
if (game::environment::is_dedi()) if (game::environment::is_dedi() || is_disabled() || !FindWindowA(0, "Steam"))
{ {
return; return;
} }

View File

@ -4,8 +4,9 @@
#include "game/game.hpp" #include "game/game.hpp"
#include <utils/io.hpp>
#include <utils/cryptography.hpp> #include <utils/cryptography.hpp>
#include <utils/io.hpp>
#include <utils/nt.hpp>
namespace system_check namespace system_check
{ {
@ -66,9 +67,12 @@ namespace system_check
void verify_binary_version() void verify_binary_version()
{ {
const auto value = *reinterpret_cast<DWORD*>(0x1337_b); const auto value = *reinterpret_cast<DWORD*>(0x1337_b);
if (value != 0xB43C9275) if (!utils::nt::is_wine())
{ {
throw std::runtime_error("Unsupported Call of Duty: Infinite Warfare version"); if (value != 0xB43C9275)
{
throw std::runtime_error("Unsupported Call of Duty: Infinite Warfare version");
}
} }
} }
} }

View File

@ -115,8 +115,8 @@ namespace steam
bool SteamAPI_Init() bool SteamAPI_Init()
{ {
const std::filesystem::path steam_path = SteamAPI_GetSteamInstallPath(); const std::filesystem::path steam_path = steam::SteamAPI_GetSteamInstallPath();
if (steam_path.empty()) return false; if (steam_path.empty()) return true; // h1-mod has this as true, is this right?
::utils::nt::library::load(steam_path / "tier0_s64.dll"); ::utils::nt::library::load(steam_path / "tier0_s64.dll");
::utils::nt::library::load(steam_path / "vstdlib_s64.dll"); ::utils::nt::library::load(steam_path / "vstdlib_s64.dll");
@ -165,17 +165,23 @@ namespace steam
return install_path.data(); return install_path.data();
} }
char path[MAX_PATH] = {0};
DWORD length = sizeof(path);
std::string path_str;
if (::utils::io::read_file("steam_path.txt", &path_str)) // steam_path.txt in root for directory
{
install_path = path_str;
return install_path.data();
}
// check if Steam contains information in registry for the install path
HKEY reg_key; HKEY reg_key;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\WOW6432Node\\Valve\\Steam", 0, KEY_QUERY_VALUE, if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\WOW6432Node\\Valve\\Steam", 0, KEY_QUERY_VALUE,
&reg_key) == &reg_key) == ERROR_SUCCESS)
ERROR_SUCCESS)
{ {
char path[MAX_PATH] = {0}; RegQueryValueExA(reg_key, "InstallPath", nullptr, nullptr, reinterpret_cast<BYTE*>(path), &length);
DWORD length = sizeof(path);
RegQueryValueExA(reg_key, "InstallPath", nullptr, nullptr, reinterpret_cast<BYTE*>(path),
&length);
RegCloseKey(reg_key); RegCloseKey(reg_key);
install_path = path; install_path = path;
} }

View File

@ -213,6 +213,17 @@ namespace utils::nt
return nullptr; return nullptr;
} }
bool is_wine()
{
static const auto has_wine_export = []() -> bool
{
const library ntdll("ntdll.dll");
return ntdll.get_proc<void*>("wine_get_version");
}();
return has_wine_export;
}
bool is_shutdown_in_progress() bool is_shutdown_in_progress()
{ {
static auto* shutdown_in_progress = [] static auto* shutdown_in_progress = []

View File

@ -165,6 +165,8 @@ namespace utils::nt
HANDLE handle_{ InvalidHandle }; HANDLE handle_{ InvalidHandle };
}; };
bool is_wine();
bool is_shutdown_in_progress(); bool is_shutdown_in_progress();
__declspec(noreturn) void raise_hard_exception(); __declspec(noreturn) void raise_hard_exception();