diff --git a/Source/Core/Core/IOS/WFS/WFSI.cpp b/Source/Core/Core/IOS/WFS/WFSI.cpp index 50eca7a2ac..0694ca0c42 100644 --- a/Source/Core/Core/IOS/WFS/WFSI.cpp +++ b/Source/Core/Core/IOS/WFS/WFSI.cpp @@ -18,6 +18,7 @@ #include "Core/HW/Memmap.h" #include "Core/IOS/ES/ES.h" #include "Core/IOS/ES/Formats.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/WFS/WFSSRV.h" namespace @@ -308,6 +309,33 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request) WARN_LOG(IOS_WFS, "IOCTL_WFSI_DELETE_TITLE: unimplemented"); break; + case IOCTL_WFSI_CHANGE_TITLE: + { + u64 title_id = Memory::Read_U64(request.buffer_in); + u16 group_id = Memory::Read_U16(request.buffer_in + 0x1C); + + // TODO: Handle permissions + SetCurrentTitleIdAndGroupId(title_id, group_id); + + // Change home directory + const std::string homedir_path = + StringFromFormat("/vol/%s/title/%s/%s/", m_device_name.c_str(), + m_current_group_id_str.c_str(), m_current_title_id_str.c_str()); + const u16 homedir_path_len = static_cast(homedir_path.size()); + INFO_LOG(IOS_WFS, "IOCTL_WFSI_CHANGE_TITLE: %s (path_len: 0x%x)", homedir_path.c_str(), + homedir_path_len); + + return_error_code = -3; + if (homedir_path_len > 0x1FD) + break; + auto device = IOS::HLE::GetIOS()->GetDeviceByName("/dev/usb/wfssrv"); + if (!device) + break; + std::static_pointer_cast(device)->SetHomeDir(homedir_path); + return_error_code = IPC_SUCCESS; + break; + } + case IOCTL_WFSI_GET_VERSION: INFO_LOG(IOS_WFS, "IOCTL_WFSI_GET_VERSION"); Memory::Write_U32(0x20, request.buffer_out); diff --git a/Source/Core/Core/IOS/WFS/WFSI.h b/Source/Core/Core/IOS/WFS/WFSI.h index 949c075fbb..c862493775 100644 --- a/Source/Core/Core/IOS/WFS/WFSI.h +++ b/Source/Core/Core/IOS/WFS/WFSI.h @@ -95,6 +95,7 @@ private: IOCTL_WFSI_FINALIZE_TITLE_INSTALL = 0x06, IOCTL_WFSI_DELETE_TITLE = 0x17, + IOCTL_WFSI_CHANGE_TITLE = 0x18, IOCTL_WFSI_GET_VERSION = 0x1b, diff --git a/Source/Core/Core/IOS/WFS/WFSSRV.cpp b/Source/Core/Core/IOS/WFS/WFSSRV.cpp index 352a7ef171..d09c91b0e4 100644 --- a/Source/Core/Core/IOS/WFS/WFSSRV.cpp +++ b/Source/Core/Core/IOS/WFS/WFSSRV.cpp @@ -383,6 +383,11 @@ s32 WFSSRV::Rename(std::string source, std::string dest) const return IPC_SUCCESS; } +void WFSSRV::SetHomeDir(const std::string& home_directory) +{ + m_home_directory = home_directory; +} + std::string WFSSRV::NormalizePath(const std::string& path) const { std::string expanded; diff --git a/Source/Core/Core/IOS/WFS/WFSSRV.h b/Source/Core/Core/IOS/WFS/WFSSRV.h index 82bc00710e..ed27a6b726 100644 --- a/Source/Core/Core/IOS/WFS/WFSSRV.h +++ b/Source/Core/Core/IOS/WFS/WFSSRV.h @@ -39,6 +39,7 @@ public: IPCCommandResult IOCtl(const IOCtlRequest& request) override; s32 Rename(std::string source, std::string dest) const; + void SetHomeDir(const std::string& home_dir); private: // WFS device name, e.g. msc01/msc02.