WFS/NAND: Better handle GID.

This commit is contained in:
Pierre Bourdon 2017-08-06 17:11:25 +02:00
parent f8e5f4296f
commit f810f1edb2
5 changed files with 62 additions and 8 deletions

View File

@ -58,6 +58,35 @@ std::string GetTMDFileName(u64 _titleID, FromWhichRoot from)
return GetTitleContentPath(_titleID, from) + "title.tmd";
}
bool IsTitlePath(const std::string& path, FromWhichRoot from, u64* title_id)
{
std::string expected_prefix = RootUserPath(from) + "/title/";
if (!StringBeginsWith(path, expected_prefix))
{
return false;
}
// Try to find a title ID in the remaining path.
std::string subdirectory = path.substr(expected_prefix.size());
std::vector<std::string> components = SplitString(subdirectory, '/');
if (components.size() < 2)
{
return false;
}
u32 title_id_high, title_id_low;
if (!AsciiToHex(components[0], title_id_high) || !AsciiToHex(components[1], title_id_low))
{
return false;
}
if (title_id != nullptr)
{
*title_id = (static_cast<u64>(title_id_high) << 32) | title_id_low;
}
return true;
}
std::string EscapeFileName(const std::string& filename)
{
// Prevent paths from containing special names like ., .., ..., ...., and so on

View File

@ -29,6 +29,9 @@ std::string GetTitleDataPath(u64 _titleID, FromWhichRoot from);
std::string GetTitleContentPath(u64 _titleID, FromWhichRoot from);
std::string GetTMDFileName(u64 _titleID, FromWhichRoot from);
// Returns whether a path is within an installed title's directory.
bool IsTitlePath(const std::string& path, FromWhichRoot from, u64* title_id = nullptr);
// Escapes characters that are invalid or have special meanings in the host file system
std::string EscapeFileName(const std::string& filename);
// Escapes characters that are invalid or have special meanings in the host file system

View File

@ -21,6 +21,8 @@
#include "Common/NandPaths.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/SystemTimers.h"
#include "Core/IOS/ES/ES.h"
#include "Core/IOS/ES/Formats.h"
#include "Core/IOS/FS/FileIO.h"
namespace IOS
@ -326,6 +328,18 @@ IPCCommandResult FS::GetAttribute(const IOCtlRequest& request)
u8 OtherPerm = 0x3; // read/write
u8 Attributes = 0x00; // no attributes
// Hack: if the path that is being accessed is within an installed title directory, get the
// UID/GID from the installed title TMD.
u64 title_id;
if (IsTitlePath(Filename, Common::FROM_SESSION_ROOT, &title_id))
{
IOS::ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(title_id);
if (tmd.IsValid())
{
GroupID = tmd.GetGroupId();
}
}
if (File::IsDirectory(Filename))
{
INFO_LOG(IOS_FILEIO, "FS: GET_ATTR Directory %s - all permission flags are set",

View File

@ -216,6 +216,7 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
break;
case IOCTL_WFSI_INIT:
{
INFO_LOG(IOS, "IOCTL_WFSI_INIT");
if (GetIOS()->GetES()->GetTitleId(&m_title_id) < 0)
{
@ -223,7 +224,15 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
return_error_code = IPC_EINVAL;
break;
}
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));
IOS::ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(m_title_id);
m_group_id = tmd.GetGroupId();
m_group_id_str = StringFromFormat("%c%c", m_group_id >> 8, m_group_id & 0xFF);
break;
}
case IOCTL_WFSI_SET_DEVICE_NAME:
INFO_LOG(IOS, "IOCTL_WFSI_SET_DEVICE_NAME");
@ -233,20 +242,16 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
case IOCTL_WFSI_APPLY_TITLE_PROFILE:
INFO_LOG(IOS, "IOCTL_WFSI_APPLY_TITLE_PROFILE");
m_base_extract_path = StringFromFormat(
"/vol/%s/_install/%c%c%c%c/content", m_device_name.c_str(),
static_cast<char>(m_tmd.GetTitleId() >> 24), static_cast<char>(m_tmd.GetTitleId() >> 16),
static_cast<char>(m_tmd.GetTitleId() >> 8), static_cast<char>(m_tmd.GetTitleId()));
m_base_extract_path = StringFromFormat("/vol/%s/_install/%s/content", m_device_name.c_str(),
m_title_id_str.c_str());
File::CreateFullPath(WFS::NativePath(m_base_extract_path));
break;
case IOCTL_WFSI_LOAD_DOL:
{
std::string path = StringFromFormat(
"/vol/%s/_install/%c%c%c%c/content", m_device_name.c_str(),
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));
std::string path = StringFromFormat("/vol/%s/title/%s/%s/content", m_device_name.c_str(),
m_group_id_str.c_str(), m_title_id_str.c_str());
u32 dol_addr = Memory::Read_U32(request.buffer_in + 0x18);
u32 max_dol_size = Memory::Read_U32(request.buffer_in + 0x14);

View File

@ -53,6 +53,9 @@ private:
IOS::ES::TMDReader m_tmd;
std::string m_base_extract_path;
u64 m_title_id;
std::string m_title_id_str;
u16 m_group_id;
std::string m_group_id_str;
ARCUnpacker m_arc_unpacker;