From d41c1b032ea5d231e60901c87f674b09ecb8f235 Mon Sep 17 00:00:00 2001 From: Jean-Philip Desjardins Date: Mon, 12 Aug 2024 18:10:33 -0400 Subject: [PATCH] Implement Rename in IOMAN. --- Source/iop/Ioman_Device.h | 4 +++ Source/iop/Iop_Ioman.cpp | 37 ++++++++++++++++++++++++++++ Source/iop/Iop_Ioman.h | 1 + Source/iop/ioman/DirectoryDevice.cpp | 8 ++++++ Source/iop/ioman/DirectoryDevice.h | 1 + 5 files changed, 51 insertions(+) diff --git a/Source/iop/Ioman_Device.h b/Source/iop/Ioman_Device.h index 89c0c8b3ee..a5f92b9bf8 100644 --- a/Source/iop/Ioman_Device.h +++ b/Source/iop/Ioman_Device.h @@ -39,6 +39,10 @@ namespace Iop //Return false to indicate that device doesn't support GetStat. return false; } + virtual void Rename(const char*, const char*) + { + throw std::runtime_error("Renaming not supported."); + } }; typedef std::shared_ptr DevicePtr; diff --git a/Source/iop/Iop_Ioman.cpp b/Source/iop/Iop_Ioman.cpp index 7fd0d34164..9ad7df2ef1 100644 --- a/Source/iop/Iop_Ioman.cpp +++ b/Source/iop/Iop_Ioman.cpp @@ -44,6 +44,7 @@ using namespace Iop; #define FUNCTION_CHSTAT "ChStat" #define FUNCTION_ADDDRV "AddDrv" #define FUNCTION_DELDRV "DelDrv" +#define FUNCTION_RENAME "Rename" #define FUNCTION_MOUNT "Mount" #define FUNCTION_UMOUNT "Umount" #define FUNCTION_SEEK64 "Seek64" @@ -214,6 +215,9 @@ std::string CIoman::GetFunctionName(unsigned int functionId) const case 21: return FUNCTION_DELDRV; break; + case 25: + return FUNCTION_RENAME; + break; case 31: return FUNCTION_DEVCTL; break; @@ -530,6 +534,34 @@ uint32 CIoman::DelDrv(uint32 drvNamePtr) return -1; } +int32 CIoman::Rename(const char* srcPath, const char* dstPath) +{ + CLog::GetInstance().Print(LOG_NAME, FUNCTION_RENAME "(srcPath = '%s', dstPath = '%s');\r\n", + srcPath, dstPath); + int32 result = -1; + try + { + auto srcPathInfo = SplitPath(srcPath); + auto dstPathInfo = SplitPath(dstPath); + if(srcPathInfo.deviceName != dstPathInfo.deviceName) + { + throw std::runtime_error("Renaming files across devices not supported."); + } + auto deviceIterator = m_devices.find(srcPathInfo.deviceName); + if(deviceIterator == m_devices.end()) + { + throw std::runtime_error("Device not found."); + } + deviceIterator->second->Rename(srcPathInfo.devicePath.c_str(), dstPathInfo.devicePath.c_str()); + } + catch(const std::exception& except) + { + CLog::GetInstance().Warn(LOG_NAME, "%s: Error occured while trying to rename file '%s' to '%s'\r\n", + __FUNCTION__, srcPath, dstPath, except.what()); + } + return result; +} + int32 CIoman::DevCtlVirtual(CMIPS& context) { uint32 deviceNamePtr = context.m_State.nGPR[CMIPS::A0].nV0; @@ -1043,6 +1075,11 @@ void CIoman::Invoke(CMIPS& context, unsigned int functionId) context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(DelDrv( context.m_State.nGPR[CMIPS::A0].nV0)); break; + case 25: + context.m_State.nGPR[CMIPS::V0].nD0 = Rename( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV[0]]), + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A1].nV[0]])); + break; case 31: context.m_State.nGPR[CMIPS::V0].nD0 = DevCtlVirtual(context); break; diff --git a/Source/iop/Iop_Ioman.h b/Source/iop/Iop_Ioman.h index d40623be6b..8a22df4108 100644 --- a/Source/iop/Iop_Ioman.h +++ b/Source/iop/Iop_Ioman.h @@ -57,6 +57,7 @@ namespace Iop uint32 GetStat(const char*, Ioman::STAT*); int32 ChStat(const char*, Ioman::STAT*, uint32); uint32 DelDrv(uint32); + int32 Rename(const char*, const char*); int32 Mount(const char*, const char*); int32 Umount(const char*); uint64 Seek64(uint32, int64, uint32); diff --git a/Source/iop/ioman/DirectoryDevice.cpp b/Source/iop/ioman/DirectoryDevice.cpp index 6f82ff9673..333776c1c8 100644 --- a/Source/iop/ioman/DirectoryDevice.cpp +++ b/Source/iop/ioman/DirectoryDevice.cpp @@ -86,3 +86,11 @@ void CDirectoryDevice::MakeDirectory(const char* devicePath) throw std::runtime_error("Failed to create directory."); } } + +void CDirectoryDevice::Rename(const char* srcDevicePath, const char* dstDevicePath) +{ + auto basePath = GetBasePath(); + auto srcPath = Iop::PathUtils::MakeHostPath(basePath, srcDevicePath); + auto dstPath = Iop::PathUtils::MakeHostPath(basePath, dstDevicePath); + fs::rename(srcPath, dstPath); +} diff --git a/Source/iop/ioman/DirectoryDevice.h b/Source/iop/ioman/DirectoryDevice.h index 6c29aaa627..608179eb2f 100644 --- a/Source/iop/ioman/DirectoryDevice.h +++ b/Source/iop/ioman/DirectoryDevice.h @@ -15,6 +15,7 @@ namespace Iop Framework::CStream* GetFile(uint32, const char*) override; DirectoryIteratorPtr GetDirectory(const char*) override; void MakeDirectory(const char*) override; + void Rename(const char*, const char*) override; protected: virtual fs::path GetBasePath() = 0;