From aa20220627631b58fba7512cfed3483f9925261e Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Tue, 30 Mar 2021 16:20:36 +0200 Subject: [PATCH] HostFS: Implement opendir and closedir --- pcsx2/IopBios.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++++++ pcsx2/IopBios.h | 7 ++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/pcsx2/IopBios.cpp b/pcsx2/IopBios.cpp index 2645a23877..6f8bfb6f72 100644 --- a/pcsx2/IopBios.cpp +++ b/pcsx2/IopBios.cpp @@ -235,6 +235,42 @@ public: } }; +class HostDir : public IOManDir +{ +public: + DIR *dir; + + HostDir(DIR *native_dir) + { + dir = native_dir; + } + + virtual ~HostDir() = default; + + static int open(IOManDir **dir, const std::string &full_path) + { + struct stat stats; + const std::string path = host_path(full_path.substr(full_path.find(':') + 1)); + + if(!(::stat(path.c_str(), &stats) && S_ISDIR(stats.st_mode))) + { + *dir = new HostDir(::opendir(path.c_str())); + if (!*dir) + return -IOP_ENOMEM; + + return 0; + } else + return -IOP_ENOMEM; + } + + virtual void close() + { + ::closedir(dir); + delete this; + } + +}; + namespace ioman { const int firstfd = 0x100; const int maxfds = 0x100; @@ -397,6 +433,47 @@ namespace ioman { return 0; } + int dopen_HLE() + { + IOManDir *dir = NULL; + const std::string path = Ra0; + + int err = HostDir::open(&dir, path); + + if (err != 0 || !dir) + { + if (err == 0) + err = -IOP_EIO; + if (dir) + dir->close(); + v0 = err; + } + else + { + v0 = allocfd(dir); + if ((s32)v0 < 0) + dir->close(); + } + + pc = ra; + return 1; + } + + int dclose_HLE() + { + s32 dir = a0; + + if (getfd(dir)) + { + freefd(dir); + v0 = 0; + pc = ra; + return 1; + } + + return 0; + } + int lseek_HLE() { s32 fd = a0; @@ -708,6 +785,8 @@ irxHLE irxImportHLE(const std::string &libname, u16 index) EXPORT_H( 8, lseek) EXPORT_H( 11, mkdir) EXPORT_H( 12, rmdir) + EXPORT_H( 13, dopen) + EXPORT_H( 14, dclose) END_MODULE return 0; diff --git a/pcsx2/IopBios.h b/pcsx2/IopBios.h index 2168062ce6..0bf0dea6d8 100644 --- a/pcsx2/IopBios.h +++ b/pcsx2/IopBios.h @@ -55,7 +55,12 @@ class IOManDir { // Don't think about it until we know the loaded ioman version. // The dirent structure changed between versions. public: - virtual void close(); + static int open(IOManDir **dir, const std::string &full_path) + { + return -IOP_ENODEV; + } + + virtual void close() = 0; }; typedef int (*irxHLE)(); // return 1 if handled, otherwise 0