Simplify registry API and handle path writes

This commit is contained in:
Sajid 2025-01-28 14:59:41 +06:00
parent ef8d099309
commit d0509e0890
7 changed files with 51 additions and 63 deletions

View file

@ -17,6 +17,7 @@
#include <install/installer.h> #include <install/installer.h>
#include <os/logger.h> #include <os/logger.h>
#include <os/process.h> #include <os/process.h>
#include <os/registry.h>
#include <ui/installer_wizard.h> #include <ui/installer_wizard.h>
#include <mod/mod_loader.h> #include <mod/mod_loader.h>
@ -146,6 +147,9 @@ int main(int argc, char *argv[])
timeBeginPeriod(1); timeBeginPeriod(1);
#endif #endif
if (!os::registry::Init())
LOGN_WARNING("OS doesn't support registry");
os::logger::Init(); os::logger::Init();
bool forceInstaller = false; bool forceInstaller = false;

View file

@ -32,7 +32,7 @@ std::filesystem::path os::process::GetWorkingDirectory()
// TODO // TODO
bool os::process::SetWorkingDirectory(const std::filesystem::path& path) bool os::process::SetWorkingDirectory(const std::filesystem::path& path)
{ {
return false; return chdir(path.c_str()) == 0;
} }
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)

View file

@ -1,5 +1,11 @@
#include <os/registry.h> #include <os/registry.h>
// TODO: Implement
inline bool os::registry::Init()
{
return false;
}
// TODO: read from file? // TODO: read from file?
template<typename T> template<typename T>
bool os::registry::ReadValue(const std::filesystem::path& path, const std::string& name, T& data) bool os::registry::ReadValue(const std::filesystem::path& path, const std::string& name, T& data)

View file

@ -2,11 +2,13 @@
namespace os::registry namespace os::registry
{ {
template<typename T> bool Init();
bool ReadValue(const std::filesystem::path& path, const std::string& name, T& data);
template<typename T> template<typename T>
bool WriteValue(const std::filesystem::path& path, const std::string& name, const T& data); bool ReadValue(const std::string& name, T& data);
template<typename T>
bool WriteValue(const std::string& name, const T& data);
} }
#if _WIN32 #if _WIN32

View file

@ -1,45 +1,19 @@
#include <os/registry.h> #include <os/registry.h>
#include <unordered_map> #include <unordered_map>
static const std::unordered_map<std::string, HKEY> g_rootKeys = inline const wchar_t* g_registryRoot = L"Software\\UnleashedRecomp";
inline bool os::registry::Init()
{ {
{ "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT }, return true;
{ "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> template<typename T>
bool os::registry::ReadValue(const std::filesystem::path& path, const std::string& name, T& data) bool os::registry::ReadValue(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; HKEY hKey;
if (RegOpenKeyExA(hRootKey, subKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS) if (RegOpenKeyExW(HKEY_CURRENT_USER, g_registryRoot, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
return false; return false;
BYTE buffer[512]; BYTE buffer[512];
@ -83,30 +57,17 @@ bool os::registry::ReadValue(const std::filesystem::path& path, const std::strin
} }
template<typename T> template<typename T>
bool os::registry::WriteValue(const std::filesystem::path& path, const std::string& name, const T& data) bool os::registry::WriteValue(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; HKEY hKey;
if (RegCreateKeyExA(hRootKey, subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) if (RegCreateKeyExW(HKEY_CURRENT_USER, g_registryRoot, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
return false; return false;
BYTE* pData = nullptr; BYTE* pData = nullptr;
DWORD dataSize = 0; DWORD dataSize = 0;
DWORD dataType = 0; DWORD dataType = 0;
bool wideString = false;
if constexpr (std::is_same_v<T, std::string>) if constexpr (std::is_same_v<T, std::string>)
{ {
@ -126,12 +87,35 @@ bool os::registry::WriteValue(const std::filesystem::path& path, const std::stri
dataSize = sizeof(T); dataSize = sizeof(T);
dataType = REG_QWORD; dataType = REG_QWORD;
} }
else if constexpr (std::is_same_v<T, std::filesystem::path>)
{
pData = (BYTE*)data.c_str();
dataSize = (wcslen((const wchar_t*)pData) + 1) * sizeof(wchar_t);
dataType = REG_SZ;
wideString = true;
}
else else
{ {
static_assert(false, "Unsupported data type."); static_assert(false, "Unsupported data type.");
} }
auto result = RegSetValueExA(hKey, name.c_str(), 0, dataType, (const BYTE*)pData, dataSize); LSTATUS result = ERROR_INVALID_FUNCTION;
if (wideString)
{
wchar_t wideName[128];
int wideNameSize = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name.size(), wideName, sizeof(wideName));
if (wideNameSize == 0)
{
return false;
}
wideName[wideNameSize] = 0;
result = RegSetValueExW(hKey, wideName, 0, dataType, pData, dataSize);
}
else
{
result = RegSetValueExA(hKey, name.c_str(), 0, dataType, pData, dataSize);
}
RegCloseKey(hKey); RegCloseKey(hKey);

View file

@ -5,17 +5,10 @@
void Registry::Load() void Registry::Load()
{ {
std::filesystem::path path = "HKEY_CURRENT_USER\\Software\\UnleashedRecomp"; os::registry::ReadValue(STR(RootDirectoryPath), RootDirectoryPath);
os::registry::ReadValue(path, STR(ExecutableFilePath), ExecutableFilePath);
os::registry::ReadValue(path, STR(RootDirectoryPath), RootDirectoryPath);
} }
void Registry::Save() void Registry::Save()
{ {
std::filesystem::path path = "HKEY_CURRENT_USER\\Software\\UnleashedRecomp"; os::registry::WriteValue(STR(ExecutableFilePath), os::process::GetExecutablePath());
ExecutableFilePath = os::process::GetExecutablePath().string();
os::registry::WriteValue(path, STR(ExecutableFilePath), ExecutableFilePath);
} }

View file

@ -3,7 +3,6 @@
class Registry class Registry
{ {
public: public:
inline static std::string ExecutableFilePath;
inline static std::string RootDirectoryPath; inline static std::string RootDirectoryPath;
static void Load(); static void Load();