From 4d988262593f315d758a613af8ac7c40cdd5ec8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Sun, 9 Feb 2014 22:53:48 +0100 Subject: [PATCH] Directory-related functions implemented * cellFsOpendir, cellFsReaddir, cellFsClosedir functions implemented. * vfsDirBase: m_entryes, GetEntryes renamed to m_entries, GetEntries respectively. * vfsLocalDir: Read() function added to get the entries one by one. * Moved IsExists() from vfsLocalDir to vfsDirBase to avoid "R6025 pure virtual function call" error. * Other minor changes in some functions of sys_fs --- rpcs3/Emu/Cell/PPUThread.cpp | 4 +- rpcs3/Emu/FS/vfsDirBase.cpp | 11 +++- rpcs3/Emu/FS/vfsDirBase.h | 6 +- rpcs3/Emu/FS/vfsLocalDir.cpp | 19 +++--- rpcs3/Emu/FS/vfsLocalDir.h | 5 +- rpcs3/Emu/SysCalls/SysCalls.h | 2 +- rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 75 ++++++++++++++++++------ rpcs3/stdafx.h | 2 + 8 files changed, 88 insertions(+), 36 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index e788d0e9f4..91dce7d6a8 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -65,11 +65,11 @@ void PPUThread::InitRegs() SetPc(pc); /* - const s32 thread_num = Emu.GetCPU().GetThread NumById(GetType(), GetId()); + const s32 thread_num = Emu.GetCPU().GetThreadNumById(GetType(), GetId()); if(thread_num < 0) { - ConLog.Error("GetThread NumById failed."); + ConLog.Error("GetThreadNumById failed."); Emu.Pause(); return; } diff --git a/rpcs3/Emu/FS/vfsDirBase.cpp b/rpcs3/Emu/FS/vfsDirBase.cpp index 97ff25cde9..8e5c945e36 100644 --- a/rpcs3/Emu/FS/vfsDirBase.cpp +++ b/rpcs3/Emu/FS/vfsDirBase.cpp @@ -27,15 +27,20 @@ bool vfsDirBase::IsOpened() const return !m_cwd.IsEmpty(); } -const Array& vfsDirBase::GetEntryes() const +bool vfsDirBase::IsExists(const wxString& path) const { - return m_entryes; + return wxDirExists(path); +} + +const Array& vfsDirBase::GetEntries() const +{ + return m_entries; } void vfsDirBase::Close() { m_cwd = wxEmptyString; - m_entryes.Clear(); + m_entries.Clear(); } wxString vfsDirBase::GetPath() const diff --git a/rpcs3/Emu/FS/vfsDirBase.h b/rpcs3/Emu/FS/vfsDirBase.h index 74f0b7ebef..a1d5301efe 100644 --- a/rpcs3/Emu/FS/vfsDirBase.h +++ b/rpcs3/Emu/FS/vfsDirBase.h @@ -31,7 +31,7 @@ class vfsDirBase { protected: wxString m_cwd; - Array m_entryes; + Array m_entries; public: vfsDirBase(const wxString& path); @@ -39,13 +39,13 @@ public: virtual bool Open(const wxString& path); virtual bool IsOpened() const; - virtual const Array& GetEntryes() const; + virtual bool IsExists(const wxString& path) const; + virtual const Array& GetEntries() const; virtual void Close(); virtual wxString GetPath() const; virtual bool Create(const wxString& path)=0; //virtual bool Create(const DirEntryInfo& info)=0; - virtual bool IsExists(const wxString& path) const=0; virtual bool Rename(const wxString& from, const wxString& to)=0; virtual bool Remove(const wxString& path)=0; }; \ No newline at end of file diff --git a/rpcs3/Emu/FS/vfsLocalDir.cpp b/rpcs3/Emu/FS/vfsLocalDir.cpp index 722665c220..291b34f9d2 100644 --- a/rpcs3/Emu/FS/vfsLocalDir.cpp +++ b/rpcs3/Emu/FS/vfsLocalDir.cpp @@ -2,7 +2,9 @@ #include "vfsLocalDir.h" #include -vfsLocalDir::vfsLocalDir(const wxString& path) : vfsDirBase(path) +vfsLocalDir::vfsLocalDir(const wxString& path) + : vfsDirBase(path) + , m_pos(0) { } @@ -25,7 +27,7 @@ bool vfsLocalDir::Open(const wxString& path) { wxString dir_path = path + wxFILE_SEP_PATH + name; - DirEntryInfo& info = m_entryes[m_entryes.Move(new DirEntryInfo())]; + DirEntryInfo& info = m_entries[m_entries.Move(new DirEntryInfo())]; info.name = name; info.flags |= wxDirExists(dir_path) ? DirEntry_TypeDir : DirEntry_TypeFile; @@ -37,16 +39,19 @@ bool vfsLocalDir::Open(const wxString& path) return true; } +const DirEntryInfo* vfsLocalDir::Read() +{ + if (m_pos >= m_entries.GetCount()) + return 0; + + return &m_entries[m_pos++]; +} + bool vfsLocalDir::Create(const wxString& path) { return wxFileName::Mkdir(path, 0777, wxPATH_MKDIR_FULL); } -bool vfsLocalDir::IsExists(const wxString& path) const -{ - return wxDirExists(path); -} - bool vfsLocalDir::Rename(const wxString& from, const wxString& to) { return false; diff --git a/rpcs3/Emu/FS/vfsLocalDir.h b/rpcs3/Emu/FS/vfsLocalDir.h index 7e4fb7fe15..860064aa13 100644 --- a/rpcs3/Emu/FS/vfsLocalDir.h +++ b/rpcs3/Emu/FS/vfsLocalDir.h @@ -3,14 +3,17 @@ class vfsLocalDir : public vfsDirBase { +private: + u32 m_pos; + public: vfsLocalDir(const wxString& path = wxEmptyString); virtual ~vfsLocalDir(); virtual bool Open(const wxString& path) override; + const DirEntryInfo* Read(); virtual bool Create(const wxString& path) override; - virtual bool IsExists(const wxString& path) const override; virtual bool Rename(const wxString& from, const wxString& to) override; virtual bool Remove(const wxString& path) override; }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index c40a4a8d01..212b58edef 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -228,7 +228,7 @@ extern int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread); extern int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite); extern int cellFsClose(u32 fd); extern int cellFsOpendir(u32 path_addr, mem32_t fd); -extern int cellFsReaddir(u32 fd, u32 dir_addr, mem64_t nread); +extern int cellFsReaddir(u32 fd, mem_ptr_t dir, mem64_t nread); extern int cellFsClosedir(u32 fd); extern int cellFsStat(u32 path_addr, mem_ptr_t sb); extern int cellFsFstat(u32 fd, mem_ptr_t sb); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index d78c3bc5c7..830f634421 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -132,21 +132,54 @@ int cellFsClose(u32 fd) int cellFsOpendir(u32 path_addr, mem32_t fd) { const wxString& path = Memory.ReadString(path_addr); - sys_fs.Error("cellFsOpendir(path_addr: 0x%x(%s), fd_addr: 0x%x)", path_addr, path.mb_str(), fd.GetAddr()); - if(!Memory.IsGoodAddr(path_addr) || !fd.IsGood()) return CELL_EFAULT; + sys_fs.Warning("cellFsOpendir(path=\"%s\", fd_addr=0x%x)", path.mb_str(), fd.GetAddr()); + + if(!Memory.IsGoodAddr(path_addr) || !fd.IsGood()) + return CELL_EFAULT; + wxString localPath; + Emu.GetVFS().GetDevice(path, localPath); + vfsLocalDir* dir = new vfsLocalDir(localPath); + if(!dir->Open(localPath)) + return CELL_ENOENT; + + fd = sys_fs.GetNewId(dir); return CELL_OK; } -int cellFsReaddir(u32 fd, u32 dir_addr, mem64_t nread) +int cellFsReaddir(u32 fd, mem_ptr_t dir, mem64_t nread) { - sys_fs.Error("cellFsReaddir(fd: %d, dir_addr: 0x%x, nread_addr: 0x%x)", fd, dir_addr, nread.GetAddr()); + sys_fs.Log("cellFsReaddir(fd=%d, dir_addr=0x%x, nread_addr=0x%x)", fd, dir.GetAddr(), nread.GetAddr()); + + vfsLocalDir* directory; + if(!sys_fs.CheckId(fd, directory)) + return CELL_ESRCH; + if(!dir.IsGood() || !nread.IsGood()) + return CELL_EFAULT; + + const DirEntryInfo* info = directory->Read(); + if(info) + { + nread = 1; + Memory.WriteString(dir.GetAddr()+2, info->name.mb_str()); + dir->d_namlen = info->name.Length(); + dir->d_type = (info->flags & 0x1) ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY; + } + else + { + nread = 0; + } + return CELL_OK; } int cellFsClosedir(u32 fd) { - sys_fs.Error("cellFsClosedir(fd: %d)", fd); + sys_fs.Log("cellFsClosedir(fd=%d)", fd); + + if(!Emu.GetIdManager().RemoveID(fd)) + return CELL_ESRCH; + return CELL_OK; } @@ -231,11 +264,12 @@ int cellFsFstat(u32 fd, mem_ptr_t sb) int cellFsMkdir(u32 path_addr, u32 mode) { const wxString& ps3_path = Memory.ReadString(path_addr); - wxString path; - Emu.GetVFS().GetDevice(ps3_path, path); - sys_fs.Log("cellFsMkdir(path: %s, mode: 0x%x)", path.mb_str(), mode); - if(wxDirExists(path)) return CELL_EEXIST; - if(!wxMkdir(path)) return CELL_EBUSY; + sys_fs.Log("cellFsMkdir(path=\"%s\", mode=0x%x)", ps3_path.mb_str(), mode); + + wxString localPath; + Emu.GetVFS().GetDevice(ps3_path, localPath); + if(wxDirExists(localPath)) return CELL_EEXIST; + if(!wxMkdir(localPath)) return CELL_EBUSY; return CELL_OK; } @@ -248,7 +282,7 @@ int cellFsRename(u32 from_addr, u32 to_addr) Emu.GetVFS().GetDevice(ps3_from, from); Emu.GetVFS().GetDevice(ps3_to, to); - sys_fs.Log("cellFsRename(from: %s, to: %s)", from.mb_str(), to.mb_str()); + sys_fs.Log("cellFsRename(from=\"%s\", to=\"%s\")", ps3_from.mb_str(), ps3_to.mb_str()); if(!wxFileExists(from)) return CELL_ENOENT; if(wxFileExists(to)) return CELL_EEXIST; if(!wxRenameFile(from, to)) return CELL_EBUSY; // (TODO: RenameFile(a,b) = CopyFile(a,b) + RemoveFile(a), therefore file "a" will not be removed if it is opened) @@ -258,20 +292,23 @@ int cellFsRename(u32 from_addr, u32 to_addr) int cellFsRmdir(u32 path_addr) { const wxString& ps3_path = Memory.ReadString(path_addr); - wxString path; - Emu.GetVFS().GetDevice(ps3_path, path); - sys_fs.Log("cellFsRmdir(path: %s)", path.mb_str()); - if(!wxDirExists(path)) return CELL_ENOENT; - if(!wxRmdir(path)) return CELL_EBUSY; // (TODO: Under certain conditions it is not able to delete the folder) + sys_fs.Log("cellFsRmdir(path=\"%s\")", ps3_path.mb_str()); + + wxString localPath; + Emu.GetVFS().GetDevice(ps3_path, localPath); + if(!wxDirExists(localPath)) return CELL_ENOENT; + if(!wxRmdir(localPath)) return CELL_EBUSY; // (TODO: Under certain conditions it is not able to delete the folder) return CELL_OK; } int cellFsUnlink(u32 path_addr) { const wxString& ps3_path = Memory.ReadString(path_addr); - wxString path; - Emu.GetVFS().GetDevice(ps3_path, path); - sys_fs.Error("cellFsUnlink(path: %s)", path.mb_str()); + sys_fs.Warning("cellFsUnlink(path=\"%s\")", ps3_path.mb_str()); + + wxString localPath; + Emu.GetVFS().GetDevice(ps3_path, localPath); + wxRemoveFile(localPath); return CELL_OK; } diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index 18a72ee8dc..9d71b93fe2 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -206,7 +206,9 @@ enum Status #include "Emu/System.h" #include "Emu/Cell/PPUThread.h" +#include "Emu/FS/vfsDirBase.h" #include "Emu/FS/vfsFileBase.h" +#include "Emu/FS/vfsLocalDir.h" #include "Emu/FS/vfsLocalFile.h" #include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsStream.h"