mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-08-03 11:23:49 +00:00
ABI fixes: libNet, libSaveData (rewrite the legacy Kyty implementation)
This commit is contained in:
@@ -35,6 +35,7 @@ namespace LibNet {
|
|||||||
LIB_VERSION("Net", 1, "Net", 1, 1);
|
LIB_VERSION("Net", 1, "Net", 1, 1);
|
||||||
|
|
||||||
static thread_local int g_net_errno = 0;
|
static thread_local int g_net_errno = 0;
|
||||||
|
static constexpr uint32_t g_in6addr_any[4] {};
|
||||||
|
|
||||||
namespace Net = Network::Net;
|
namespace Net = Network::Net;
|
||||||
|
|
||||||
@@ -180,6 +181,8 @@ uint16_t KYTY_SYSV_ABI NetNtohs(uint16_t net16) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LIB_DEFINE(InitNet_1_Net) {
|
LIB_DEFINE(InitNet_1_Net) {
|
||||||
|
LIB_OBJECT("ZRAJo-A-ukc", &LibNet::g_in6addr_any);
|
||||||
|
|
||||||
LIB_FUNC("Nlev7Lg8k3A", LibNet::NetInit);
|
LIB_FUNC("Nlev7Lg8k3A", LibNet::NetInit);
|
||||||
LIB_FUNC("HQOwnfMGipQ", LibNet::GetNetErrorAddr);
|
LIB_FUNC("HQOwnfMGipQ", LibNet::GetNetErrorAddr);
|
||||||
LIB_FUNC("PIWqhn9oSxc", LibNet::NetAccept);
|
LIB_FUNC("PIWqhn9oSxc", LibNet::NetAccept);
|
||||||
|
|||||||
+55
-32
@@ -4,9 +4,11 @@
|
|||||||
#include "common/file.h"
|
#include "common/file.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
#include "common/threads.h"
|
||||||
#include "kernel/fileSystem.h"
|
#include "kernel/fileSystem.h"
|
||||||
#include "libs/errno.h"
|
#include "libs/errno.h"
|
||||||
#include "libs/libs.h"
|
#include "libs/libs.h"
|
||||||
|
#include "libs/saveDataMountSlots.h"
|
||||||
#include "loader/symbolDatabase.h"
|
#include "loader/symbolDatabase.h"
|
||||||
#include "loader/systemContent.h"
|
#include "loader/systemContent.h"
|
||||||
|
|
||||||
@@ -23,7 +25,6 @@ namespace SaveData {
|
|||||||
|
|
||||||
// TODO(): specify dir at launcher
|
// TODO(): specify dir at launcher
|
||||||
static constexpr char SAVE_DATA_DIR[] = "_SaveData";
|
static constexpr char SAVE_DATA_DIR[] = "_SaveData";
|
||||||
static constexpr char SAVE_DATA_POINT[] = "/savedata0";
|
|
||||||
static constexpr uint64_t SAVE_DATA_BLOCKS_MAX = 16384;
|
static constexpr uint64_t SAVE_DATA_BLOCKS_MAX = 16384;
|
||||||
|
|
||||||
struct SceSaveDataDirName {
|
struct SceSaveDataDirName {
|
||||||
@@ -234,6 +235,8 @@ static constexpr uint32_t SAVE_DATA_EVENT_TYPE_COMMIT_BACKUP_END = 4u;
|
|||||||
static std::vector<uint8_t> g_save_data_memory(0x10000);
|
static std::vector<uint8_t> g_save_data_memory(0x10000);
|
||||||
static int32_t g_next_transaction_resource = 1;
|
static int32_t g_next_transaction_resource = 1;
|
||||||
static std::deque<SaveDataEvent> g_save_data_events;
|
static std::deque<SaveDataEvent> g_save_data_events;
|
||||||
|
static SaveDataMountSlots g_mount_slots;
|
||||||
|
static Common::Mutex g_mount_mutex;
|
||||||
|
|
||||||
static std::string get_title_id() {
|
static std::string get_title_id() {
|
||||||
std::string title_id;
|
std::string title_id;
|
||||||
@@ -291,6 +294,18 @@ static bool dir_name_match(const char* str, const char* pattern) {
|
|||||||
return *str == '\0' && *pattern == '\0';
|
return *str == '\0' && *pattern == '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mount_save_data(int slot, std::string_view dir_name, const std::string& directory,
|
||||||
|
uint32_t status, SaveDataMountResult* result) {
|
||||||
|
const std::string mount_point = SaveDataMountSlots::MountPoint(static_cast<size_t>(slot));
|
||||||
|
LibKernel::FileSystem::Mount(directory, mount_point);
|
||||||
|
g_mount_slots.Mount(static_cast<size_t>(slot), dir_name);
|
||||||
|
std::snprintf(result->mount_point.data, sizeof(result->mount_point.data), "%s",
|
||||||
|
mount_point.c_str());
|
||||||
|
result->required_blocks = 0;
|
||||||
|
result->mount_status = status;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
int KYTY_SYSV_ABI SaveDataInitialize3(const void* /*init*/) {
|
int KYTY_SYSV_ABI SaveDataInitialize3(const void* /*init*/) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
@@ -302,6 +317,10 @@ int KYTY_SYSV_ABI SaveDataInitialize3(const void* /*init*/) {
|
|||||||
int KYTY_SYSV_ABI SaveDataTerminate() {
|
int KYTY_SYSV_ABI SaveDataTerminate() {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
|
Common::LockGuard lock(g_mount_mutex);
|
||||||
|
if (!g_mount_slots.Empty()) {
|
||||||
|
return SAVE_DATA_ERROR_BUSY;
|
||||||
|
}
|
||||||
g_save_data_events.clear();
|
g_save_data_events.clear();
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -418,12 +437,20 @@ int KYTY_SYSV_ABI SaveDataMount3(const SaveDataMount3* mount, SaveDataMountResul
|
|||||||
|
|
||||||
*mount_result = {};
|
*mount_result = {};
|
||||||
|
|
||||||
std::string mount_dir = std::string(SAVE_DATA_DIR) + "/" + get_title_id() + "/" +
|
Common::LockGuard lock(g_mount_mutex);
|
||||||
std::string(mount->dir_name->data);
|
const std::string dir_name = mount->dir_name->data;
|
||||||
std::string mount_point = SAVE_DATA_POINT;
|
const std::string mount_dir = std::string(SAVE_DATA_DIR) + "/" + get_title_id() + "/" + dir_name;
|
||||||
bool create = ((mount->mount_mode & 4u) != 0);
|
const bool create = ((mount->mount_mode & 4u) != 0);
|
||||||
bool create2 = ((mount->mount_mode & 32u) != 0);
|
const bool create2 = ((mount->mount_mode & 32u) != 0);
|
||||||
bool open = (!create && !create2 && ((mount->mount_mode & 3u) != 0));
|
const bool open = (!create && !create2 && ((mount->mount_mode & 3u) != 0));
|
||||||
|
|
||||||
|
const int slot = g_mount_slots.FindAvailable(dir_name);
|
||||||
|
if (slot == SaveDataMountSlots::BUSY) {
|
||||||
|
return SAVE_DATA_ERROR_BUSY;
|
||||||
|
}
|
||||||
|
if (slot == SaveDataMountSlots::FULL) {
|
||||||
|
return SAVE_DATA_ERROR_MOUNT_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!create && !create2 && !open) {
|
if (!create && !create2 && !open) {
|
||||||
EXIT("unknown mount mode: %u", mount->mount_mode);
|
EXIT("unknown mount mode: %u", mount->mount_mode);
|
||||||
@@ -445,16 +472,7 @@ int KYTY_SYSV_ABI SaveDataMount3(const SaveDataMount3* mount, SaveDataMountResul
|
|||||||
EXIT_NOT_IMPLEMENTED((!Common::File::IsDirectoryExisting(mount_dir)));
|
EXIT_NOT_IMPLEMENTED((!Common::File::IsDirectoryExisting(mount_dir)));
|
||||||
}
|
}
|
||||||
|
|
||||||
LibKernel::FileSystem::Mount(mount_dir, mount_point);
|
return mount_save_data(slot, dir_name, mount_dir, created ? 1u : 0u, mount_result);
|
||||||
|
|
||||||
int s = snprintf(mount_result->mount_point.data, 16, "%s", mount_point.c_str());
|
|
||||||
|
|
||||||
EXIT_NOT_IMPLEMENTED(s >= 16);
|
|
||||||
|
|
||||||
mount_result->required_blocks = 0;
|
|
||||||
mount_result->mount_status = (created ? 1 : 0);
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int KYTY_SYSV_ABI SaveDataSetupSaveDataMemory2(const SaveDataMemorySetup2* setup_param,
|
int KYTY_SYSV_ABI SaveDataSetupSaveDataMemory2(const SaveDataMemorySetup2* setup_param,
|
||||||
@@ -575,24 +593,22 @@ int KYTY_SYSV_ABI SaveDataTransferringMount(const SaveDataTransferringMount* mou
|
|||||||
|
|
||||||
*mount_result = {};
|
*mount_result = {};
|
||||||
|
|
||||||
std::string mount_dir = std::string(SAVE_DATA_DIR) + "/" + get_title_id() + "/" +
|
Common::LockGuard lock(g_mount_mutex);
|
||||||
std::string(mount->dir_name->data);
|
const std::string dir_name = mount->dir_name->data;
|
||||||
std::string mount_point = SAVE_DATA_POINT;
|
const std::string mount_dir = std::string(SAVE_DATA_DIR) + "/" + get_title_id() + "/" + dir_name;
|
||||||
|
const int slot = g_mount_slots.FindAvailable(dir_name);
|
||||||
|
if (slot == SaveDataMountSlots::BUSY) {
|
||||||
|
return SAVE_DATA_ERROR_BUSY;
|
||||||
|
}
|
||||||
|
if (slot == SaveDataMountSlots::FULL) {
|
||||||
|
return SAVE_DATA_ERROR_MOUNT_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Common::File::IsDirectoryExisting(mount_dir)) {
|
if (!Common::File::IsDirectoryExisting(mount_dir)) {
|
||||||
Common::File::CreateDirectories(mount_dir);
|
Common::File::CreateDirectories(mount_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
LibKernel::FileSystem::Mount(mount_dir, mount_point);
|
return mount_save_data(slot, dir_name, mount_dir, 1, mount_result);
|
||||||
|
|
||||||
int s = snprintf(mount_result->mount_point.data, 16, "%s", mount_point.c_str());
|
|
||||||
|
|
||||||
EXIT_NOT_IMPLEMENTED(s >= 16);
|
|
||||||
|
|
||||||
mount_result->required_blocks = 0;
|
|
||||||
mount_result->mount_status = 1;
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int KYTY_SYSV_ABI SaveDataUmount2(uint32_t mode, const SaveDataMountPoint* mount_point) {
|
int KYTY_SYSV_ABI SaveDataUmount2(uint32_t mode, const SaveDataMountPoint* mount_point) {
|
||||||
@@ -606,11 +622,18 @@ int KYTY_SYSV_ABI SaveDataUmount2(uint32_t mode, const SaveDataMountPoint* mount
|
|||||||
"\t mount_point = %s\n",
|
"\t mount_point = %s\n",
|
||||||
mode, mount_point->data);
|
mode, mount_point->data);
|
||||||
|
|
||||||
|
Common::LockGuard lock(g_mount_mutex);
|
||||||
|
const std::string point = mount_point->data;
|
||||||
|
const int slot = g_mount_slots.Find(point);
|
||||||
|
if (slot == SaveDataMountSlots::FULL) {
|
||||||
|
return SAVE_DATA_ERROR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
if ((mode & SAVE_DATA_UMOUNT_MODE_BACKUP_ASYNC) != 0) {
|
if ((mode & SAVE_DATA_UMOUNT_MODE_BACKUP_ASYNC) != 0) {
|
||||||
queue_save_data_event(SAVE_DATA_EVENT_TYPE_UMOUNT_BACKUP_END, 0, nullptr, nullptr);
|
queue_save_data_event(SAVE_DATA_EVENT_TYPE_UMOUNT_BACKUP_END, 0, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
LibKernel::FileSystem::Umount(point);
|
||||||
LibKernel::FileSystem::Umount(std::string(mount_point->data));
|
g_mount_slots.Release(static_cast<size_t>(slot));
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ namespace SystemService {
|
|||||||
[[maybe_unused]] constexpr int PARAM_ID_SUMMERTIME = 5;
|
[[maybe_unused]] constexpr int PARAM_ID_SUMMERTIME = 5;
|
||||||
[[maybe_unused]] constexpr int PARAM_ID_SYSTEM_NAME = 6;
|
[[maybe_unused]] constexpr int PARAM_ID_SYSTEM_NAME = 6;
|
||||||
[[maybe_unused]] constexpr int PARAM_ID_GAME_PARENTAL_LEVEL = 7;
|
[[maybe_unused]] constexpr int PARAM_ID_GAME_PARENTAL_LEVEL = 7;
|
||||||
|
[[maybe_unused]] constexpr int PARAM_ID_SCREEN_READER = 208;
|
||||||
[[maybe_unused]] constexpr int PARAM_ID_ENTER_BUTTON_ASSIGN = 1000;
|
[[maybe_unused]] constexpr int PARAM_ID_ENTER_BUTTON_ASSIGN = 1000;
|
||||||
|
|
||||||
[[maybe_unused]] constexpr int PARAM_LANG_JAPANESE = 0;
|
[[maybe_unused]] constexpr int PARAM_LANG_JAPANESE = 0;
|
||||||
@@ -126,6 +127,7 @@ static int KYTY_SYSV_ABI SystemServiceParamGetInt(int param_id, int* value) {
|
|||||||
case PARAM_ID_TIME_ZONE: v = +180; break;
|
case PARAM_ID_TIME_ZONE: v = +180; break;
|
||||||
case PARAM_ID_SUMMERTIME: v = 0; break;
|
case PARAM_ID_SUMMERTIME: v = 0; break;
|
||||||
case PARAM_ID_GAME_PARENTAL_LEVEL: v = PARAM_GAME_PARENTAL_OFF; break;
|
case PARAM_ID_GAME_PARENTAL_LEVEL: v = PARAM_GAME_PARENTAL_OFF; break;
|
||||||
|
case PARAM_ID_SCREEN_READER: v = 0; break;
|
||||||
case PARAM_ID_ENTER_BUTTON_ASSIGN: v = PARAM_ENTER_BUTTON_ASSIGN_CROSS; break;
|
case PARAM_ID_ENTER_BUTTON_ASSIGN: v = PARAM_ENTER_BUTTON_ASSIGN_CROSS; break;
|
||||||
default: EXIT("unknown param_id: %d\n", param_id);
|
default: EXIT("unknown param_id: %d\n", param_id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#ifndef EMULATOR_INCLUDE_EMULATOR_LIBS_SAVEDATAMOUNTSLOTS_H_
|
||||||
|
#define EMULATOR_INCLUDE_EMULATOR_LIBS_SAVEDATAMOUNTSLOTS_H_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace Libs::SaveData {
|
||||||
|
|
||||||
|
class SaveDataMountSlots {
|
||||||
|
public:
|
||||||
|
static constexpr int BUSY = -2;
|
||||||
|
static constexpr int FULL = -1;
|
||||||
|
static constexpr size_t COUNT = 16;
|
||||||
|
|
||||||
|
[[nodiscard]] int FindAvailable(std::string_view directory) const {
|
||||||
|
int available = FULL;
|
||||||
|
for (size_t index = 0; index < m_directories.size(); index++) {
|
||||||
|
const auto& mounted = m_directories[index];
|
||||||
|
if (mounted == directory) {
|
||||||
|
return BUSY;
|
||||||
|
}
|
||||||
|
if (!mounted.has_value() && available == FULL) {
|
||||||
|
available = static_cast<int>(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mount(size_t slot, std::string_view directory) { m_directories[slot] = directory; }
|
||||||
|
|
||||||
|
void Release(size_t slot) {
|
||||||
|
if (slot < m_directories.size()) {
|
||||||
|
m_directories[slot].reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int Find(std::string_view mount_point) const {
|
||||||
|
for (size_t index = 0; index < m_directories.size(); index++) {
|
||||||
|
if (m_directories[index].has_value() && MountPoint(index) == mount_point) {
|
||||||
|
return static_cast<int>(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static std::string MountPoint(size_t slot) {
|
||||||
|
return "/savedata" + std::to_string(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool Empty() const {
|
||||||
|
for (const auto& directory: m_directories) {
|
||||||
|
if (directory.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<std::optional<std::string>, COUNT> m_directories;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libs::SaveData
|
||||||
|
|
||||||
|
#endif /* EMULATOR_INCLUDE_EMULATOR_LIBS_SAVEDATAMOUNTSLOTS_H_ */
|
||||||
Reference in New Issue
Block a user