mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 18:45:36 +00:00
some work for fs trying to run libpng demo of openorbis (not working)
This commit is contained in:
parent
62731c7331
commit
379037e2fd
@ -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
|
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
|
set(HOST_SOURCES src/Emulator/Host/controller.cpp
|
||||||
|
@ -40,6 +40,8 @@ bool File::read(void* data, u64 size) const {
|
|||||||
return isOpen() && std::fread(data, 1, size, m_file) == size;
|
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) {
|
bool File::seek(s64 offset, SeekMode mode) {
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
if (!isOpen() || _fseeki64(m_file, offset, getSeekMode(mode)) != 0) {
|
if (!isOpen() || _fseeki64(m_file, offset, getSeekMode(mode)) != 0) {
|
||||||
|
@ -31,6 +31,7 @@ class File {
|
|||||||
bool open(const std::string& path, OpenMode mode = OpenMode::Read);
|
bool open(const std::string& path, OpenMode mode = OpenMode::Read);
|
||||||
bool close();
|
bool close();
|
||||||
bool read(void* data, u64 size) const;
|
bool read(void* data, u64 size) const;
|
||||||
|
size_t reads(void* data, u64 size) const;
|
||||||
bool write(std::span<const u08> data);
|
bool write(std::span<const u08> data);
|
||||||
bool seek(s64 offset, SeekMode mode);
|
bool seek(s64 offset, SeekMode mode);
|
||||||
u64 getFileSize();
|
u64 getFileSize();
|
||||||
|
91
src/core/file_sys/fs.cpp
Normal file
91
src/core/file_sys/fs.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "fs.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
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
|
54
src/core/file_sys/fs.h
Normal file
54
src/core/file_sys/fs.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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<MntPair> 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<Common::FS::DirEntry> 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<File*> m_files;
|
||||||
|
std::mutex m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core::FileSys
|
@ -2,6 +2,9 @@
|
|||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "core/hle/libraries/libkernel/file_system.h"
|
#include "core/hle/libraries/libkernel/file_system.h"
|
||||||
#include "core/hle/libraries/libs.h"
|
#include "core/hle/libraries/libs.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "core/file_sys/fs.h"
|
||||||
|
#include <core/hle/error_codes.h>
|
||||||
|
|
||||||
namespace Core::Libraries::LibKernel {
|
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) {
|
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);
|
||||||
return 0;
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::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) {
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) {
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::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) {
|
void fileSystemSymbolsRegister(Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
||||||
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
||||||
|
|
||||||
//openOrbis (to check if it is valid out of OpenOrbis
|
//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("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
|
} // namespace Core::Libraries::LibKernel
|
||||||
|
@ -8,10 +8,15 @@ class SymbolsResolver;
|
|||||||
|
|
||||||
namespace Core::Libraries::LibKernel {
|
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 sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode);
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_open(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);
|
void fileSystemSymbolsRegister(Loader::SymbolsResolver *sym);
|
||||||
|
|
||||||
} // namespace Core::Libraries::LibKernel
|
} // namespace Core::Libraries::LibKernel
|
||||||
|
Loading…
Reference in New Issue
Block a user