244 lines
6.1 KiB
C++
244 lines
6.1 KiB
C++
#include "Steam.h"
|
|
#include <windows.h>
|
|
#include <tlhelp32.h>
|
|
#include <cstdio>
|
|
#include "../../Menu/Menu.h"
|
|
|
|
|
|
// 嵌入的 Steam 覆盖层文件数据(定义在各 .h 中)
|
|
extern unsigned int gameoverlayui_exe_len;
|
|
extern unsigned char gameoverlayui_exe[];
|
|
extern unsigned int gameoverlayui64_exe_len;
|
|
extern unsigned char gameoverlayui64_exe[];
|
|
extern unsigned int GameOverlayRenderer_dll_len;
|
|
extern unsigned char GameOverlayRenderer_dll[];
|
|
extern unsigned int GameOverlayRenderer64_dll_len;
|
|
extern unsigned char GameOverlayRenderer64_dll[];
|
|
|
|
// 单例
|
|
Steam* Steam::Get()
|
|
{
|
|
static Steam instance;
|
|
return &instance;
|
|
}
|
|
|
|
Steam::Steam() = default;
|
|
Steam::~Steam() = default;
|
|
|
|
const std::string& Steam::GetSteamPath() const {
|
|
// 每次调用都从注册表查询 Steam 安装路径
|
|
HKEY hKey;
|
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Valve\\Steam", 0, KEY_READ | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS) {
|
|
char path[MAX_PATH];
|
|
DWORD size = sizeof(path);
|
|
if (RegQueryValueExA(hKey, "InstallPath", nullptr, nullptr,
|
|
reinterpret_cast<BYTE*>(path), &size) == ERROR_SUCCESS)
|
|
{
|
|
m_SteamPath = path;
|
|
RegCloseKey(hKey);
|
|
printf("[Steam] > install path: %s\n", m_SteamPath.c_str());
|
|
return m_SteamPath;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
// 回退:当前用户注册表
|
|
if (RegOpenKeyExA(HKEY_CURRENT_USER,
|
|
"SOFTWARE\\Valve\\Steam", 0,
|
|
KEY_READ | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
char path[MAX_PATH];
|
|
DWORD size = sizeof(path);
|
|
if (RegQueryValueExA(hKey, "SteamPath", nullptr, nullptr,
|
|
reinterpret_cast<BYTE*>(path), &size) == ERROR_SUCCESS)
|
|
{
|
|
m_SteamPath = path;
|
|
RegCloseKey(hKey);
|
|
printf("[Steam] > install path: %s\n", m_SteamPath.c_str());
|
|
return m_SteamPath;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
m_SteamPath.clear();
|
|
printf("[Steam] > warn: could not find steam install path\n");
|
|
return m_SteamPath;
|
|
}
|
|
|
|
bool Steam::IsProcessRunning(const wchar_t* exeName) const {
|
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
if (hSnapshot == INVALID_HANDLE_VALUE)
|
|
return false;
|
|
|
|
PROCESSENTRY32W pe32;
|
|
pe32.dwSize = sizeof(pe32);
|
|
|
|
bool found = false;
|
|
if (Process32FirstW(hSnapshot, &pe32))
|
|
{
|
|
do
|
|
{
|
|
if (_wcsicmp(pe32.szExeFile, exeName) == 0)
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
} while (Process32NextW(hSnapshot, &pe32));
|
|
}
|
|
|
|
CloseHandle(hSnapshot);
|
|
return found;
|
|
}
|
|
|
|
bool Steam::TerminateProcessByName(const wchar_t* exeName) const {
|
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
if (hSnapshot == INVALID_HANDLE_VALUE)
|
|
return false;
|
|
|
|
PROCESSENTRY32W pe32;
|
|
pe32.dwSize = sizeof(pe32);
|
|
|
|
bool killed = false;
|
|
if (Process32FirstW(hSnapshot, &pe32))
|
|
{
|
|
do
|
|
{
|
|
if (_wcsicmp(pe32.szExeFile, exeName) == 0)
|
|
{
|
|
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
|
|
if (hProcess)
|
|
{
|
|
TerminateProcess(hProcess, 0);
|
|
CloseHandle(hProcess);
|
|
killed = true;
|
|
}
|
|
}
|
|
} while (Process32NextW(hSnapshot, &pe32));
|
|
}
|
|
|
|
CloseHandle(hSnapshot);
|
|
return killed;
|
|
}
|
|
|
|
bool Steam::IsSteamRunning() {
|
|
return IsProcessRunning(L"steam.exe");
|
|
}
|
|
|
|
bool Steam::StartSteam() {
|
|
const std::string& steamPath = GetSteamPath();
|
|
if (steamPath.empty())
|
|
{
|
|
printf("[Steam] > err: steam path unknown, cannot start\n");
|
|
return false;
|
|
}
|
|
|
|
std::string exePath = steamPath + "\\steam.exe";
|
|
|
|
HINSTANCE result = ShellExecuteA(
|
|
nullptr, "open", exePath.c_str(), nullptr, nullptr, SW_SHOW
|
|
);
|
|
|
|
if (reinterpret_cast<INT_PTR>(result) > 32)
|
|
{
|
|
printf("[Steam] > started: %s\n", exePath.c_str());
|
|
return true;
|
|
}
|
|
|
|
printf("[Steam] > err: failed to start (code %d)\n",
|
|
static_cast<int>(reinterpret_cast<INT_PTR>(result)));
|
|
return false;
|
|
}
|
|
|
|
bool Steam::KillSteam() {
|
|
auto Log = Menu::Get();
|
|
if (!IsSteamRunning())
|
|
{
|
|
printf("[Steam] > steam not running\n");
|
|
Log->AddLog("[Steam] > steam not running");
|
|
return false;
|
|
}
|
|
|
|
if (TerminateProcessByName(L"steam.exe"))
|
|
{
|
|
printf("[Steam] > steam killed\n");
|
|
Log->AddLog("[Steam] > steam killed");
|
|
return true;
|
|
}
|
|
|
|
printf("[Steam] > err: failed to kill steam\n");
|
|
Log->AddLog("[Steam] > err: failed to kill steam");
|
|
return false;
|
|
}
|
|
|
|
// ─── 写入嵌入文件到磁盘的辅助函数 ────────────────────────────
|
|
|
|
static bool WriteEmbeddedFile(const std::string& dir, const char* name, const file& f)
|
|
{
|
|
std::string fullPath = dir + "\\" + name;
|
|
|
|
HANDLE hFile = CreateFileA(
|
|
fullPath.c_str(),
|
|
GENERIC_WRITE,
|
|
0,
|
|
nullptr,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
nullptr
|
|
);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
printf("[Steam] > err: cannot create file %s (0x%lx)\n", fullPath.c_str(), GetLastError());
|
|
return false;
|
|
}
|
|
|
|
DWORD written = 0;
|
|
const BOOL ok = WriteFile(hFile, f.file, f.len, &written, nullptr);
|
|
CloseHandle(hFile);
|
|
|
|
if (!ok || written != f.len)
|
|
{
|
|
printf("[Steam] > err: write failed for %s (wrote %lu/%u)\n", fullPath.c_str(), written, f.len);
|
|
return false;
|
|
}
|
|
|
|
printf("[Steam] > replaced: %s (%u bytes)\n", fullPath.c_str(), f.len);
|
|
return true;
|
|
}
|
|
|
|
// ─── 替换 Steam 覆盖层文件 ──────────────────────────────────
|
|
|
|
bool Steam::ReplaceOverlayFiles()
|
|
{
|
|
auto Log = Menu::Get();
|
|
const std::string& steamPath = GetSteamPath();
|
|
if (steamPath.empty())
|
|
{
|
|
printf("[Steam] > err: steam path unknown, cannot replace overlay files\n");
|
|
Log->AddLog("[Steam] > err: steam path unknown, cannot replace overlay files");
|
|
return false;
|
|
}
|
|
|
|
printf("[Steam] > replacing overlay files in: %s\n", steamPath.c_str());
|
|
|
|
bool allOk = true;
|
|
|
|
allOk &= WriteEmbeddedFile(steamPath, "gameoverlayui.exe", gameoverlayui());
|
|
allOk &= WriteEmbeddedFile(steamPath, "GameOverlayRenderer.dll", GameOverlayRenderer());
|
|
allOk &= WriteEmbeddedFile(steamPath, "gameoverlayui64.exe", gameoverlayui64());
|
|
allOk &= WriteEmbeddedFile(steamPath, "GameOverlayRenderer64.dll", GameOverlayRenderer64());
|
|
|
|
if (allOk) {
|
|
printf("[Steam] > all overlay files replaced successfully\n");
|
|
Log->AddLog("[Steam] > all overlay files replaced successfully");
|
|
}
|
|
else {
|
|
printf("[Steam] > warn: some overlay files failed to replace\n");
|
|
Log->AddLog("[Steam] > warn: some overlay files failed to replace");
|
|
}
|
|
|
|
|
|
return allOk;
|
|
}
|
|
|