mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-03-29 06:59:43 -06:00
* Rename SceKernelIovec to OrbisKernelIovec Fixes the naming scheme to match the rest of the project. * Type fixups Noticed this while working on the actual thing this PR is about. * More type fixups * Update file_system.cpp * Abstract directory handling * Clang * Directory fstat * Fix dirent loading logic * PfsDirectory size Seemed to be hardcoded when I ran tests, so I've hardcoded it here. Also fixed up the reclen-aligning logic based on hardware observations. * GetDents cleanup Bring back the bytes < 512 error return from before, as that's still something that can be checked for out here. I've also swapped the file type stuff to run from a switch case, so that the check for invalid file type can be used as the default case * Support reading directories * getdents For PfsDirectory, getdents behaves like read does on normal directories. Since dirents are stored internally with a different struct, this means getdents has to convert the dirents before returning data. For NormalDirectory, getdents is identical to read, so it can just call read and set the basep output. * Directory readv * Directory preadv Since the file mutex is locked before these calls, messing with dirents_index like this shouldn't cause any weird side effects. * return ORBIS_OK instead of 0 to better align with our coding standards. * Directory lseek * Un-modify CMakePresets.json I keep this modified locally for Linux, but accidentally pushed it. * Clang * Fix mac compile * Potential windows compile fix? * Filename fix * Fix normal directory d_reclen * Comment cleanup * Remove unnecessary dirent conversion logic On real hardware, the records are still returned with the same reclen, despite the change in structure. * PfsDirectory dirents_index fixes Some weird stuff happens once you reach eof on directories. Thankfully, PfsDirectories are rather tame in this regard. * Change comment * Rewrite normal directory reads The logic for these seems to behave like a normal file, so instead of tracking a dirents_index, keep an internal buffer representing the file contents, and copy that to output buffers as needed. * Update pfs_directory.cpp * Clang * Fix normal dirents When rewriting the code, I forgot to account for the increased reclen value for the last dirent in the buffer. * PfsDirectory::lseek fixes Based on some additional tests, it seems like lseek unconditionally returns dirents_index, not the actual file position. Also fixed some bugs with the logic for calculating the proper offset when games do wonky things, and fixed a potential area where games could crash. * Downgrade stat and fstat log to debug These functions can get pretty spammy. * PfsDirectory: Properly track if end of file is reached Using the metric `dirents_index < directory_content_size` fails when `directory_content_size` is larger than the actual directory size we report. Since, from what I can tell, PfsDirectories shouldn't ever report more than 0x10000 bytes for size, this change is necessary. * Revert "PfsDirectory: Properly track if end of file is reached" I need to do some hardware tests to see if all this excess logic is actually necessary. * Fix PfsDirectory directory_size Turns out, if your game has over 1000 files in a folder, it will actually cause the size to increase. * Update copyright date * Move devices and directories into file_sys I've also updated the copyright dates on all these files. * C++ style type casts * Remove unnecessary memset * Use a vector for the data buffer Simplifies logic for freeing the buffer, based on review suggestions. * Fix potential oob array access * Change type casts in Create function * Clang * std::memcpy instead of memcpy * NormalDirectory::lseek cleanup * Create constants for directory alignment values. * Use const wherever possible * Includes cleanup
75 lines
2.2 KiB
C++
75 lines
2.2 KiB
C++
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include "common/types.h"
|
|
#include "core/libraries/kernel/time.h"
|
|
|
|
namespace Core::Loader {
|
|
class SymbolsResolver;
|
|
}
|
|
|
|
namespace Libraries::Kernel {
|
|
|
|
constexpr int ORBIS_MAX_PATH = 255;
|
|
|
|
struct OrbisKernelIovec {
|
|
void* iov_base;
|
|
std::size_t iov_len;
|
|
};
|
|
|
|
struct OrbisKernelStat {
|
|
u32 st_dev;
|
|
u32 st_ino;
|
|
u16 st_mode;
|
|
u16 st_nlink;
|
|
u32 st_uid;
|
|
u32 st_gid;
|
|
u32 st_rdev;
|
|
OrbisKernelTimespec st_atim;
|
|
OrbisKernelTimespec st_mtim;
|
|
OrbisKernelTimespec st_ctim;
|
|
s64 st_size;
|
|
s64 st_blocks;
|
|
u32 st_blksize;
|
|
u32 st_flags;
|
|
u32 st_gen;
|
|
s32 st_lspare;
|
|
OrbisKernelTimespec st_birthtim;
|
|
u32 : (8 / 2) * (16 - static_cast<int>(sizeof(OrbisKernelTimespec)));
|
|
u32 : (8 / 2) * (16 - static_cast<int>(sizeof(OrbisKernelTimespec)));
|
|
};
|
|
|
|
struct OrbisKernelDirent {
|
|
u32 d_fileno; /* file number of entry */
|
|
u16 d_reclen; /* length of this record */
|
|
u8 d_type; /* file type, see below */
|
|
u8 d_namlen; /* length of string in d_name */
|
|
char d_name[ORBIS_MAX_PATH + 1]; /* name must be no longer than this */
|
|
};
|
|
|
|
// flags for Open
|
|
constexpr int ORBIS_KERNEL_O_RDONLY = 0x0000;
|
|
constexpr int ORBIS_KERNEL_O_WRONLY = 0x0001;
|
|
constexpr int ORBIS_KERNEL_O_RDWR = 0x0002;
|
|
|
|
constexpr int ORBIS_KERNEL_O_NONBLOCK = 0x0004;
|
|
constexpr int ORBIS_KERNEL_O_APPEND = 0x0008;
|
|
constexpr int ORBIS_KERNEL_O_FSYNC = 0x0080;
|
|
constexpr int ORBIS_KERNEL_O_SYNC = 0x0080;
|
|
constexpr int ORBIS_KERNEL_O_CREAT = 0x0200;
|
|
constexpr int ORBIS_KERNEL_O_TRUNC = 0x0400;
|
|
constexpr int ORBIS_KERNEL_O_EXCL = 0x0800;
|
|
constexpr int ORBIS_KERNEL_O_DSYNC = 0x1000;
|
|
constexpr int ORBIS_KERNEL_O_DIRECT = 0x00010000;
|
|
constexpr int ORBIS_KERNEL_O_DIRECTORY = 0x00020000;
|
|
|
|
s64 PS4_SYSV_ABI sceKernelWrite(s32 fd, const void* buf, u64 nbytes);
|
|
s64 PS4_SYSV_ABI sceKernelRead(s32 fd, void* buf, u64 nbytes);
|
|
s64 PS4_SYSV_ABI sceKernelPread(s32 fd, void* buf, u64 nbytes, s64 offset);
|
|
s64 PS4_SYSV_ABI sceKernelPwrite(s32 fd, void* buf, u64 nbytes, s64 offset);
|
|
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym);
|
|
|
|
} // namespace Libraries::Kernel
|