/**
* Ashita SDK - Copyright (c) 2023 Ashita Development Team
* Contact: https://www.ashitaxi.com/
* Contact: https://discord.gg/Ashita
*
* This file is part of Ashita.
*
* Ashita is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Ashita is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Ashita. If not, see .
*/
#ifndef ASHITA_SDK_REGISTRY_H_INCLUDED
#define ASHITA_SDK_REGISTRY_H_INCLUDED
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
#pragma warning(disable : 4505) // unreferenced local function has been removed
#include
#include
#include
namespace Ashita
{
/**
* Language Id Enumeration
*/
enum class LanguageId : uint32_t
{
Default = 0,
Japanese = 1,
English = 2,
European = 3,
MaxValue
};
/**
* Square Enix Game Id Enumeration
*/
enum class SquareEnixGameId : uint32_t
{
PlayOnline = 0,
FinalFantasyXI = 1,
TetraMaster = 2,
FinalFantasyXITestClient = 3,
MaxValue
};
namespace Registry
{
/**
* Obtains the install path for the given Square Enix game entity.
*
* @param {LanguageId} lid - The language id to use for which PlayOnline registry key to look within.
* @param {SquareEnixGameId} gid - The game entity id to lookup.
* @param {LPSTR} buffer - The output buffer to store the path.
* @param {uint32_t} size - The size of the output buffer.
* @return {bool} True on success, false otherwise.
*/
static bool GetInstallPath(const LanguageId lid, const SquareEnixGameId gid, const LPSTR buffer, const uint32_t size)
{
// Validate the parameters..
if ((uint32_t)lid < 0 || lid >= LanguageId::MaxValue ||
(uint32_t)gid < 0 || gid >= SquareEnixGameId::MaxValue ||
buffer == nullptr || size == 0)
return false;
constexpr char tags[4][255] = {"US", "", "US", "EU"};
constexpr char path[4][255] = {"1000", "0001", "0002", "0015"};
// Build the initial registry key path to the install folder information..
char regpath[MAX_PATH]{};
sprintf_s(regpath, MAX_PATH, "SOFTWARE\\PlayOnline%s\\InstallFolder", tags[(uint32_t)lid]);
// Open the registry for reading..
HKEY key = nullptr;
if (!(::RegOpenKeyExA(HKEY_LOCAL_MACHINE, regpath, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) == ERROR_SUCCESS))
return false;
// Read the install path from the registry..
const char ipath[MAX_PATH]{};
DWORD ksize = MAX_PATH;
auto ktype = REG_DWORD;
if (!(::RegQueryValueExA(key, path[(uint32_t)gid], nullptr, &ktype, (LPBYTE)ipath, &ksize) == ERROR_SUCCESS))
{
::RegCloseKey(key);
return false;
}
::RegCloseKey(key);
// Ensure the output buffer is large enough for the path..
if (strlen(ipath) > size)
return false;
// Copy the result into the output buffer..
strcpy_s(buffer, size, ipath);
return true;
}
/**
* Returns the value of a registry key from the games registry data.
*
* @param {LanguageId} lid - The language id to use for which PlayOnline registry key to look within.
* @param {const char*} parent - The inner-parent key holding the value to obtain.
* @param {const char*} keyName - The key name of the value to read.
* @return {uint32_t} The value of the key on success, 0 otherwise.
*/
static uint32_t GetValue(const LanguageId lid, const char* parent, const char* keyName)
{
// Validate the parameters..
if ((uint32_t)lid < 0 || lid >= LanguageId::MaxValue)
return 0;
constexpr char tags[4][255] = {"US", "", "US", "EU"};
// Build the path to the registry value..
char regpath[MAX_PATH]{};
sprintf_s(regpath, MAX_PATH, "SOFTWARE\\PlayOnline%s\\%s", tags[(uint32_t)lid], parent);
// Open the registry for reading..
HKEY key = nullptr;
if (!(::RegOpenKeyExA(HKEY_LOCAL_MACHINE, regpath, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) == ERROR_SUCCESS))
return 0;
DWORD ksize = 4;
auto ktype = REG_DWORD;
DWORD value = 0;
// Read the value..
if (!(::RegQueryValueExA(key, keyName, nullptr, &ktype, (LPBYTE)&value, &ksize) == ERROR_SUCCESS))
{
::RegCloseKey(key);
return 0;
}
::RegCloseKey(key);
return value;
}
/**
* Sets the value of a registry key from the games registry data.
*
* @param {LanguageId} lid - The language id to use for which PlayOnline registry key to look within.
* @param {const char*} parent - The inner-parent key holding the value to write to.
* @param {const char*} keyName - The key name of the value to write.
* @return {bool} True on success, false otherwise.
*/
static bool SetValue(const LanguageId lid, const char* parent, const char* keyName, const uint32_t value)
{
// Validate the parameters..
if ((uint32_t)lid < 0 || lid >= LanguageId::MaxValue)
return false;
constexpr char tags[4][255] = {"US", "", "US", "EU"};
// Build the path to the registry value..
char regpath[MAX_PATH]{};
sprintf_s(regpath, MAX_PATH, "SOFTWARE\\PlayOnline%s\\%s", tags[(uint32_t)lid], parent);
// Open the registry for writing..
HKEY key = nullptr;
if (!(::RegOpenKeyExA(HKEY_LOCAL_MACHINE, regpath, 0, KEY_WRITE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key) == ERROR_SUCCESS))
return false;
// Write the value..
const auto ret = ::RegSetValueExA(key, keyName, 0, REG_DWORD, (LPBYTE)&value, sizeof(uint32_t));
::RegCloseKey(key);
return ret == ERROR_SUCCESS;
}
} // namespace Registry
} // namespace Ashita
#endif // ASHITA_SDK_REGISTRY_H_INCLUDED