100 lines
2.7 KiB
C++
100 lines
2.7 KiB
C++
#include "rem/version_guard.h"
|
|
|
|
#include <windows.h>
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
#include "rem/log.h"
|
|
#include "rem/runtime.h"
|
|
|
|
namespace
|
|
{
|
|
constexpr std::uint16_t FreelancerV10Build = 1223;
|
|
|
|
bool ReadProductBuild(const char* moduleName, std::uint16_t& build)
|
|
{
|
|
HMODULE module = GetModuleHandleA(moduleName);
|
|
if (!module)
|
|
module = LoadLibraryA(moduleName);
|
|
|
|
if (!module)
|
|
{
|
|
rem::log::ModuleMissing("version_guard", moduleName);
|
|
return false;
|
|
}
|
|
|
|
char path[MAX_PATH]{};
|
|
if (GetModuleFileNameA(module, path, MAX_PATH) == 0)
|
|
return false;
|
|
|
|
DWORD ignored = 0;
|
|
const DWORD infoSize = GetFileVersionInfoSizeA(path, &ignored);
|
|
if (infoSize == 0)
|
|
return false;
|
|
|
|
std::vector<BYTE> info(infoSize);
|
|
if (!GetFileVersionInfoA(path, 0, infoSize, info.data()))
|
|
return false;
|
|
|
|
VS_FIXEDFILEINFO* fixedInfo = nullptr;
|
|
UINT fixedInfoSize = 0;
|
|
if (!VerQueryValueA(info.data(), "\\", reinterpret_cast<void**>(&fixedInfo), &fixedInfoSize)
|
|
|| !fixedInfo
|
|
|| fixedInfoSize < sizeof(VS_FIXEDFILEINFO)
|
|
|| fixedInfo->dwSignature != 0xFEEF04BD)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
build = HIWORD(fixedInfo->dwProductVersionLS);
|
|
return true;
|
|
}
|
|
|
|
bool CheckModule(const char* moduleName)
|
|
{
|
|
std::uint16_t build = 0;
|
|
if (!ReadProductBuild(moduleName, build))
|
|
{
|
|
char message[256]{};
|
|
sprintf_s(message, "could not verify the product version of %s", moduleName);
|
|
rem::log::Error(message);
|
|
return false;
|
|
}
|
|
|
|
if (build <= FreelancerV10Build)
|
|
{
|
|
char message[256]{};
|
|
sprintf_s(message, "%s build %u is unsupported; Freelancer 1.1 is required", moduleName, build);
|
|
rem::log::Error(message);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
namespace rem
|
|
{
|
|
bool IsSupportedGameVersion()
|
|
{
|
|
const bool commonSupported = CheckModule("common.dll");
|
|
const bool serverSupported = CheckModule("server.dll");
|
|
if (commonSupported && serverSupported)
|
|
return true;
|
|
|
|
log::Error("initialization stopped because the Freelancer 1.1 module check failed");
|
|
if (IsClient())
|
|
{
|
|
MessageBoxA(
|
|
nullptr,
|
|
"rem-essentials requires the official Freelancer 1.1 modules.\n"
|
|
"No memory patches were applied.",
|
|
"REM Essentials",
|
|
MB_OK | MB_ICONERROR);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|