some fs work for openorbis (WIP)
This commit is contained in:
parent
57ddf939d4
commit
ff43fec76a
|
@ -147,7 +147,7 @@ add_executable(shadps4
|
||||||
src/emuTimer.h
|
src/emuTimer.h
|
||||||
src/core/hle/libraries/libkernel/time_management.cpp
|
src/core/hle/libraries/libkernel/time_management.cpp
|
||||||
src/core/hle/libraries/libkernel/time_management.h
|
src/core/hle/libraries/libkernel/time_management.h
|
||||||
)
|
"src/common/io_file.cpp" "src/common/io_file.h")
|
||||||
|
|
||||||
create_target_directory_groups(shadps4)
|
create_target_directory_groups(shadps4)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include "io_file.h"
|
||||||
|
|
||||||
|
//#include "helpers.hpp"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// 64 bit offsets for MSVC
|
||||||
|
#define fseeko _fseeki64
|
||||||
|
#define ftello _ftelli64
|
||||||
|
#define fileno _fileno
|
||||||
|
|
||||||
|
#pragma warning(disable : 4996)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <io.h> // For _chsize_s
|
||||||
|
#else
|
||||||
|
#include <unistd.h> // For ftruncate
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IOFile::IOFile(const std::filesystem::path& path, const char* permissions) : handle(nullptr) {
|
||||||
|
open(path, permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::open(const std::filesystem::path& path, const char* permissions) {
|
||||||
|
const auto str =
|
||||||
|
path.string(); // For some reason converting paths directly with c_str() doesn't work
|
||||||
|
return open(str.c_str(), permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::open(const char* filename, const char* permissions) {
|
||||||
|
// If this IOFile is already bound to an open file descriptor, release the file descriptor
|
||||||
|
// To avoid leaking it and/or erroneously locking the file
|
||||||
|
if (isOpen()) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
handle = std::fopen(filename, permissions);
|
||||||
|
return isOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOFile::close() {
|
||||||
|
if (isOpen()) {
|
||||||
|
fclose(handle);
|
||||||
|
handle = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> IOFile::read(void* data, std::size_t length, std::size_t dataSize) {
|
||||||
|
if (!isOpen()) {
|
||||||
|
return {false, std::numeric_limits<std::size_t>::max()};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return {true, 0};
|
||||||
|
return {true, std::fread(data, dataSize, length, handle)};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> IOFile::write(const void* data, std::size_t length,
|
||||||
|
std::size_t dataSize) {
|
||||||
|
if (!isOpen()) {
|
||||||
|
return {false, std::numeric_limits<std::size_t>::max()};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 0) {
|
||||||
|
return {true, 0};
|
||||||
|
} else {
|
||||||
|
return {true, std::fwrite(data, dataSize, length, handle)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> IOFile::readBytes(void* data, std::size_t count) {
|
||||||
|
return read(data, count, sizeof(std::uint8_t));
|
||||||
|
}
|
||||||
|
std::pair<bool, std::size_t> IOFile::writeBytes(const void* data, std::size_t count) {
|
||||||
|
return write(data, count, sizeof(std::uint8_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::uint64_t> IOFile::size() {
|
||||||
|
if (!isOpen())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
std::uint64_t pos = ftello(handle);
|
||||||
|
if (fseeko(handle, 0, SEEK_END) != 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t size = ftello(handle);
|
||||||
|
if ((size != pos) && (fseeko(handle, pos, SEEK_SET) != 0)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::seek(std::int64_t offset, int origin) {
|
||||||
|
if (!isOpen() || fseeko(handle, offset, origin) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::flush() {
|
||||||
|
if (!isOpen() || fflush(handle))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::rewind() {
|
||||||
|
return seek(0, SEEK_SET);
|
||||||
|
}
|
||||||
|
FILE* IOFile::getHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOFile::setAppDataDir(const std::filesystem::path& dir) {
|
||||||
|
//if (dir == "")
|
||||||
|
// Helpers::panic("Failed to set app data directory");
|
||||||
|
appData = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOFile::setSize(std::uint64_t size) {
|
||||||
|
if (!isOpen())
|
||||||
|
return false;
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
success = _chsize_s(_fileno(handle), size) == 0;
|
||||||
|
#else
|
||||||
|
success = ftruncate(fileno(handle), size) == 0;
|
||||||
|
#endif
|
||||||
|
fflush(handle);
|
||||||
|
return success;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
class IOFile {
|
||||||
|
FILE* handle = nullptr;
|
||||||
|
static inline std::filesystem::path appData =""; // Directory for holding app data. AppData on Windows
|
||||||
|
|
||||||
|
public:
|
||||||
|
IOFile() : handle(nullptr) {}
|
||||||
|
IOFile(FILE* handle) : handle(handle) {}
|
||||||
|
IOFile(const std::filesystem::path& path, const char* permissions = "rb");
|
||||||
|
|
||||||
|
bool isOpen() {
|
||||||
|
return handle != nullptr;
|
||||||
|
}
|
||||||
|
bool open(const std::filesystem::path& path, const char* permissions = "rb");
|
||||||
|
bool open(const char* filename, const char* permissions = "rb");
|
||||||
|
void close();
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> read(void* data, std::size_t length, std::size_t dataSize);
|
||||||
|
std::pair<bool, std::size_t> readBytes(void* data, std::size_t count);
|
||||||
|
|
||||||
|
std::pair<bool, std::size_t> write(const void* data, std::size_t length, std::size_t dataSize);
|
||||||
|
std::pair<bool, std::size_t> writeBytes(const void* data, std::size_t count);
|
||||||
|
|
||||||
|
std::optional<std::uint64_t> size();
|
||||||
|
|
||||||
|
bool seek(std::int64_t offset, int origin = SEEK_SET);
|
||||||
|
bool rewind();
|
||||||
|
bool flush();
|
||||||
|
FILE* getHandle();
|
||||||
|
static void setAppDataDir(const std::filesystem::path& dir);
|
||||||
|
static std::filesystem::path getAppData() {
|
||||||
|
return appData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the size of the file to "size" and returns whether it succeeded or not
|
||||||
|
bool setSize(std::uint64_t size);
|
||||||
|
};
|
|
@ -4,6 +4,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/fs_file.h"
|
#include "common/fs_file.h"
|
||||||
|
#include <common/io_file.h>
|
||||||
|
|
||||||
namespace Core::FileSys {
|
namespace Core::FileSys {
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ struct File {
|
||||||
std::atomic_bool isDirectory;
|
std::atomic_bool isDirectory;
|
||||||
std::string m_host_name;
|
std::string m_host_name;
|
||||||
std::string m_guest_name;
|
std::string m_guest_name;
|
||||||
Common::FS::File f;
|
IOFile f;
|
||||||
//std::vector<Common::FS::DirEntry> dirents;
|
//std::vector<Common::FS::DirEntry> dirents;
|
||||||
u32 dirents_index;
|
u32 dirents_index;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
|
|
|
@ -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 <core/file_sys/fs.h>
|
||||||
|
#include <common/singleton.h>
|
||||||
|
#include <core/hle/error_codes.h>
|
||||||
|
|
||||||
namespace Core::Libraries::LibKernel {
|
namespace Core::Libraries::LibKernel {
|
||||||
|
|
||||||
|
@ -9,10 +12,25 @@ 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);
|
||||||
|
if (!result) {
|
||||||
|
h->deleteHandle(handle);
|
||||||
|
return SCE_KERNEL_ERROR_EACCES;
|
||||||
|
}
|
||||||
|
file->isOpened = true;
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI open(const char* path, int flags, /* SceKernelMode*/ u16 mode) {
|
int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode) {
|
||||||
LOG_INFO_IF(log_file_fs, "posix open redirect to sceKernelOpen\n");
|
LOG_INFO_IF(log_file_fs, "posix open redirect to sceKernelOpen\n");
|
||||||
int result = sceKernelOpen(path, flags, mode);
|
int result = sceKernelOpen(path, flags, mode);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
|
@ -21,9 +39,25 @@ int PS4_SYSV_ABI open(const char* path, int flags, /* SceKernelMode*/ u16 mode)
|
||||||
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.readBytes(iov[i].iov_base,iov[i].iov_len).second;
|
||||||
|
}
|
||||||
|
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, open);
|
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
||||||
|
LIB_FUNCTION("+WRlkKjZvag", "libkernel", 1, "libkernel", 1, 1, _readv);
|
||||||
|
|
||||||
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Core::Libraries::LibKernel
|
} // namespace Core::Libraries::LibKernel
|
||||||
|
|
|
@ -8,9 +8,14 @@ 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 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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue