mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 21:01:37 +00:00
Implemented Windows registry read/write
This commit is contained in:
parent
7b9b4245de
commit
ef8d099309
12 changed files with 232 additions and 1 deletions
|
|
@ -179,6 +179,7 @@ set(UNLEASHED_RECOMP_USER_CXX_SOURCES
|
||||||
"user/achievement_data.cpp"
|
"user/achievement_data.cpp"
|
||||||
"user/achievement_manager.cpp"
|
"user/achievement_manager.cpp"
|
||||||
"user/config.cpp"
|
"user/config.cpp"
|
||||||
|
"user/registry.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(UNLEASHED_RECOMP_MOD_CXX_SOURCES
|
set(UNLEASHED_RECOMP_MOD_CXX_SOURCES
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <ui/game_window.h>
|
#include <ui/game_window.h>
|
||||||
#include <user/config.h>
|
#include <user/config.h>
|
||||||
#include <user/paths.h>
|
#include <user/paths.h>
|
||||||
|
#include <user/registry.h>
|
||||||
|
|
||||||
void App::Restart(std::vector<std::string> restartArgs)
|
void App::Restart(std::vector<std::string> restartArgs)
|
||||||
{
|
{
|
||||||
|
|
@ -18,6 +19,7 @@ void App::Restart(std::vector<std::string> restartArgs)
|
||||||
void App::Exit()
|
void App::Exit()
|
||||||
{
|
{
|
||||||
Config::Save();
|
Config::Save();
|
||||||
|
Registry::Save();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
timeEndPeriod(1);
|
timeEndPeriod(1);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
typedef returnType _##procName(__VA_ARGS__); \
|
typedef returnType _##procName(__VA_ARGS__); \
|
||||||
_##procName* procName = (_##procName*)PROC_ADDRESS(libraryName, #procName);
|
_##procName* procName = (_##procName*)PROC_ADDRESS(libraryName, #procName);
|
||||||
|
|
||||||
|
#define STR(x) #x
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T RoundUp(const T& in_rValue, uint32_t in_round)
|
inline T RoundUp(const T& in_rValue, uint32_t in_round)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@
|
||||||
#include <hid/hid.h>
|
#include <hid/hid.h>
|
||||||
#include <user/config.h>
|
#include <user/config.h>
|
||||||
#include <user/paths.h>
|
#include <user/paths.h>
|
||||||
|
#include <user/registry.h>
|
||||||
#include <kernel/xdbf.h>
|
#include <kernel/xdbf.h>
|
||||||
#include <install/installer.h>
|
#include <install/installer.h>
|
||||||
#include <os/logger.h>
|
#include <os/logger.h>
|
||||||
|
#include <os/process.h>
|
||||||
#include <ui/installer_wizard.h>
|
#include <ui/installer_wizard.h>
|
||||||
#include <mod/mod_loader.h>
|
#include <mod/mod_loader.h>
|
||||||
|
|
||||||
|
|
@ -165,6 +167,13 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::Load();
|
Config::Load();
|
||||||
|
Registry::Load();
|
||||||
|
|
||||||
|
if (!Registry::RootDirectoryPath.empty())
|
||||||
|
{
|
||||||
|
if (!os::process::SetWorkingDirectory(std::filesystem::path(Registry::RootDirectoryPath)))
|
||||||
|
LOGFN_ERROR("Failed to set working directory: \"{}\"", Registry::RootDirectoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
HostStartup();
|
HostStartup();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,12 @@ std::filesystem::path os::process::GetWorkingDirectory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
bool os::process::SetWorkingDirectory(const std::filesystem::path& path)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work)
|
bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work)
|
||||||
{
|
{
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
|
|
|
||||||
15
UnleashedRecomp/os/linux/registry_linux.inl
Normal file
15
UnleashedRecomp/os/linux/registry_linux.inl
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include <os/registry.h>
|
||||||
|
|
||||||
|
// TODO: read from file?
|
||||||
|
template<typename T>
|
||||||
|
bool os::registry::ReadValue(const std::filesystem::path& path, const std::string& name, T& data)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: write to file?
|
||||||
|
template<typename T>
|
||||||
|
bool os::registry::WriteValue(const std::filesystem::path& path, const std::string& name, const T& data)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
@ -4,5 +4,6 @@ namespace os::process
|
||||||
{
|
{
|
||||||
std::filesystem::path GetExecutablePath();
|
std::filesystem::path GetExecutablePath();
|
||||||
std::filesystem::path GetWorkingDirectory();
|
std::filesystem::path GetWorkingDirectory();
|
||||||
|
bool SetWorkingDirectory(const std::filesystem::path& path);
|
||||||
bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {});
|
bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
UnleashedRecomp/os/registry.h
Normal file
16
UnleashedRecomp/os/registry.h
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace os::registry
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
bool ReadValue(const std::filesystem::path& path, const std::string& name, T& data);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool WriteValue(const std::filesystem::path& path, const std::string& name, const T& data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#include <os/win32/registry_win32.inl>
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#include <os/linux/registry_linux.inl>
|
||||||
|
#endif
|
||||||
|
|
@ -20,6 +20,11 @@ std::filesystem::path os::process::GetWorkingDirectory()
|
||||||
return std::filesystem::path(workPath);
|
return std::filesystem::path(workPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool os::process::SetWorkingDirectory(const std::filesystem::path& path)
|
||||||
|
{
|
||||||
|
return SetCurrentDirectoryW(path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work)
|
bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work)
|
||||||
{
|
{
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
|
|
|
||||||
142
UnleashedRecomp/os/win32/registry_win32.inl
Normal file
142
UnleashedRecomp/os/win32/registry_win32.inl
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
#include <os/registry.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, HKEY> g_rootKeys =
|
||||||
|
{
|
||||||
|
{ "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT },
|
||||||
|
{ "HKEY_CURRENT_USER", HKEY_CURRENT_USER },
|
||||||
|
{ "HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE },
|
||||||
|
{ "HKEY_USERS", HKEY_USERS },
|
||||||
|
{ "HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG }
|
||||||
|
};
|
||||||
|
|
||||||
|
static HKEY ParseRootKey(const std::string& name)
|
||||||
|
{
|
||||||
|
auto it = g_rootKeys.find(name);
|
||||||
|
|
||||||
|
if (it == g_rootKeys.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool os::registry::ReadValue(const std::filesystem::path& path, const std::string& name, T& data)
|
||||||
|
{
|
||||||
|
auto pathStr = path.string();
|
||||||
|
auto pathSeparator = pathStr.find('\\');
|
||||||
|
|
||||||
|
if (pathSeparator == std::string::npos)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto rootKey = pathStr.substr(0, pathSeparator);
|
||||||
|
auto subKey = pathStr.substr(pathSeparator + 1);
|
||||||
|
|
||||||
|
HKEY hRootKey = ParseRootKey(rootKey);
|
||||||
|
|
||||||
|
if (!hRootKey)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
if (RegOpenKeyExA(hRootKey, subKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BYTE buffer[512];
|
||||||
|
DWORD bufferSize = sizeof(buffer);
|
||||||
|
DWORD dataType = 0;
|
||||||
|
|
||||||
|
auto result = RegQueryValueExA(hKey, name.c_str(), NULL, &dataType, buffer, &bufferSize);
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
if (result != ERROR_SUCCESS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, std::string>)
|
||||||
|
{
|
||||||
|
if (dataType != REG_SZ)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
data = std::string((char*)buffer, bufferSize - 1);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, uint32_t>)
|
||||||
|
{
|
||||||
|
if (dataType != REG_DWORD)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
data = *(uint32_t*)buffer;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, uint64_t>)
|
||||||
|
{
|
||||||
|
if (dataType != REG_QWORD)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
data = *(uint32_t*)buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_assert(false, "Unsupported data type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool os::registry::WriteValue(const std::filesystem::path& path, const std::string& name, const T& data)
|
||||||
|
{
|
||||||
|
auto pathStr = path.string();
|
||||||
|
auto pathSeparator = pathStr.find('\\');
|
||||||
|
|
||||||
|
if (pathSeparator == std::string::npos)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto rootKey = pathStr.substr(0, pathSeparator);
|
||||||
|
auto subKey = pathStr.substr(pathSeparator + 1);
|
||||||
|
|
||||||
|
HKEY hRootKey = ParseRootKey(rootKey);
|
||||||
|
|
||||||
|
if (!hRootKey)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
if (RegCreateKeyExA(hRootKey, subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BYTE* pData = nullptr;
|
||||||
|
DWORD dataSize = 0;
|
||||||
|
DWORD dataType = 0;
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, std::string>)
|
||||||
|
{
|
||||||
|
pData = (BYTE*)data.c_str();
|
||||||
|
dataSize = data.size() + 1;
|
||||||
|
dataType = REG_SZ;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, uint32_t>)
|
||||||
|
{
|
||||||
|
pData = &data;
|
||||||
|
dataSize = sizeof(T);
|
||||||
|
dataType = REG_DWORD;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, uint64_t>)
|
||||||
|
{
|
||||||
|
pData = &data;
|
||||||
|
dataSize = sizeof(T);
|
||||||
|
dataType = REG_QWORD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_assert(false, "Unsupported data type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = RegSetValueExA(hKey, name.c_str(), 0, dataType, (const BYTE*)pData, dataSize);
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
if (result != ERROR_SUCCESS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
21
UnleashedRecomp/user/registry.cpp
Normal file
21
UnleashedRecomp/user/registry.cpp
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "registry.h"
|
||||||
|
#include <os/process.h>
|
||||||
|
#include <os/registry.h>
|
||||||
|
#include <user/config.h>
|
||||||
|
|
||||||
|
void Registry::Load()
|
||||||
|
{
|
||||||
|
std::filesystem::path path = "HKEY_CURRENT_USER\\Software\\UnleashedRecomp";
|
||||||
|
|
||||||
|
os::registry::ReadValue(path, STR(ExecutableFilePath), ExecutableFilePath);
|
||||||
|
os::registry::ReadValue(path, STR(RootDirectoryPath), RootDirectoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Registry::Save()
|
||||||
|
{
|
||||||
|
std::filesystem::path path = "HKEY_CURRENT_USER\\Software\\UnleashedRecomp";
|
||||||
|
|
||||||
|
ExecutableFilePath = os::process::GetExecutablePath().string();
|
||||||
|
|
||||||
|
os::registry::WriteValue(path, STR(ExecutableFilePath), ExecutableFilePath);
|
||||||
|
}
|
||||||
11
UnleashedRecomp/user/registry.h
Normal file
11
UnleashedRecomp/user/registry.h
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Registry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline static std::string ExecutableFilePath;
|
||||||
|
inline static std::string RootDirectoryPath;
|
||||||
|
|
||||||
|
static void Load();
|
||||||
|
static void Save();
|
||||||
|
};
|
||||||
Loading…
Add table
Reference in a new issue