mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-06 02:33:15 +00:00
More Fixes for Separate Update (#1487)
* handle getdents + fix condition + add info to description * fix not handling dents errors * to not overwrite it, only gather separate update entries when normal folder is done * fix always setting entries to 0 and guest name including "UPDATE" * reset indexes on completion * don't use concat, fixes long standing bug * make sce_module module loading take both paths into account
This commit is contained in:
parent
3c8e25e8e4
commit
aa5c1c10df
6 changed files with 119 additions and 29 deletions
|
@ -199,4 +199,14 @@ void HandleTable::CreateStdHandles() {
|
|||
setup("/dev/stderr", new Devices::Logger("stderr", true)); // stderr
|
||||
}
|
||||
|
||||
int HandleTable::GetFileDescriptor(File* file) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
auto it = std::find(m_files.begin(), m_files.end(), file);
|
||||
|
||||
if (it != m_files.end()) {
|
||||
return std::distance(m_files.begin(), it);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Core::FileSys
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <vector>
|
||||
#include <tsl/robin_map.h>
|
||||
#include "common/io_file.h"
|
||||
#include "common/logging/formatter.h"
|
||||
#include "core/devices/base_device.h"
|
||||
|
||||
namespace Core::FileSys {
|
||||
|
@ -37,6 +38,14 @@ public:
|
|||
std::filesystem::path GetHostPath(std::string_view guest_directory,
|
||||
bool* is_read_only = nullptr);
|
||||
|
||||
const MntPair* GetMountFromHostPath(const std::string& host_path) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
const auto it = std::ranges::find_if(m_mnt_pairs, [&](const MntPair& mount) {
|
||||
return host_path.starts_with(std::string{fmt::UTF(mount.host_path.u8string()).data});
|
||||
});
|
||||
return it == m_mnt_pairs.end() ? nullptr : &*it;
|
||||
}
|
||||
|
||||
const MntPair* GetMount(const std::string& guest_path) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
const auto it = std::ranges::find_if(m_mnt_pairs, [&](const auto& mount) {
|
||||
|
@ -86,6 +95,7 @@ public:
|
|||
void DeleteHandle(int d);
|
||||
File* GetFile(int d);
|
||||
File* GetFile(const std::filesystem::path& host_name);
|
||||
int GetFileDescriptor(File* file);
|
||||
|
||||
void CreateStdHandles();
|
||||
|
||||
|
|
|
@ -695,12 +695,66 @@ static int GetDents(int fd, char* buf, int nbytes, s64* basep) {
|
|||
return sizeof(OrbisKernelDirent);
|
||||
}
|
||||
|
||||
static int HandleSeparateUpdateDents(int fd, char* buf, int nbytes, s64* basep) {
|
||||
int dir_entries = 0;
|
||||
|
||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||
auto* file = h->GetFile(fd);
|
||||
auto update_dir_name = std::string{fmt::UTF(file->m_host_name.u8string()).data};
|
||||
auto mount = mnt->GetMountFromHostPath(update_dir_name);
|
||||
auto suffix = std::string{fmt::UTF(mount->host_path.u8string()).data};
|
||||
|
||||
size_t pos = update_dir_name.find("-UPDATE");
|
||||
if (pos != std::string::npos) {
|
||||
update_dir_name.erase(pos, 7);
|
||||
auto guest_name = mount->mount + "/" + update_dir_name.substr(suffix.size() + 1);
|
||||
int descriptor;
|
||||
|
||||
auto existent_folder = h->GetFile(update_dir_name);
|
||||
if (!existent_folder) {
|
||||
u32 handle = h->CreateHandle();
|
||||
auto* new_file = h->GetFile(handle);
|
||||
new_file->type = Core::FileSys::FileType::Directory;
|
||||
new_file->m_guest_name = guest_name;
|
||||
new_file->m_host_name = update_dir_name;
|
||||
if (!std::filesystem::is_directory(new_file->m_host_name)) {
|
||||
h->DeleteHandle(handle);
|
||||
return dir_entries;
|
||||
} else {
|
||||
new_file->dirents = GetDirectoryEntries(new_file->m_host_name);
|
||||
new_file->dirents_index = 0;
|
||||
}
|
||||
new_file->is_opened = true;
|
||||
descriptor = h->GetFileDescriptor(new_file);
|
||||
} else {
|
||||
descriptor = h->GetFileDescriptor(existent_folder);
|
||||
}
|
||||
|
||||
dir_entries = GetDents(descriptor, buf, nbytes, basep);
|
||||
if (dir_entries == ORBIS_OK && existent_folder) {
|
||||
existent_folder->dirents_index = 0;
|
||||
file->dirents_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return dir_entries;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelGetdents(int fd, char* buf, int nbytes) {
|
||||
return GetDents(fd, buf, nbytes, nullptr);
|
||||
int a = GetDents(fd, buf, nbytes, nullptr);
|
||||
if (a == ORBIS_OK) {
|
||||
return HandleSeparateUpdateDents(fd, buf, nbytes, nullptr);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelGetdirentries(int fd, char* buf, int nbytes, s64* basep) {
|
||||
return GetDents(fd, buf, nbytes, basep);
|
||||
int a = GetDents(fd, buf, nbytes, basep);
|
||||
if (a == ORBIS_OK) {
|
||||
return HandleSeparateUpdateDents(fd, buf, nbytes, basep);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue