Merge pull request #7598 from sepalani/wfsi

WFSI: Fix Dragon Quest X (all-in-one, v2, v3) installers
This commit is contained in:
Pierre Bourdon 2018-12-03 02:39:47 +01:00 committed by GitHub
commit f5e9135912
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 19 deletions

View File

@ -268,7 +268,7 @@ constexpr std::array<MemoryValues, 41> ios_memory_values = {
RAM_VENDOR, 0x93600000, 0x93620000, 0,
},
{
59, 0x3b1c21, 0x101811, MEM1_SIZE,
59, 0x3b2421, 0x101811, MEM1_SIZE,
MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END,
MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN,
0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION,

View File

@ -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
@ -116,6 +117,15 @@ void WFSI::SetImportTitleIdAndGroupId(u64 tid, u16 gid)
m_import_group_id_str = GroupIdStr(gid);
}
void WFSI::FinalizePatchInstall()
{
const std::string current_title_dir =
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 std::string patch_dir = current_title_dir + "/_patch";
File::CopyDir(WFS::NativePath(patch_dir), WFS::NativePath(current_title_dir), true);
}
IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
{
s32 return_error_code = IPC_SUCCESS;
@ -257,7 +267,43 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
case IOCTL_WFSI_FINALIZE_TITLE_INSTALL:
{
std::string tmd_path;
if (m_patch_type == NOT_A_PATCH)
switch (m_patch_type)
{
case PATCH_TYPE_2:
{
// Delete content's default.dol
const std::string title_content_dir =
StringFromFormat("/vol/%s/title/%s/%s/content/", m_device_name.c_str(),
m_current_group_id_str.c_str(), m_current_title_id_str.c_str());
File::Delete(WFS::NativePath(title_content_dir + "default.dol"));
// Copy content's _default.dol to patch's directory
const std::string patch_dir =
StringFromFormat("/vol/%s/title/%s/%s/_patch/", m_device_name.c_str(),
m_current_group_id_str.c_str(), m_current_title_id_str.c_str());
const std::string patch_content_dir = patch_dir + "content/";
File::CreateDir(WFS::NativePath(patch_dir));
File::CreateDir(WFS::NativePath(patch_content_dir));
File::Rename(WFS::NativePath(title_content_dir + "_default.dol"),
WFS::NativePath(patch_content_dir + "default.dol"));
FinalizePatchInstall();
[[fallthrough]];
}
case PATCH_TYPE_1:
{
std::string patch_dir =
StringFromFormat("/vol/%s/title/%s/%s/_patch", m_device_name.c_str(),
m_current_group_id_str.c_str(), m_current_title_id_str.c_str());
File::DeleteDirRecursively(WFS::NativePath(patch_dir));
tmd_path = StringFromFormat("/vol/%s/title/%s/%s/meta/%016" PRIx64 ".tmd",
m_device_name.c_str(), m_current_group_id_str.c_str(),
m_current_title_id_str.c_str(), m_import_title_id);
break;
}
case NOT_A_PATCH:
{
std::string title_install_dir = StringFromFormat("/vol/%s/_install/%s", m_device_name.c_str(),
m_import_title_id_str.c_str());
@ -269,17 +315,8 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
tmd_path = StringFromFormat("/vol/%s/title/%s/%s/meta/%016" PRIx64 ".tmd",
m_device_name.c_str(), m_import_group_id_str.c_str(),
m_import_title_id_str.c_str(), m_import_title_id);
break;
}
else
{
std::string patch_dir =
StringFromFormat("/vol/%s/title/%s/%s/_patch", m_device_name.c_str(),
m_current_group_id_str.c_str(), m_current_title_id_str.c_str());
File::DeleteDirRecursively(WFS::NativePath(patch_dir));
tmd_path = StringFromFormat("/vol/%s/title/%s/%s/meta/%016" PRIx64 ".tmd",
m_device_name.c_str(), m_current_group_id_str.c_str(),
m_current_title_id_str.c_str(), m_import_title_id);
}
File::IOFile tmd_file(WFS::NativePath(tmd_path), "wb");
@ -291,13 +328,7 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
{
INFO_LOG(IOS_WFS, "IOCTL_WFSI_FINALIZE_PATCH_INSTALL");
if (m_patch_type != NOT_A_PATCH)
{
std::string current_title_dir =
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());
std::string patch_dir = current_title_dir + "/_patch";
File::CopyDir(WFS::NativePath(patch_dir), WFS::NativePath(current_title_dir), true);
}
FinalizePatchInstall();
break;
}
@ -308,6 +339,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<u16>(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<IOS::HLE::Device::WFSSRV>(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);

View File

@ -46,6 +46,7 @@ private:
void SetCurrentTitleIdAndGroupId(u64 tid, u16 gid);
void SetImportTitleIdAndGroupId(u64 tid, u16 gid);
void FinalizePatchInstall();
s32 CancelTitleImport(bool continue_install);
s32 CancelPatchImport(bool continue_install);
@ -95,6 +96,7 @@ private:
IOCTL_WFSI_FINALIZE_TITLE_INSTALL = 0x06,
IOCTL_WFSI_DELETE_TITLE = 0x17,
IOCTL_WFSI_CHANGE_TITLE = 0x18,
IOCTL_WFSI_GET_VERSION = 0x1b,

View File

@ -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;

View File

@ -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.