From 379037e2fd9c874ef6e110891b1cbeaa2868abc0 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 17 Nov 2023 16:16:35 +0200 Subject: [PATCH] some work for fs trying to run libpng demo of openorbis (not working) --- CMakeLists.txt | 4 +- src/common/fs_file.cpp | 2 + src/common/fs_file.h | 1 + src/core/file_sys/fs.cpp | 91 +++++++++++++++++++ src/core/file_sys/fs.h | 54 +++++++++++ .../hle/libraries/libkernel/file_system.cpp | 33 ++++++- .../hle/libraries/libkernel/file_system.h | 7 +- 7 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 src/core/file_sys/fs.cpp create mode 100644 src/core/file_sys/fs.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d4d605f41..8d198ee1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,9 @@ set(SYSTEMSERVICE_SOURCES src/core/hle/libraries/libsystemservice/system_service ) set(FILESYSTEM_SOURCES src/core/hle/libraries/libkernel/file_system.cpp - src/core/hle/libraries/libkernel/file_system.h + src/core/hle/libraries/libkernel/file_system.h + src/core/file_sys/fs.cpp + src/core/file_sys/fs.h ) set(HOST_SOURCES src/Emulator/Host/controller.cpp diff --git a/src/common/fs_file.cpp b/src/common/fs_file.cpp index 007ec72d4..26282425a 100644 --- a/src/common/fs_file.cpp +++ b/src/common/fs_file.cpp @@ -40,6 +40,8 @@ bool File::read(void* data, u64 size) const { return isOpen() && std::fread(data, 1, size, m_file) == size; } +size_t File::reads(void* data, u64 size) const { return std::fread(data, 1, size, m_file); } + bool File::seek(s64 offset, SeekMode mode) { #ifdef _WIN64 if (!isOpen() || _fseeki64(m_file, offset, getSeekMode(mode)) != 0) { diff --git a/src/common/fs_file.h b/src/common/fs_file.h index adc996053..c14d0e21a 100644 --- a/src/common/fs_file.h +++ b/src/common/fs_file.h @@ -31,6 +31,7 @@ class File { bool open(const std::string& path, OpenMode mode = OpenMode::Read); bool close(); bool read(void* data, u64 size) const; + size_t reads(void* data, u64 size) const; bool write(std::span data); bool seek(s64 offset, SeekMode mode); u64 getFileSize(); diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp new file mode 100644 index 000000000..18884b740 --- /dev/null +++ b/src/core/file_sys/fs.cpp @@ -0,0 +1,91 @@ +#include "fs.h" + +#include + +namespace Core::FileSys { + +constexpr int RESERVED_HANDLES = 3; // First 3 handles are stdin,stdout,stderr + +void MntPoints::mount(const std::string& host_folder, const std::string& guest_folder) { + std::scoped_lock lock{m_mutex}; + + MntPair pair; + pair.host_path = host_folder; + pair.guest_path = guest_folder; + + m_mnt_pairs.push_back(pair); +} +void MntPoints::unmount(const std::string& path) {} // TODO! +void MntPoints::unmountAll() { + std::scoped_lock lock{m_mutex}; + m_mnt_pairs.clear(); +} +std::string MntPoints::getHostDirectory(const std::string& guest_directory) { + std::scoped_lock lock{m_mutex}; + for (auto& pair : m_mnt_pairs) { + if (pair.guest_path.starts_with(guest_directory)) { + return pair.host_path + guest_directory; + } + } + // hack for relative path , get app0 and assuming it goes from there + for (auto& pair : m_mnt_pairs) { + if (pair.guest_path.starts_with("/app0")) { + std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/'); + return pair.host_path + guest_directory; + } + } + return ""; +} +std::string MntPoints::getHostFile(const std::string& guest_file) { + std::scoped_lock lock{m_mutex}; + + for (auto& pair : m_mnt_pairs) { + //horrible code but it works :D + int find = guest_file.find(pair.guest_path); + if (find == 0) { + std::string npath = guest_file.substr(pair.guest_path.size(), guest_file.size()-1); + std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/'); + return pair.host_path + npath; + } + } + return ""; +} +int HandleTable::createHandle() { + std::scoped_lock lock{m_mutex}; + auto* file = new File{}; + file->isDirectory = false; + file->isOpened = false; + + int existingFilesNum = m_files.size(); + + for (int index = 0; index < existingFilesNum; index++) { + if (m_files.at(index) == nullptr) { + m_files[index] = file; + return index + RESERVED_HANDLES; + } + } + + m_files.push_back(file); + + return m_files.size() + RESERVED_HANDLES - 1; +} +void HandleTable::deleteHandle(int d) { + std::scoped_lock lock{m_mutex}; + delete m_files.at(d - RESERVED_HANDLES); + m_files[d - RESERVED_HANDLES] = nullptr; +} + +File* HandleTable::getFile(int d) { + std::scoped_lock lock{m_mutex}; + return m_files.at(d - RESERVED_HANDLES); +} +File* HandleTable::getFile(const std::string& host_name) { + std::scoped_lock lock{m_mutex}; + for (auto* file : m_files) { + if (file != nullptr && file->m_host_name == host_name) { + return file; + } + } + return nullptr; +} +} // namespace Core::FileSys \ No newline at end of file diff --git a/src/core/file_sys/fs.h b/src/core/file_sys/fs.h new file mode 100644 index 000000000..75ea174c4 --- /dev/null +++ b/src/core/file_sys/fs.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include + +#include "common/fs_file.h" + +namespace Core::FileSys { + +class MntPoints { + public: + struct MntPair { + std::string host_path; + std::string guest_path; // e.g /app0/ + }; + + MntPoints() = default; + virtual ~MntPoints() = default; + void mount(const std::string& host_folder, const std::string& guest_folder); + void unmount(const std::string& path); + void unmountAll(); + std::string getHostDirectory(const std::string& guest_directory); + std::string MntPoints::getHostFile(const std::string& guest_file); + + private: + std::vector m_mnt_pairs; + std::mutex m_mutex; +}; + +struct File { + std::atomic_bool isOpened; + std::atomic_bool isDirectory; + std::string m_host_name; + std::string m_guest_name; + Common::FS::File f; + //std::vector dirents; + u32 dirents_index; + std::mutex m_mutex; +}; +class HandleTable { + public: + HandleTable() {} + virtual ~HandleTable() {} + int createHandle(); + void deleteHandle(int d); + File* getFile(int d); + File* getFile(const std::string& host_name); + + private: + std::vector m_files; + std::mutex m_mutex; +}; + +} // namespace Core::FileSys \ No newline at end of file diff --git a/src/core/hle/libraries/libkernel/file_system.cpp b/src/core/hle/libraries/libkernel/file_system.cpp index ca38cf79a..a26ae1b84 100644 --- a/src/core/hle/libraries/libkernel/file_system.cpp +++ b/src/core/hle/libraries/libkernel/file_system.cpp @@ -2,6 +2,9 @@ #include "common/debug.h" #include "core/hle/libraries/libkernel/file_system.h" #include "core/hle/libraries/libs.h" +#include "common/singleton.h" +#include "core/file_sys/fs.h" +#include namespace Core::Libraries::LibKernel { @@ -9,7 +12,22 @@ constexpr bool log_file_fs = true; // disable it to disable logging int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) { LOG_INFO_IF(log_file_fs, "sceKernelOpen path = {} flags = {:#x} mode = {:#x}\n", path, flags, mode); - return 0; + auto* h = Common::Singleton::Instance(); + auto* mnt = Common::Singleton::Instance(); + + //only open files support! + u32 handle = h->createHandle(); + auto* file = h->getFile(handle); + file->m_guest_name = path; + file->m_host_name = mnt->getHostFile(file->m_guest_name); + + bool result = file->f.open(file->m_host_name, Common::FS::OpenMode::ReadWrite); + if (!result) { + h->deleteHandle(handle); + return SCE_KERNEL_ERROR_EACCES; + } + file->isOpened = true; + return handle; } int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode) { @@ -21,12 +39,25 @@ int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 return result; } +size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) { + auto* h = Common::Singleton::Instance(); + auto* file = h->getFile(d); + size_t total_read = 0; + file->m_mutex.lock(); + for (int i = 0; i < iovcnt; i++) { + total_read+=file->f.reads(iov[i].iov_base, iov[i].iov_len); + } + file->m_mutex.unlock(); + return total_read; +} + void fileSystemSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen); LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open); //openOrbis (to check if it is valid out of OpenOrbis LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1, posix_open);// _open shoudld be equal to open function + LIB_FUNCTION("+WRlkKjZvag", "libkernel", 1, "libkernel", 1, 1, _readv); } } // namespace Core::Libraries::LibKernel diff --git a/src/core/hle/libraries/libkernel/file_system.h b/src/core/hle/libraries/libkernel/file_system.h index 010e952a3..0e557efd4 100644 --- a/src/core/hle/libraries/libkernel/file_system.h +++ b/src/core/hle/libraries/libkernel/file_system.h @@ -8,10 +8,15 @@ class SymbolsResolver; namespace Core::Libraries::LibKernel { +struct SceKernelIovec { + void *iov_base; + size_t iov_len; +}; + int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode); int PS4_SYSV_ABI posix_open(const char *path, int flags, /* SceKernelMode*/ u16 mode); void fileSystemSymbolsRegister(Loader::SymbolsResolver *sym); -} // namespace Core::Libraries::LibKernel +} // namespace Core::Libraries::LibKernel