fs: Actually functional linux case insensitive search
This commit is contained in:
parent
26f8fbf628
commit
dbeed80e3b
|
@ -205,9 +205,9 @@ public:
|
||||||
return WriteSpan(string);
|
return WriteSpan(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteBytes(const std::filesystem::path path, std::span<u8> vec) {
|
static void WriteBytes(const std::filesystem::path path, std::span<const u8> data) {
|
||||||
IOFile out(path, FileAccessMode::Write);
|
IOFile out(path, FileAccessMode::Write);
|
||||||
out.Write(vec);
|
out.Write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -11,18 +11,12 @@ constexpr int RESERVED_HANDLES = 3; // First 3 handles are stdin,stdout,stderr
|
||||||
|
|
||||||
void MntPoints::Mount(const std::filesystem::path& host_folder, const std::string& guest_folder) {
|
void MntPoints::Mount(const std::filesystem::path& host_folder, const std::string& guest_folder) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
m_mnt_pairs.emplace_back(host_folder, guest_folder);
|
||||||
MntPair pair;
|
|
||||||
pair.host_path = host_folder.string();
|
|
||||||
std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/');
|
|
||||||
pair.guest_path = guest_folder;
|
|
||||||
|
|
||||||
m_mnt_pairs.push_back(pair);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MntPoints::Unmount(const std::filesystem::path& host_folder, const std::string& guest_folder) {
|
void MntPoints::Unmount(const std::filesystem::path& host_folder, const std::string& guest_folder) {
|
||||||
auto it = std::remove_if(m_mnt_pairs.begin(), m_mnt_pairs.end(),
|
auto it = std::remove_if(m_mnt_pairs.begin(), m_mnt_pairs.end(),
|
||||||
[&](const MntPair& pair) { return pair.guest_path == guest_folder; });
|
[&](const MntPair& pair) { return pair.mount == guest_folder; });
|
||||||
m_mnt_pairs.erase(it, m_mnt_pairs.end());
|
m_mnt_pairs.erase(it, m_mnt_pairs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,47 +25,74 @@ void MntPoints::UnmountAll() {
|
||||||
m_mnt_pairs.clear();
|
m_mnt_pairs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MntPoints::GetHostDirectory(const std::string& guest_directory) {
|
std::filesystem::path MntPoints::GetHostPath(const std::string& guest_directory) {
|
||||||
std::scoped_lock lock{m_mutex};
|
const MntPair* mount = GetMount(guest_directory);
|
||||||
for (auto& pair : m_mnt_pairs) {
|
if (!mount) {
|
||||||
// horrible code but it works :D
|
return guest_directory;
|
||||||
int find = guest_directory.find(pair.guest_path);
|
|
||||||
if (find == 0) {
|
|
||||||
std::string npath =
|
|
||||||
guest_directory.substr(pair.guest_path.size(), guest_directory.size() - 1);
|
|
||||||
std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/');
|
|
||||||
return pair.host_path + npath;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string MntPoints::GetHostFile(const std::string& guest_file) {
|
// Remove device (e.g /app0) from path to retrieve relative path.
|
||||||
std::scoped_lock lock{m_mutex};
|
const u32 pos = mount->mount.size() + 1;
|
||||||
|
const auto rel_path = std::string_view(guest_directory).substr(pos);
|
||||||
for (auto& pair : m_mnt_pairs) {
|
const auto host_path = mount->host_path / rel_path;
|
||||||
// horrible code but it works :D
|
if (!NeedsCaseInsensiveSearch || std::filesystem::exists(host_path)) {
|
||||||
int find = guest_file.find(pair.guest_path);
|
|
||||||
if (find != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::string npath = guest_file.substr(pair.guest_path.size(), guest_file.size() - 1);
|
|
||||||
const auto host_path = pair.host_path + npath;
|
|
||||||
#ifndef _WIN64
|
|
||||||
const std::filesystem::path path{host_path};
|
|
||||||
if (!std::filesystem::exists(path)) {
|
|
||||||
const auto filename = Common::ToLower(path.filename());
|
|
||||||
for (const auto& file : std::filesystem::directory_iterator(path.parent_path())) {
|
|
||||||
const auto exist_filename = Common::ToLower(file.path().filename());
|
|
||||||
if (filename == exist_filename) {
|
|
||||||
return file.path();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return host_path;
|
return host_path;
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
|
// If the path does not exist attempt to verify this.
|
||||||
|
// Retrieve parent path until we find one that exists.
|
||||||
|
path_parts.clear();
|
||||||
|
auto current_path = host_path;
|
||||||
|
while (!std::filesystem::exists(current_path)) {
|
||||||
|
// We have probably cached this if it's a folder.
|
||||||
|
if (auto it = path_cache.find(current_path); it != path_cache.end()) {
|
||||||
|
current_path = it->second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
path_parts.emplace_back(current_path.filename());
|
||||||
|
current_path = current_path.parent_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have found an anchor. Traverse parts we recoded and see if they
|
||||||
|
// exist in filesystem but in different case.
|
||||||
|
auto guest_path = current_path;
|
||||||
|
while (!path_parts.empty()) {
|
||||||
|
const auto& part = path_parts.back();
|
||||||
|
const auto add_match = [&](const auto& host_part) {
|
||||||
|
current_path += host_part;
|
||||||
|
guest_path += part;
|
||||||
|
path_cache[guest_path] = current_path;
|
||||||
|
path_parts.pop_back();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Can happen when the mismatch is in upper folder.
|
||||||
|
if (std::filesystem::exists(current_path / part)) {
|
||||||
|
add_match(part);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto part_low = Common::ToLower(part.string());
|
||||||
|
bool found_match = false;
|
||||||
|
for (const auto& path : std::filesystem::directory_iterator(current_path)) {
|
||||||
|
const auto candidate = path.path().filename();
|
||||||
|
const auto filename = Common::ToLower(candidate);
|
||||||
|
// Check if a filename matches in case insensitive manner.
|
||||||
|
if (filename != part_low) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// We found a match, record the actual path in the cache.
|
||||||
|
add_match(candidate);
|
||||||
|
found_match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!found_match) {
|
||||||
|
// Opening the guest path will surely fail but at least gives
|
||||||
|
// a better error message than the empty path.
|
||||||
|
return guest_directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The path was found.
|
||||||
|
return current_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HandleTable::CreateHandle() {
|
int HandleTable::CreateHandle() {
|
||||||
|
|
|
@ -7,28 +7,45 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <tsl/robin_map.h>
|
||||||
#include "common/io_file.h"
|
#include "common/io_file.h"
|
||||||
|
|
||||||
namespace Core::FileSys {
|
namespace Core::FileSys {
|
||||||
|
|
||||||
class MntPoints {
|
class MntPoints {
|
||||||
|
#ifdef _WIN64
|
||||||
|
static constexpr bool NeedsCaseInsensiveSearch = false;
|
||||||
|
#else
|
||||||
|
static constexpr bool NeedsCaseInsensiveSearch = true;
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
struct MntPair {
|
struct MntPair {
|
||||||
std::string host_path;
|
std::filesystem::path host_path;
|
||||||
std::string guest_path; // e.g /app0/
|
std::string mount; // e.g /app0/
|
||||||
};
|
};
|
||||||
|
|
||||||
MntPoints() = default;
|
explicit MntPoints() = default;
|
||||||
virtual ~MntPoints() = default;
|
~MntPoints() = default;
|
||||||
|
|
||||||
void Mount(const std::filesystem::path& host_folder, const std::string& guest_folder);
|
void Mount(const std::filesystem::path& host_folder,
|
||||||
void Unmount(const std::filesystem::path& host_folder, const std::string& guest_folder);
|
const std::string& guest_folder);
|
||||||
|
void Unmount(const std::filesystem::path& host_folder,
|
||||||
|
const std::string& guest_folder);
|
||||||
void UnmountAll();
|
void UnmountAll();
|
||||||
std::string GetHostDirectory(const std::string& guest_directory);
|
|
||||||
std::string GetHostFile(const std::string& guest_file);
|
std::filesystem::path GetHostPath(const std::string& guest_directory);
|
||||||
|
|
||||||
|
const MntPair* GetMount(const std::string& guest_path) {
|
||||||
|
const auto it = std::ranges::find_if(m_mnt_pairs, [&](const auto& mount) {
|
||||||
|
return guest_path.starts_with(mount.mount);
|
||||||
|
});
|
||||||
|
return it == m_mnt_pairs.end() ? nullptr : &*it;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<MntPair> m_mnt_pairs;
|
std::vector<MntPair> m_mnt_pairs;
|
||||||
|
std::vector<std::filesystem::path> path_parts;
|
||||||
|
tsl::robin_map<std::filesystem::path, std::filesystem::path> path_cache;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
||||||
if (directory) {
|
if (directory) {
|
||||||
file->is_directory = true;
|
file->is_directory = true;
|
||||||
file->m_guest_name = path;
|
file->m_guest_name = path;
|
||||||
file->m_host_name = mnt->GetHostDirectory(file->m_guest_name);
|
file->m_host_name = mnt->GetHostPath(file->m_guest_name);
|
||||||
if (!std::filesystem::is_directory(file->m_host_name)) { // directory doesn't exist
|
if (!std::filesystem::is_directory(file->m_host_name)) { // directory doesn't exist
|
||||||
h->DeleteHandle(handle);
|
h->DeleteHandle(handle);
|
||||||
return ORBIS_KERNEL_ERROR_ENOTDIR;
|
return ORBIS_KERNEL_ERROR_ENOTDIR;
|
||||||
|
@ -72,7 +72,7 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
file->m_guest_name = path;
|
file->m_guest_name = path;
|
||||||
file->m_host_name = mnt->GetHostFile(file->m_guest_name);
|
file->m_host_name = mnt->GetHostPath(file->m_guest_name);
|
||||||
int e = 0;
|
int e = 0;
|
||||||
if (read) {
|
if (read) {
|
||||||
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read);
|
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read);
|
||||||
|
@ -165,8 +165,7 @@ int PS4_SYSV_ABI sceKernelUnlink(const char* path) {
|
||||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
|
|
||||||
std::string host_path = mnt->GetHostFile(path);
|
const auto host_path = mnt->GetHostPath(path);
|
||||||
|
|
||||||
if (host_path.empty()) {
|
if (host_path.empty()) {
|
||||||
return SCE_KERNEL_ERROR_EACCES;
|
return SCE_KERNEL_ERROR_EACCES;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +249,7 @@ int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) {
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
std::string dir_name = mnt->GetHostFile(path);
|
const auto dir_name = mnt->GetHostPath(path);
|
||||||
if (std::filesystem::exists(dir_name)) {
|
if (std::filesystem::exists(dir_name)) {
|
||||||
return SCE_KERNEL_ERROR_EEXIST;
|
return SCE_KERNEL_ERROR_EEXIST;
|
||||||
}
|
}
|
||||||
|
@ -279,7 +278,7 @@ int PS4_SYSV_ABI posix_mkdir(const char* path, u16 mode) {
|
||||||
int PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) {
|
int PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) {
|
||||||
LOG_INFO(Kernel_Fs, "(PARTIAL) path = {}", path);
|
LOG_INFO(Kernel_Fs, "(PARTIAL) path = {}", path);
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
const auto& path_name = mnt->GetHostFile(path);
|
const auto path_name = mnt->GetHostPath(path);
|
||||||
std::memset(sb, 0, sizeof(OrbisKernelStat));
|
std::memset(sb, 0, sizeof(OrbisKernelStat));
|
||||||
const bool is_dir = std::filesystem::is_directory(path_name);
|
const bool is_dir = std::filesystem::is_directory(path_name);
|
||||||
const bool is_file = std::filesystem::is_regular_file(path_name);
|
const bool is_file = std::filesystem::is_regular_file(path_name);
|
||||||
|
@ -314,7 +313,7 @@ int PS4_SYSV_ABI posix_stat(const char* path, OrbisKernelStat* sb) {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelCheckReachability(const char* path) {
|
int PS4_SYSV_ABI sceKernelCheckReachability(const char* path) {
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
std::string path_name = mnt->GetHostFile(path);
|
const auto path_name = mnt->GetHostPath(path);
|
||||||
if (!std::filesystem::exists(path_name)) {
|
if (!std::filesystem::exists(path_name)) {
|
||||||
return SCE_KERNEL_ERROR_ENOENT;
|
return SCE_KERNEL_ERROR_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,7 +222,7 @@ s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, size_t arg
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
const auto path = mnt->GetHostFile(moduleFileName);
|
const auto path = mnt->GetHostPath(moduleFileName);
|
||||||
|
|
||||||
// Load PRX module and relocate any modules that import it.
|
// Load PRX module and relocate any modules that import it.
|
||||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/libc/libc_stdio.h"
|
#include "core/libraries/libc/libc_stdio.h"
|
||||||
|
@ -10,11 +10,12 @@ namespace Libraries::LibC {
|
||||||
|
|
||||||
std::FILE* PS4_SYSV_ABI ps4_fopen(const char* filename, const char* mode) {
|
std::FILE* PS4_SYSV_ABI ps4_fopen(const char* filename, const char* mode) {
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
FILE* f = std::fopen(mnt->GetHostFile(filename).c_str(), mode);
|
const auto host_path = mnt->GetHostPath(filename);
|
||||||
|
FILE* f = std::fopen(host_path.c_str(), mode);
|
||||||
if (f != nullptr) {
|
if (f != nullptr) {
|
||||||
LOG_INFO(Lib_LibC, "fopen = {}", mnt->GetHostFile(filename).c_str());
|
LOG_INFO(Lib_LibC, "fopen = {}", host_path.native());
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO(Lib_LibC, "fopen can't open = {}", mnt->GetHostFile(filename).c_str());
|
LOG_INFO(Lib_LibC, "fopen can't open = {}", host_path.native());
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
#include "error_codes.h"
|
#include "error_codes.h"
|
||||||
|
|
||||||
namespace Libraries::SaveData {
|
namespace Libraries::SaveData {
|
||||||
static std::string g_mount_point = "/savedata0"; // temp mount point (todo)
|
|
||||||
|
static constexpr std::string_view g_mount_point = "/savedata0"; // temp mount point (todo)
|
||||||
std::string game_serial;
|
std::string game_serial;
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceSaveDataAbort() {
|
int PS4_SYSV_ABI sceSaveDataAbort() {
|
||||||
|
@ -50,11 +51,11 @@ int PS4_SYSV_ABI sceSaveDataChangeInternal() {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceSaveDataCheckBackupData(const OrbisSaveDataCheckBackupData* check) {
|
int PS4_SYSV_ABI sceSaveDataCheckBackupData(const OrbisSaveDataCheckBackupData* check) {
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
std::string mount_dir = mnt->GetHostFile(check->dirName->data);
|
const auto mount_dir = mnt->GetHostPath(check->dirName->data);
|
||||||
if (!std::filesystem::exists(mount_dir)) {
|
if (!std::filesystem::exists(mount_dir)) {
|
||||||
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
|
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
LOG_INFO(Lib_SaveData, "called = {}", mount_dir);
|
LOG_INFO(Lib_SaveData, "called = {}", mount_dir.native());
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -317,14 +318,14 @@ int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(OrbisSaveDataMemoryGet2* getParam
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
file.Seek(getParam->data->offset);
|
file.Seek(getParam->data->offset);
|
||||||
size_t nbytes = file.ReadRaw<u8>(getParam->data->buf, getParam->data->bufSize);
|
file.ReadRaw<u8>(getParam->data->buf, getParam->data->bufSize);
|
||||||
LOG_INFO(Lib_SaveData, "called: bufSize = {}, offset = {}", getParam->data->bufSize,
|
LOG_INFO(Lib_SaveData, "called: bufSize = {}, offset = {}", getParam->data->bufSize,
|
||||||
getParam->data->offset);
|
getParam->data->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getParam->param != nullptr) {
|
if (getParam->param != nullptr) {
|
||||||
Common::FS::IOFile file1(mount_dir / "param.txt", Common::FS::FileAccessMode::Read);
|
Common::FS::IOFile file(mount_dir / "param.txt", Common::FS::FileAccessMode::Read);
|
||||||
size_t nbytes = file1.ReadRaw<u8>(getParam->param, sizeof(OrbisSaveDataParam));
|
file.ReadRaw<u8>(getParam->param, sizeof(OrbisSaveDataParam));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -394,13 +395,13 @@ int PS4_SYSV_ABI sceSaveDataIsMounted() {
|
||||||
int PS4_SYSV_ABI sceSaveDataLoadIcon(const OrbisSaveDataMountPoint* mountPoint,
|
int PS4_SYSV_ABI sceSaveDataLoadIcon(const OrbisSaveDataMountPoint* mountPoint,
|
||||||
OrbisSaveDataIcon* icon) {
|
OrbisSaveDataIcon* icon) {
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
std::string mount_dir = mnt->GetHostFile(mountPoint->data);
|
const auto mount_dir = mnt->GetHostPath(mountPoint->data);
|
||||||
LOG_INFO(Lib_SaveData, "called: dir = {}", mount_dir);
|
LOG_INFO(Lib_SaveData, "called: dir = {}", mount_dir.native());
|
||||||
|
|
||||||
if (icon != nullptr) {
|
if (icon != nullptr) {
|
||||||
Common::FS::IOFile file(mount_dir + "/save_data.png", Common::FS::FileAccessMode::Read);
|
Common::FS::IOFile file(mount_dir / "save_data.png", Common::FS::FileAccessMode::Read);
|
||||||
icon->bufSize = file.GetSize();
|
icon->bufSize = file.GetSize();
|
||||||
size_t nbytes = file.ReadRaw<u8>(icon->buf, icon->bufSize);
|
file.ReadRaw<u8>(icon->buf, icon->bufSize);
|
||||||
}
|
}
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -409,6 +410,7 @@ s32 saveDataMount(u32 user_id, char* dir_name, u32 mount_mode,
|
||||||
OrbisSaveDataMountResult* mount_result) {
|
OrbisSaveDataMountResult* mount_result) {
|
||||||
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
|
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
|
||||||
std::to_string(user_id) / game_serial / dir_name;
|
std::to_string(user_id) / game_serial / dir_name;
|
||||||
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
switch (mount_mode) {
|
switch (mount_mode) {
|
||||||
case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY:
|
case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY:
|
||||||
case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR:
|
case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR:
|
||||||
|
@ -417,9 +419,8 @@ s32 saveDataMount(u32 user_id, char* dir_name, u32 mount_mode,
|
||||||
if (!std::filesystem::exists(mount_dir)) {
|
if (!std::filesystem::exists(mount_dir)) {
|
||||||
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
|
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
|
||||||
mount_result->mount_status = 0;
|
mount_result->mount_status = 0;
|
||||||
std::strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
g_mount_point.copy(mount_result->mount_point.data, 16);
|
||||||
mnt->Mount(mount_dir, mount_result->mount_point.data);
|
mnt->Mount(mount_dir, mount_result->mount_point.data);
|
||||||
} break;
|
} break;
|
||||||
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE:
|
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE:
|
||||||
|
@ -431,16 +432,15 @@ s32 saveDataMount(u32 user_id, char* dir_name, u32 mount_mode,
|
||||||
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON:
|
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON:
|
||||||
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF |
|
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF |
|
||||||
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: {
|
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: {
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
|
||||||
if (std::filesystem::exists(mount_dir)) {
|
if (std::filesystem::exists(mount_dir)) {
|
||||||
std::strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
g_mount_point.copy(mount_result->mount_point.data, 16);
|
||||||
mnt->Mount(mount_dir, mount_result->mount_point.data);
|
mnt->Mount(mount_dir, mount_result->mount_point.data);
|
||||||
mount_result->required_blocks = 0;
|
mount_result->required_blocks = 0;
|
||||||
mount_result->mount_status = 0;
|
mount_result->mount_status = 0;
|
||||||
return ORBIS_SAVE_DATA_ERROR_EXISTS;
|
return ORBIS_SAVE_DATA_ERROR_EXISTS;
|
||||||
}
|
}
|
||||||
if (std::filesystem::create_directories(mount_dir)) {
|
if (std::filesystem::create_directories(mount_dir)) {
|
||||||
std::strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
g_mount_point.copy(mount_result->mount_point.data, 16);
|
||||||
mnt->Mount(mount_dir, mount_result->mount_point.data);
|
mnt->Mount(mount_dir, mount_result->mount_point.data);
|
||||||
mount_result->mount_status = 1;
|
mount_result->mount_status = 1;
|
||||||
}
|
}
|
||||||
|
@ -451,8 +451,7 @@ s32 saveDataMount(u32 user_id, char* dir_name, u32 mount_mode,
|
||||||
if (!std::filesystem::exists(mount_dir)) {
|
if (!std::filesystem::exists(mount_dir)) {
|
||||||
std::filesystem::create_directories(mount_dir);
|
std::filesystem::create_directories(mount_dir);
|
||||||
}
|
}
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
g_mount_point.copy(mount_result->mount_point.data, 16);
|
||||||
std::strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
|
||||||
mnt->Mount(mount_dir, mount_result->mount_point.data);
|
mnt->Mount(mount_dir, mount_result->mount_point.data);
|
||||||
mount_result->mount_status = 1;
|
mount_result->mount_status = 1;
|
||||||
} break;
|
} break;
|
||||||
|
@ -534,12 +533,12 @@ int PS4_SYSV_ABI sceSaveDataRestoreLoadSaveDataMemory() {
|
||||||
int PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint,
|
int PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint,
|
||||||
const OrbisSaveDataIcon* icon) {
|
const OrbisSaveDataIcon* icon) {
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
std::string mount_dir = mnt->GetHostFile(mountPoint->data);
|
const auto mount_dir = mnt->GetHostPath(mountPoint->data);
|
||||||
LOG_INFO(Lib_SaveData, "called = {}", mount_dir);
|
LOG_INFO(Lib_SaveData, "called = {}", mount_dir.native());
|
||||||
|
|
||||||
if (icon != nullptr) {
|
if (icon != nullptr) {
|
||||||
Common::FS::IOFile file(mount_dir + "/save_data.png", Common::FS::FileAccessMode::Write);
|
Common::FS::IOFile file(mount_dir / "save_data.png", Common::FS::FileAccessMode::Write);
|
||||||
file.WriteRaw<u8>((void*)icon->buf, icon->bufSize);
|
file.WriteRaw<u8>(icon->buf, icon->bufSize);
|
||||||
}
|
}
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -558,12 +557,13 @@ int PS4_SYSV_ABI sceSaveDataSetParam(const OrbisSaveDataMountPoint* mountPoint,
|
||||||
OrbisSaveDataParamType paramType, const void* paramBuf,
|
OrbisSaveDataParamType paramType, const void* paramBuf,
|
||||||
size_t paramBufSize) {
|
size_t paramBufSize) {
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
std::string mount_dir = mnt->GetHostFile(mountPoint->data);
|
const auto mount_dir = mnt->GetHostPath(mountPoint->data);
|
||||||
LOG_INFO(Lib_SaveData, "called = {}, mountPoint->data = {}", mount_dir, mountPoint->data);
|
LOG_INFO(Lib_SaveData, "called = {}, mountPoint->data = {}", mount_dir.native(),
|
||||||
|
mountPoint->data);
|
||||||
|
|
||||||
if (paramBuf != nullptr) {
|
if (paramBuf != nullptr) {
|
||||||
Common::FS::IOFile file(mount_dir + "/param.txt", Common::FS::FileAccessMode::Write);
|
Common::FS::IOFile file(mount_dir / "param.txt", Common::FS::FileAccessMode::Write);
|
||||||
file.WriteRaw<u8>((void*)paramBuf, paramBufSize);
|
file.WriteRaw<u8>(paramBuf, paramBufSize);
|
||||||
}
|
}
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -711,24 +711,23 @@ int PS4_SYSV_ABI sceSaveDataUmountSys() {
|
||||||
int PS4_SYSV_ABI sceSaveDataUmountWithBackup(const OrbisSaveDataMountPoint* mountPoint) {
|
int PS4_SYSV_ABI sceSaveDataUmountWithBackup(const OrbisSaveDataMountPoint* mountPoint) {
|
||||||
LOG_ERROR(Lib_SaveData, "called = {}", std::string(mountPoint->data));
|
LOG_ERROR(Lib_SaveData, "called = {}", std::string(mountPoint->data));
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
std::string mount_dir = mnt->GetHostFile(mountPoint->data);
|
const auto mount_dir = mnt->GetHostPath(mountPoint->data);
|
||||||
if (!std::filesystem::exists(mount_dir)) {
|
if (!std::filesystem::exists(mount_dir)) {
|
||||||
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
|
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
|
||||||
} else {
|
|
||||||
std::filesystem::path mnt_dir(mount_dir);
|
|
||||||
std::filesystem::create_directories(mnt_dir.parent_path() / "backup");
|
|
||||||
|
|
||||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(mnt_dir)) {
|
|
||||||
const auto& path = entry.path();
|
|
||||||
std::filesystem::path target_path = mnt_dir.parent_path() / "backup";
|
|
||||||
|
|
||||||
if (std::filesystem::is_regular_file(path)) {
|
|
||||||
std::filesystem::copy(path, target_path,
|
|
||||||
std::filesystem::copy_options::overwrite_existing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mnt->Unmount(mount_dir, mountPoint->data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::filesystem::create_directories(mount_dir.parent_path() / "backup");
|
||||||
|
|
||||||
|
for (const auto& entry : std::filesystem::recursive_directory_iterator(mount_dir)) {
|
||||||
|
const auto& path = entry.path();
|
||||||
|
const auto target_path = mount_dir.parent_path() / "backup";
|
||||||
|
if (std::filesystem::is_regular_file(path)) {
|
||||||
|
std::filesystem::copy(path, target_path,
|
||||||
|
std::filesystem::copy_options::overwrite_existing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mnt->Unmount(mount_dir, mountPoint->data);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue