WFSI: Implement install finalization.

This commit is contained in:
Pierre Bourdon 2017-08-16 06:10:11 +02:00
parent 88580b8d5f
commit e6e00f6c8d
2 changed files with 40 additions and 4 deletions

View File

@ -98,6 +98,8 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
u32 tmd_addr = Memory::Read_U32(request.buffer_in);
u32 tmd_size = Memory::Read_U32(request.buffer_in + 4);
m_continue_install = Memory::Read_U32(request.buffer_in + 36);
INFO_LOG(IOS_WFS, "IOCTL_WFSI_PREPARE_DEVICE");
constexpr u32 MAX_TMD_SIZE = 0x4000;
@ -122,6 +124,13 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
memcpy(m_aes_key, ticket.GetTitleKey(m_ios.GetIOSC()).data(), sizeof(m_aes_key));
mbedtls_aes_setkey_dec(&m_aes_ctx, m_aes_key, 128);
m_title_id = m_tmd.GetTitleId();
m_title_id_str = StringFromFormat(
"%c%c%c%c", static_cast<char>(m_title_id >> 24), static_cast<char>(m_title_id >> 16),
static_cast<char>(m_title_id >> 8), static_cast<char>(m_title_id));
m_group_id = m_tmd.GetGroupId();
m_group_id_str = StringFromFormat("%c%c", m_group_id >> 8, m_group_id & 0xFF);
break;
}
@ -205,6 +214,23 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
break;
}
case IOCTL_WFSI_FINALIZE_IMPORT:
{
// TODO(wfs): Handle patches.
std::string title_install_dir =
StringFromFormat("/vol/%s/_install/%s", m_device_name.c_str(), m_title_id_str.c_str());
std::string title_final_dir = StringFromFormat("/vol/%s/title/%s/%s", m_device_name.c_str(),
m_group_id_str.c_str(), m_title_id_str.c_str());
File::Rename(WFS::NativePath(title_install_dir), WFS::NativePath(title_final_dir));
std::string tmd_path =
StringFromFormat("/vol/%s/title/%s/%s/meta/%016" PRIx64 ".tmd", m_device_name.c_str(),
m_group_id_str.c_str(), m_title_id_str.c_str(), m_title_id);
File::IOFile tmd_file(WFS::NativePath(tmd_path), "wb");
tmd_file.WriteBytes(m_tmd.GetBytes().data(), m_tmd.GetBytes().size());
break;
}
case IOCTL_WFSI_DELETE_TITLE:
// Bytes 0-4: ??
// Bytes 4-8: game id
@ -226,8 +252,8 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
break;
}
m_title_id_str = StringFromFormat(
"%c%c%c%c", static_cast<char>(m_title_id >> 56), static_cast<char>(m_title_id >> 48),
static_cast<char>(m_title_id >> 40), static_cast<char>(m_title_id >> 32));
"%c%c%c%c", static_cast<char>(m_title_id >> 24), static_cast<char>(m_title_id >> 16),
static_cast<char>(m_title_id >> 8), static_cast<char>(m_title_id));
IOS::ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(m_title_id);
m_group_id = tmd.GetGroupId();
@ -241,10 +267,11 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
break;
case IOCTL_WFSI_APPLY_TITLE_PROFILE:
{
INFO_LOG(IOS_WFS, "IOCTL_WFSI_APPLY_TITLE_PROFILE");
std::string install_directory = StringFromFormat("/vol/%s/_install", m_device_name.c_str());
if (File::IsDirectory(WFS::NativePath(install_directory)))
if (!m_continue_install && File::IsDirectory(WFS::NativePath(install_directory)))
{
File::DeleteDirRecursively(WFS::NativePath(install_directory));
}
@ -252,19 +279,22 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
m_base_extract_path =
StringFromFormat("%s/%s/content", install_directory.c_str(), m_title_id_str.c_str());
File::CreateFullPath(WFS::NativePath(m_base_extract_path));
File::CreateDir(WFS::NativePath(m_base_extract_path));
for (auto dir : {"work", "meta", "save"})
{
std::string path =
StringFromFormat("%s/%s/%s", install_directory.c_str(), m_title_id_str.c_str(), dir);
File::CreateFullPath(WFS::NativePath(path));
File::CreateDir(WFS::NativePath(path));
}
std::string group_path =
StringFromFormat("/vol/%s/title/%s", m_device_name.c_str(), m_group_id_str.c_str());
File::CreateFullPath(WFS::NativePath(group_path));
File::CreateDir(WFS::NativePath(group_path));
break;
}
case IOCTL_WFSI_GET_TMD:
{

View File

@ -58,6 +58,10 @@ private:
u16 m_group_id;
std::string m_group_id_str;
// Set on PREPARE_DEVICE when the next profile application should not delete
// temporary install files.
u32 m_continue_install = 0;
ARCUnpacker m_arc_unpacker;
enum
@ -73,6 +77,8 @@ private:
IOCTL_WFSI_IMPORT_CONTENT = 0x04,
IOCTL_WFSI_FINALIZE_CONTENT = 0x05,
IOCTL_WFSI_FINALIZE_IMPORT = 0x06,
IOCTL_WFSI_DELETE_TITLE = 0x17,
IOCTL_WFSI_IMPORT_TITLE = 0x2f,