From 40a3868cbcf25b693385b9b10ed5f963e9910d70 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 20 Oct 2023 15:39:23 +0300 Subject: [PATCH] we can create directories now --- src/Core/PS4/HLE/ErrorCodes.h | 1 + .../LibKernel/FileSystem/file_system.cpp | 34 +++++++++++++++++-- .../LibKernel/FileSystem/file_system.h | 6 +++- src/Emulator/Host/fs.cpp | 18 ++++++++++ src/Emulator/Host/fs.h | 11 +++--- 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/Core/PS4/HLE/ErrorCodes.h b/src/Core/PS4/HLE/ErrorCodes.h index 06c3014d..0e6d3c19 100644 --- a/src/Core/PS4/HLE/ErrorCodes.h +++ b/src/Core/PS4/HLE/ErrorCodes.h @@ -4,6 +4,7 @@ constexpr int SCE_OK = 0; constexpr int SCE_KERNEL_ERROR_EBADF = 0x80020009; constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000c; // Insufficient memory constexpr int SCE_KERNEL_ERROR_EFAULT = 0x8002000e; // Invalid address pointer +constexpr int SCE_KERNEL_ERROR_ENOTDIR = 0x80020014; constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016; // null or invalid states constexpr int SCE_KERNEL_ERROR_EAGAIN = 0x80020023; // Memory cannot be allocated constexpr int SCE_KERNEL_ERROR_ENAMETOOLONG = 0x8002003f; // character strings exceeds valid size diff --git a/src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_system.cpp b/src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_system.cpp index cdf35595..2154ad59 100644 --- a/src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_system.cpp +++ b/src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_system.cpp @@ -1,13 +1,43 @@ #include "file_system.h" #include #include +#include +#include "Emulator/Host/fs.h" +#include + namespace Emulator::HLE::Libraries::LibKernel::FileSystem { constexpr bool log_file_fs = true; // disable it to disable logging -int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) { +int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) { LOG_INFO_IF(log_file_fs, "sceKernelOpen path = {} flags = {} mode = {}\n", path, log_hex_full(flags), log_hex_full(mode)); - return 0; + + bool isDirectory = (flags & SCE_KERNEL_O_DIRECTORY) != 0; + bool createFileOrDir = (flags & SCE_KERNEL_O_CREAT) != 0; + + auto* h = singleton::instance(); + auto* mnt = singleton::instance(); + + u32 handle = h->createHandle().value();//TODO check if overflows + + Emulator::Host::Fs::File file = h->getFile(handle); + + file.guest_path = path; + if (isDirectory) { + file.host_path = mnt->getHostDirectory(path); + if (!std::filesystem::exists(file.host_path)) { //directory doesn't exist + if (createFileOrDir) { //if we have a create flag create it + if (std::filesystem::create_directories(file.host_path)) { + return handle; + } else { + return SCE_KERNEL_ERROR_ENOTDIR; + } + } else { + return SCE_KERNEL_ERROR_ENOTDIR; + } + } + } + return handle; } } // namespace Emulator::HLE::Libraries::LibKernel::FileSystem \ No newline at end of file diff --git a/src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_system.h b/src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_system.h index 98f090f0..1651a281 100644 --- a/src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_system.h +++ b/src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_system.h @@ -2,6 +2,10 @@ #include namespace Emulator::HLE::Libraries::LibKernel::FileSystem { + +constexpr u32 SCE_KERNEL_O_CREAT = 0x0200; +constexpr u32 SCE_KERNEL_O_DIRECTORY = 0x00020000; + int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode); -} \ No newline at end of file +} // namespace Emulator::HLE::Libraries::LibKernel::FileSystem \ No newline at end of file diff --git a/src/Emulator/Host/fs.cpp b/src/Emulator/Host/fs.cpp index 38bce9db..b03e941f 100644 --- a/src/Emulator/Host/fs.cpp +++ b/src/Emulator/Host/fs.cpp @@ -1,4 +1,5 @@ #include "fs.h" +#include namespace Emulator::Host::Fs { void MntPoints::mount(const std::string& host_folder, const std::string& guest_folder) { @@ -12,4 +13,21 @@ void MntPoints::mount(const std::string& host_folder, const std::string& guest_f } void MntPoints::unMount(const std::string& path) {} void MntPoints::unMountAll() {} +std::string MntPoints::getHostDirectory(const std::string& guest_directory) { + Lib::LockMutexGuard 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(); +} } // namespace Emulator::Host::Fs \ No newline at end of file diff --git a/src/Emulator/Host/fs.h b/src/Emulator/Host/fs.h index 45071f47..7fcf33a7 100644 --- a/src/Emulator/Host/fs.h +++ b/src/Emulator/Host/fs.h @@ -24,16 +24,17 @@ class MntPoints { 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); private: std::vector m_mnt_pairs; Lib::Mutex m_mutex; - }; struct File { - bool valid = false; // Το descriptor ειναι οντως ανοιχτο; - FILE* file; // File handle του αρχειο - std::filesystem::path path; // Path του στο host FS + bool valid = false; // Το descriptor ειναι οντως ανοιχτο; + FILE* file; // File handle του αρχειο + std::filesystem::path host_path; // Path in host FS + std::string guest_path; // Path in PS4 FS File() : valid(true) {} }; @@ -87,6 +88,8 @@ class HandleTable { return handle; } + File getFile(u32 handle) { return files[handle]; } + void freeHandle(u32 handle) { if (handle >= files.size()) { // Στανταρ invalid