partial support for sceKernelOpen directory

This commit is contained in:
georgemoralis 2023-11-06 20:47:18 +02:00
parent 172fa7df6e
commit 3238fff089
5 changed files with 49 additions and 9 deletions

View File

@ -53,7 +53,7 @@ int HandleTable::createHandle() {
m_files.push_back(file); m_files.push_back(file);
return existingFilesNum + RESERVED_HANDLES - 1; return m_files.size() + RESERVED_HANDLES - 1;
} }
void HandleTable::deleteHandle(int d) { void HandleTable::deleteHandle(int d) {
std::unique_lock lock{m_mutex}; std::unique_lock lock{m_mutex};
@ -64,10 +64,10 @@ File* HandleTable::getFile(int d) {
std::unique_lock lock{m_mutex}; std::unique_lock lock{m_mutex};
return m_files.at(d - RESERVED_HANDLES); 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}; std::unique_lock lock{m_mutex};
for (auto* file : m_files) { 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; return file;
} }
} }

View File

@ -27,15 +27,17 @@ class MntPoints {
struct File { struct File {
std::atomic_bool isOpened; std::atomic_bool isOpened;
std::atomic_bool isDirectory; std::atomic_bool isDirectory;
std::string m_real_name; std::string m_host_name;
std::string m_guest_name;
}; };
class HandleTable { class HandleTable {
public:
HandleTable() {} HandleTable() {}
virtual ~HandleTable() {} virtual ~HandleTable() {}
int createHandle(); int createHandle();
void deleteHandle(int d); void deleteHandle(int d);
File* getFile(int d); File* getFile(int d);
File* getFile(const std::string& real_name); File* getFile(const std::string& host_name);
private: private:
std::vector<File*> m_files; std::vector<File*> m_files;

View File

@ -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_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_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option 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

View File

@ -1,6 +1,10 @@
#include "common/log.h"
#include "common/debug.h"
#include "core/hle/libraries/libkernel/file_system.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" #include "core/hle/libraries/libs.h"
namespace Core::Libraries::LibKernel { 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) { 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); 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<Core::FileSys::HandleTable>::Instance();
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::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; return 0;
} }

View File

@ -7,6 +7,20 @@ class SymbolsResolver;
} }
namespace Core::Libraries::LibKernel { 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); int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode);