From 3238fff0896281a8240298ccf4f46e2b3c045a5a Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Mon, 6 Nov 2023 20:47:18 +0200 Subject: [PATCH] partial support for sceKernelOpen directory --- src/core/file_sys/fs.cpp | 6 ++--- src/core/file_sys/fs.h | 6 +++-- src/core/hle/error_codes.h | 3 +++ .../hle/libraries/libkernel/file_system.cpp | 27 ++++++++++++++++--- .../hle/libraries/libkernel/file_system.h | 16 ++++++++++- 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index 02477e37..365b4c2d 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -53,7 +53,7 @@ int HandleTable::createHandle() { m_files.push_back(file); - return existingFilesNum + RESERVED_HANDLES - 1; + return m_files.size() + RESERVED_HANDLES - 1; } void HandleTable::deleteHandle(int d) { std::unique_lock lock{m_mutex}; @@ -64,10 +64,10 @@ File* HandleTable::getFile(int d) { std::unique_lock lock{m_mutex}; return m_files.at(d - RESERVED_HANDLES); } -File* HandleTable::getFile(const std::string& real_name) { +File* HandleTable::getFile(const std::string& host_name) { std::unique_lock lock{m_mutex}; for (auto* file : m_files) { - if (file != nullptr && file->m_real_name == real_name) { + if (file != nullptr && file->m_host_name == host_name) { return file; } } diff --git a/src/core/file_sys/fs.h b/src/core/file_sys/fs.h index 462093ba..3e49c035 100644 --- a/src/core/file_sys/fs.h +++ b/src/core/file_sys/fs.h @@ -27,15 +27,17 @@ class MntPoints { struct File { std::atomic_bool isOpened; std::atomic_bool isDirectory; - std::string m_real_name; + std::string m_host_name; + std::string m_guest_name; }; class HandleTable { + public: HandleTable() {} virtual ~HandleTable() {} int createHandle(); void deleteHandle(int d); File* getFile(int d); - File* getFile(const std::string& real_name); + File* getFile(const std::string& host_name); private: std::vector m_files; diff --git a/src/core/hle/error_codes.h b/src/core/hle/error_codes.h index cdb26407..3629342f 100644 --- a/src/core/hle/error_codes.h +++ b/src/core/hle/error_codes.h @@ -21,3 +21,6 @@ constexpr int SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; // Invalid constexpr int SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; // slot already used constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option + +//filesystem +constexpr int SCE_KERNEL_ERROR_EMFILE = 0x80020018;//limit of max descriptors reached diff --git a/src/core/hle/libraries/libkernel/file_system.cpp b/src/core/hle/libraries/libkernel/file_system.cpp index 85461025..58c68746 100644 --- a/src/core/hle/libraries/libkernel/file_system.cpp +++ b/src/core/hle/libraries/libkernel/file_system.cpp @@ -1,6 +1,10 @@ -#include "common/log.h" -#include "common/debug.h" #include "core/hle/libraries/libkernel/file_system.h" + +#include "common/debug.h" +#include "common/log.h" +#include "common/singleton.h" +#include "core/file_sys/fs.h" +#include "core/hle/error_codes.h" #include "core/hle/libraries/libs.h" namespace Core::Libraries::LibKernel { @@ -9,6 +13,23 @@ 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); + bool isDirectory = (flags & SCE_KERNEL_O_DIRECTORY) != 0; + bool create = (flags & SCE_KERNEL_O_CREAT) != 0; + + auto* h = Common::Singleton::Instance(); + auto* mnt = Common::Singleton::Instance(); + + u32 handle = h->createHandle(); + if (handle >= 2048) { // max descriptor reached + return SCE_KERNEL_ERROR_EMFILE; + } + auto* file = h->getFile(handle); + if (isDirectory) { + file->isDirectory = true; + file->m_guest_name = path; + file->m_host_name = mnt->getHostDirectory(file->m_guest_name); + } + return 0; } @@ -26,4 +47,4 @@ void fileSystemSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open); } -} // namespace Core::Libraries::LibKernel +} // 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 010e952a..7e58c541 100644 --- a/src/core/hle/libraries/libkernel/file_system.h +++ b/src/core/hle/libraries/libkernel/file_system.h @@ -7,6 +7,20 @@ class SymbolsResolver; } namespace Core::Libraries::LibKernel { +// open flags +constexpr u32 SCE_KERNEL_O_RDONLY = 0x0000; // Open as read-only +constexpr u32 SCE_KERNEL_O_WRONLY = 0x0001; // Open as write-only +constexpr u32 SCE_KERNEL_O_RDWR = 0x0002; // Open for reading and writing +constexpr u32 SCE_KERNEL_O_NONBLOCK = 0x0004; // Perform non - blocking operation +constexpr u32 SCE_KERNEL_O_APPEND = 0x0008; // Write by appending to the end of the file +constexpr u32 SCE_KERNEL_O_FSYNC = 0x0080; // Perform synchronized writing +constexpr u32 SCE_KERNEL_O_SYNC = 0x0080; // Perform synchronized writing +constexpr u32 SCE_KERNEL_O_CREAT = 0x0200; // Create a file(overwrite if it already exists) +constexpr u32 SCE_KERNEL_O_TRUNC = 0x0400; // Truncate the file size to 0(discard data if it already exists) +constexpr u32 SCE_KERNEL_O_EXCL = 0x0800; // Error will occur if the file to create already exists +constexpr u32 SCE_KERNEL_O_DSYNC = 0x1000; // Perform synchronized writing of the file content +constexpr u32 SCE_KERNEL_O_DIRECT = 0x00010000; // Use cache as little as possible +constexpr u32 SCE_KERNEL_O_DIRECTORY = 0x00020000; // Error will occur if not a directory int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode); @@ -14,4 +28,4 @@ int PS4_SYSV_ABI posix_open(const char *path, int flags, /* SceKernelMode*/ u16 void fileSystemSymbolsRegister(Loader::SymbolsResolver *sym); -} // namespace Core::Libraries::LibKernel +} // namespace Core::Libraries::LibKernel