@@ -29,11 +29,11 @@ struct TitleContext
{
void Clear();
void DoState(PointerWrap& p);
void Update(const IOS::ES::TMDReader& tmd_, const IOS::ES::TicketReader& ticket_,
void Update(const ES::TMDReader& tmd_, const ES::TicketReader& ticket_,
DiscIO::Platform platform);

IOS::ES::TicketReader ticket;
IOS::ES::TMDReader tmd;
ES::TicketReader ticket;
ES::TMDReader tmd;
bool active = false;
bool first_change = true;
};
@@ -43,7 +43,7 @@ class ESDevice final : public Device
public:
ESDevice(Kernel& ios, const std::string& device_name);

ReturnCode DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& ticket);
ReturnCode DIVerify(const ES::TMDReader& tmd, const ES::TicketReader& ticket);
bool LaunchTitle(u64 title_id, bool skip_reload = false);

void DoState(PointerWrap& p) override;
@@ -57,7 +57,7 @@ class ESDevice final : public Device
void DoState(PointerWrap& p);

bool valid = false;
IOS::ES::TMDReader tmd;
ES::TMDReader tmd;
IOSC::Handle key_handle = 0;
struct ContentContext
{
@@ -87,9 +87,9 @@ class ESDevice final : public Device
No = false,
};

IOS::ES::TMDReader FindImportTMD(u64 title_id) const;
IOS::ES::TMDReader FindInstalledTMD(u64 title_id) const;
IOS::ES::TicketReader FindSignedTicket(u64 title_id) const;
ES::TMDReader FindImportTMD(u64 title_id) const;
ES::TMDReader FindInstalledTMD(u64 title_id) const;
ES::TicketReader FindSignedTicket(u64 title_id) const;

// Get installed titles (in /title) without checking for TMDs at all.
std::vector<u64> GetInstalledTitles() const;
@@ -98,14 +98,14 @@ class ESDevice final : public Device
// Get titles for which there is a ticket (in /ticket).
std::vector<u64> GetTitlesWithTickets() const;

std::vector<IOS::ES::Content>
GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd,
std::vector<ES::Content>
GetStoredContentsFromTMD(const ES::TMDReader& tmd,
CheckContentHashes check_content_hashes = CheckContentHashes::No) const;
u32 GetSharedContentsCount() const;
std::vector<std::array<u8, 20>> GetSharedContents() const;

// Title contents
s32 OpenContent(const IOS::ES::TMDReader& tmd, u16 content_index, u32 uid);
s32 OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid);
ReturnCode CloseContent(u32 cfd, u32 uid);
s32 ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid);
s32 SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid);
@@ -158,8 +158,7 @@ class ESDevice final : public Device
ReturnCode GetV0TicketFromView(const u8* ticket_view, u8* ticket) const;
ReturnCode GetTicketFromView(const u8* ticket_view, u8* ticket, u32* ticket_size) const;

ReturnCode SetUpStreamKey(u32 uid, const u8* ticket_view, const IOS::ES::TMDReader& tmd,
u32* handle);
ReturnCode SetUpStreamKey(u32 uid, const u8* ticket_view, const ES::TMDReader& tmd, u32* handle);

bool CreateTitleDirectories(u64 title_id, u16 group_id) const;

@@ -178,11 +177,11 @@ class ESDevice final : public Device
// On success, if issuer_handle is non-null, the IOSC object for the issuer will be written to it.
// The caller is responsible for using IOSC_DeleteObject.
ReturnCode VerifyContainer(VerifyContainerType type, VerifyMode mode,
const IOS::ES::SignedBlobReader& signed_blob,
const ES::SignedBlobReader& signed_blob,
const std::vector<u8>& cert_chain, u32* issuer_handle = nullptr);
ReturnCode VerifyContainer(VerifyContainerType type, VerifyMode mode,
const IOS::ES::CertReader& certificate,
const std::vector<u8>& cert_chain, u32 certificate_iosc_handle);
const ES::CertReader& certificate, const std::vector<u8>& cert_chain,
u32 certificate_iosc_handle);

private:
enum
@@ -316,9 +315,8 @@ class ESDevice final : public Device
IPCCommandResult GetTitleCount(const IOCtlVRequest& request);
IPCCommandResult GetTitles(const IOCtlVRequest& request);
IPCCommandResult GetBoot2Version(const IOCtlVRequest& request);
IPCCommandResult GetStoredContentsCount(const IOS::ES::TMDReader& tmd,
const IOCtlVRequest& request);
IPCCommandResult GetStoredContents(const IOS::ES::TMDReader& tmd, const IOCtlVRequest& request);
IPCCommandResult GetStoredContentsCount(const ES::TMDReader& tmd, const IOCtlVRequest& request);
IPCCommandResult GetStoredContents(const ES::TMDReader& tmd, const IOCtlVRequest& request);
IPCCommandResult GetStoredContentsCount(const IOCtlVRequest& request);
IPCCommandResult GetStoredContents(const IOCtlVRequest& request);
IPCCommandResult GetTMDStoredContentsCount(const IOCtlVRequest& request);
@@ -350,32 +348,32 @@ class ESDevice final : public Device
bool IsActiveTitlePermittedByTicket(const u8* ticket_view) const;

ReturnCode CheckStreamKeyPermissions(u32 uid, const u8* ticket_view,
const IOS::ES::TMDReader& tmd) const;
const ES::TMDReader& tmd) const;

bool IsIssuerCorrect(VerifyContainerType type, const IOS::ES::CertReader& issuer_cert) const;
bool IsIssuerCorrect(VerifyContainerType type, const ES::CertReader& issuer_cert) const;
ReturnCode ReadCertStore(std::vector<u8>* buffer) const;
ReturnCode WriteNewCertToStore(const IOS::ES::CertReader& cert);
ReturnCode WriteNewCertToStore(const ES::CertReader& cert);

// Start a title import.
bool InitImport(const IOS::ES::TMDReader& tmd);
bool InitImport(const ES::TMDReader& tmd);
// Clean up the import content directory and move it back to /title.
bool FinishImport(const IOS::ES::TMDReader& tmd);
bool FinishImport(const ES::TMDReader& tmd);
// Write a TMD for a title in /import atomically.
bool WriteImportTMD(const IOS::ES::TMDReader& tmd);
bool WriteImportTMD(const ES::TMDReader& tmd);
// Finish stale imports and clear the import directory.
void FinishStaleImport(u64 title_id);
void FinishAllStaleImports();

std::string GetContentPath(u64 title_id, const IOS::ES::Content& content,
const IOS::ES::SharedContentMap& map) const;
std::string GetContentPath(u64 title_id, const IOS::ES::Content& content) const;
std::string GetContentPath(u64 title_id, const ES::Content& content,
const ES::SharedContentMap& map) const;
std::string GetContentPath(u64 title_id, const ES::Content& content) const;

struct OpenedContent
{
bool m_opened = false;
FS::Fd m_fd;
u64 m_title_id = 0;
IOS::ES::Content m_content;
ES::Content m_content;
u32 m_uid = 0;
};

@@ -380,10 +380,10 @@ std::vector<u8> TicketReader::GetRawTicket(u64 ticket_id_to_find) const
{
for (size_t i = 0; i < GetNumberOfTickets(); ++i)
{
const auto ticket_begin = m_bytes.begin() + sizeof(IOS::ES::Ticket) * i;
const u64 ticket_id = Common::swap64(&*ticket_begin + offsetof(IOS::ES::Ticket, ticket_id));
const auto ticket_begin = m_bytes.begin() + sizeof(ES::Ticket) * i;
const u64 ticket_id = Common::swap64(&*ticket_begin + offsetof(ES::Ticket, ticket_id));
if (ticket_id == ticket_id_to_find)
return std::vector<u8>(ticket_begin, ticket_begin + sizeof(IOS::ES::Ticket));
return std::vector<u8>(ticket_begin, ticket_begin + sizeof(ES::Ticket));
}
return {};
}
@@ -120,7 +120,7 @@ IPCCommandResult ESDevice::Sign(const IOCtlVRequest& request)
ReturnCode ESDevice::VerifySign(const std::vector<u8>& hash, const std::vector<u8>& ecc_signature,
const std::vector<u8>& certs_bytes)
{
const std::map<std::string, IOS::ES::CertReader> certs = IOS::ES::ParseCertChain(certs_bytes);
const std::map<std::string, ES::CertReader> certs = ES::ParseCertChain(certs_bytes);
if (certs.empty())
return ES_EINVAL;

@@ -129,13 +129,13 @@ ReturnCode ESDevice::VerifySign(const std::vector<u8>& hash, const std::vector<u
});
if (ap_iterator == certs.end())
return ES_UNKNOWN_ISSUER;
const IOS::ES::CertReader& ap = ap_iterator->second;
const ES::CertReader& ap = ap_iterator->second;

const auto ap_issuers = SplitString(ap.GetIssuer(), '-');
const auto ng_iterator = ap_issuers.size() > 1 ? certs.find(*ap_issuers.rbegin()) : certs.end();
if (ng_iterator == certs.end())
return ES_UNKNOWN_ISSUER;
const IOS::ES::CertReader& ng = ng_iterator->second;
const ES::CertReader& ng = ng_iterator->second;

IOSC& iosc = m_ios.GetIOSC();
IOSC::Handle ng_cert;
@@ -24,7 +24,7 @@

namespace IOS::HLE
{
static IOS::ES::TMDReader FindTMD(FS::FileSystem* fs, u64 title_id, const std::string& tmd_path)
static ES::TMDReader FindTMD(FS::FileSystem* fs, u64 title_id, const std::string& tmd_path)
{
const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, tmd_path, FS::Mode::Read);
if (!file)
@@ -34,21 +34,21 @@ static IOS::ES::TMDReader FindTMD(FS::FileSystem* fs, u64 title_id, const std::s
if (!file->Read(tmd_bytes.data(), tmd_bytes.size()))
return {};

return IOS::ES::TMDReader{std::move(tmd_bytes)};
return ES::TMDReader{std::move(tmd_bytes)};
}

IOS::ES::TMDReader ESDevice::FindImportTMD(u64 title_id) const
ES::TMDReader ESDevice::FindImportTMD(u64 title_id) const
{
return FindTMD(m_ios.GetFS().get(), title_id,
Common::GetImportTitlePath(title_id) + "/content/title.tmd");
}

IOS::ES::TMDReader ESDevice::FindInstalledTMD(u64 title_id) const
ES::TMDReader ESDevice::FindInstalledTMD(u64 title_id) const
{
return FindTMD(m_ios.GetFS().get(), title_id, Common::GetTMDFileName(title_id));
}

IOS::ES::TicketReader ESDevice::FindSignedTicket(u64 title_id) const
ES::TicketReader ESDevice::FindSignedTicket(u64 title_id) const
{
const std::string path = Common::GetTicketFileName(title_id);
const auto ticket_file = m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::Read);
@@ -59,7 +59,7 @@ IOS::ES::TicketReader ESDevice::FindSignedTicket(u64 title_id) const
if (!ticket_file->Read(signed_ticket.data(), signed_ticket.size()))
return {};

return IOS::ES::TicketReader{std::move(signed_ticket)};
return ES::TicketReader{std::move(signed_ticket)};
}

static bool IsValidPartOfTitleID(const std::string& string)
@@ -164,20 +164,20 @@ std::vector<u64> ESDevice::GetTitlesWithTickets() const
return title_ids;
}

std::vector<IOS::ES::Content>
ESDevice::GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd,
std::vector<ES::Content>
ESDevice::GetStoredContentsFromTMD(const ES::TMDReader& tmd,
CheckContentHashes check_content_hashes) const
{
if (!tmd.IsValid())
return {};

const IOS::ES::SharedContentMap map{m_ios.GetFS()};
const std::vector<IOS::ES::Content> contents = tmd.GetContents();
const ES::SharedContentMap map{m_ios.GetFS()};
const std::vector<ES::Content> contents = tmd.GetContents();

std::vector<IOS::ES::Content> stored_contents;
std::vector<ES::Content> stored_contents;

std::copy_if(contents.begin(), contents.end(), std::back_inserter(stored_contents),
[this, &tmd, &map, check_content_hashes](const IOS::ES::Content& content) {
[this, &tmd, &map, check_content_hashes](const ES::Content& content) {
const auto fs = m_ios.GetFS();

const std::string path = GetContentPath(tmd.GetTitleId(), content, map);
@@ -217,7 +217,7 @@ u32 ESDevice::GetSharedContentsCount() const

std::vector<std::array<u8, 20>> ESDevice::GetSharedContents() const
{
const IOS::ES::SharedContentMap map{m_ios.GetFS()};
const ES::SharedContentMap map{m_ios.GetFS()};
return map.GetHashes();
}

@@ -267,7 +267,7 @@ bool ESDevice::CreateTitleDirectories(u64 title_id, u16 group_id) const
return false;
}

IOS::ES::UIDSys uid_sys{fs};
ES::UIDSys uid_sys{fs};
const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id);
if (fs->SetMetadata(0, data_dir, uid, group_id, 0, data_dir_modes) != FS::ResultCode::Success)
{
@@ -278,7 +278,7 @@ bool ESDevice::CreateTitleDirectories(u64 title_id, u16 group_id) const
return true;
}

bool ESDevice::InitImport(const IOS::ES::TMDReader& tmd)
bool ESDevice::InitImport(const ES::TMDReader& tmd)
{
if (!CreateTitleDirectories(tmd.GetTitleId(), tmd.GetGroupId()))
return false;
@@ -310,7 +310,7 @@ bool ESDevice::InitImport(const IOS::ES::TMDReader& tmd)
return true;
}

bool ESDevice::FinishImport(const IOS::ES::TMDReader& tmd)
bool ESDevice::FinishImport(const ES::TMDReader& tmd)
{
const auto fs = m_ios.GetFS();
const u64 title_id = tmd.GetTitleId();
@@ -343,7 +343,7 @@ bool ESDevice::FinishImport(const IOS::ES::TMDReader& tmd)
return true;
}

bool ESDevice::WriteImportTMD(const IOS::ES::TMDReader& tmd)
bool ESDevice::WriteImportTMD(const ES::TMDReader& tmd)
{
const auto fs = m_ios.GetFS();
const std::string tmd_path = "/tmp/title.tmd";
@@ -381,17 +381,17 @@ void ESDevice::FinishAllStaleImports()
FinishStaleImport(title_id);
}

std::string ESDevice::GetContentPath(const u64 title_id, const IOS::ES::Content& content,
const IOS::ES::SharedContentMap& content_map) const
std::string ESDevice::GetContentPath(const u64 title_id, const ES::Content& content,
const ES::SharedContentMap& content_map) const
{
if (content.IsShared())
return content_map.GetFilenameFromSHA1(content.sha1).value_or("");
return fmt::format("{}/{:08x}.app", Common::GetTitleContentPath(title_id), content.id);
}

std::string ESDevice::GetContentPath(const u64 title_id, const IOS::ES::Content& content) const
std::string ESDevice::GetContentPath(const u64 title_id, const ES::Content& content) const
{
IOS::ES::SharedContentMap map{m_ios.GetFS()};
ES::SharedContentMap map{m_ios.GetFS()};
return GetContentPath(title_id, content, map);
}
} // namespace IOS::HLE
@@ -15,11 +15,11 @@

namespace IOS::HLE
{
s32 ESDevice::OpenContent(const IOS::ES::TMDReader& tmd, u16 content_index, u32 uid)
s32 ESDevice::OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid)
{
const u64 title_id = tmd.GetTitleId();

IOS::ES::Content content;
ES::Content content;
if (!tmd.GetContent(content_index, &content))
return ES_EINVAL;

@@ -49,7 +49,7 @@ s32 ESDevice::OpenContent(const IOS::ES::TMDReader& tmd, u16 content_index, u32
IPCCommandResult ESDevice::OpenContent(u32 uid, const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(3, 0) || request.in_vectors[0].size != sizeof(u64) ||
request.in_vectors[1].size != sizeof(IOS::ES::TicketView) ||
request.in_vectors[1].size != sizeof(ES::TicketView) ||
request.in_vectors[2].size != sizeof(u32))
{
return GetDefaultReply(ES_EINVAL);
@@ -76,7 +76,7 @@ IPCCommandResult ESDevice::OpenActiveTitleContent(u32 caller_uid, const IOCtlVRe
if (!m_title_context.active)
return GetDefaultReply(ES_EINVAL);

IOS::ES::UIDSys uid_map{m_ios.GetFS()};
ES::UIDSys uid_map{m_ios.GetFS()};
const u32 uid = uid_map.GetOrInsertUIDForTitle(m_title_context.tmd.GetTitleId());
if (caller_uid != 0 && caller_uid != uid)
return GetDefaultReply(ES_EACCES);
@@ -16,7 +16,7 @@ namespace IOS::HLE
{
// Used by the GetStoredContents ioctlvs. This assumes that the first output vector
// is used for the content count (u32).
IPCCommandResult ESDevice::GetStoredContentsCount(const IOS::ES::TMDReader& tmd,
IPCCommandResult ESDevice::GetStoredContentsCount(const ES::TMDReader& tmd,
const IOCtlVRequest& request)
{
if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid())
@@ -32,8 +32,7 @@ IPCCommandResult ESDevice::GetStoredContentsCount(const IOS::ES::TMDReader& tmd,

// Used by the GetStoredContents ioctlvs. This assumes that the second input vector is used
// for the content count and the output vector is used to store a list of content IDs (u32s).
IPCCommandResult ESDevice::GetStoredContents(const IOS::ES::TMDReader& tmd,
const IOCtlVRequest& request)
IPCCommandResult ESDevice::GetStoredContents(const ES::TMDReader& tmd, const IOCtlVRequest& request)
{
if (!tmd.IsValid())
return GetDefaultReply(ES_EINVAL);
@@ -58,7 +57,7 @@ IPCCommandResult ESDevice::GetStoredContentsCount(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);

const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
const ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
return GetStoredContentsCount(tmd, request);
@@ -70,7 +69,7 @@ IPCCommandResult ESDevice::GetStoredContents(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);

const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
const ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
return GetStoredContents(tmd, request);
@@ -83,7 +82,7 @@ IPCCommandResult ESDevice::GetTMDStoredContentsCount(const IOCtlVRequest& reques

std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());
return GetStoredContentsCount(IOS::ES::TMDReader{std::move(tmd_bytes)}, request);
return GetStoredContentsCount(ES::TMDReader{std::move(tmd_bytes)}, request);
}

IPCCommandResult ESDevice::GetTMDStoredContents(const IOCtlVRequest& request)
@@ -94,7 +93,7 @@ IPCCommandResult ESDevice::GetTMDStoredContents(const IOCtlVRequest& request)
std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());

const IOS::ES::TMDReader tmd{std::move(tmd_bytes)};
const ES::TMDReader tmd{std::move(tmd_bytes)};
if (!tmd.IsValid())
return GetDefaultReply(ES_EINVAL);

@@ -153,7 +152,7 @@ IPCCommandResult ESDevice::GetStoredTMDSize(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);

const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
const ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);

@@ -171,7 +170,7 @@ IPCCommandResult ESDevice::GetStoredTMD(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);

const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
const ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);

@@ -24,7 +24,7 @@

namespace IOS::HLE
{
static ReturnCode WriteTicket(FS::FileSystem* fs, const IOS::ES::TicketReader& ticket)
static ReturnCode WriteTicket(FS::FileSystem* fs, const ES::TicketReader& ticket)
{
const u64 title_id = ticket.GetTitleId();

@@ -54,7 +54,7 @@ ReturnCode ESDevice::ImportTicket(const std::vector<u8>& ticket_bytes,
const std::vector<u8>& cert_chain, TicketImportType type,
VerifySignature verify_signature)
{
IOS::ES::TicketReader ticket{ticket_bytes};
ES::TicketReader ticket{ticket_bytes};
if (!ticket.IsValid())
return ES_EINVAL;

@@ -116,7 +116,7 @@ static ReturnCode InitBackupKey(u64 tid, u32 title_flags, IOSC& iosc, IOSC::Hand

// Ignore the region byte.
const u64 title_id = tid | 0xff;
const u32 affected_type = IOS::ES::TITLE_TYPE_0x10 | IOS::ES::TITLE_TYPE_DATA;
const u32 affected_type = ES::TITLE_TYPE_0x10 | ES::TITLE_TYPE_DATA;
if (title_id == Titles::SYSTEM_MENU || (title_flags & affected_type) != affected_type ||
!(title_id == 0x00010005735841ff || title_id - 0x00010005735a41ff <= 0x700))
{
@@ -185,7 +185,7 @@ IPCCommandResult ESDevice::ImportTmd(Context& context, const IOCtlVRequest& requ
if (!request.HasNumberOfValidVectors(1, 0))
return GetDefaultReply(ES_EINVAL);

if (!IOS::ES::IsValidTMDSize(request.in_vectors[0].size))
if (!ES::IsValidTMDSize(request.in_vectors[0].size))
return GetDefaultReply(ES_EINVAL);

std::vector<u8> tmd(request.in_vectors[0].size);
@@ -202,13 +202,13 @@ static ReturnCode InitTitleImportKey(const std::vector<u8>& ticket_bytes, IOSC&
return ret;

std::array<u8, 16> iv{};
std::copy_n(&ticket_bytes[offsetof(IOS::ES::Ticket, title_id)], sizeof(u64), iv.begin());
const u8 index = ticket_bytes[offsetof(IOS::ES::Ticket, common_key_index)];
std::copy_n(&ticket_bytes[offsetof(ES::Ticket, title_id)], sizeof(u64), iv.begin());
const u8 index = ticket_bytes[offsetof(ES::Ticket, common_key_index)];
if (index >= IOSC::COMMON_KEY_HANDLES.size())
return ES_INVALID_TICKET;

return iosc.ImportSecretKey(*handle, IOSC::COMMON_KEY_HANDLES[index], iv.data(),
&ticket_bytes[offsetof(IOS::ES::Ticket, title_key)], PID_ES);
&ticket_bytes[offsetof(ES::Ticket, title_key)], PID_ES);
}

ReturnCode ESDevice::ImportTitleInit(Context& context, const std::vector<u8>& tmd_bytes,
@@ -271,7 +271,7 @@ IPCCommandResult ESDevice::ImportTitleInit(Context& context, const IOCtlVRequest
if (!request.HasNumberOfValidVectors(4, 0))
return GetDefaultReply(ES_EINVAL);

if (!IOS::ES::IsValidTMDSize(request.in_vectors[0].size))
if (!ES::IsValidTMDSize(request.in_vectors[0].size))
return GetDefaultReply(ES_EINVAL);

std::vector<u8> tmd(request.in_vectors[0].size);
@@ -307,7 +307,7 @@ ReturnCode ESDevice::ImportContentBegin(Context& context, u64 title_id, u32 cont

// The IV for title content decryption is the lower two bytes of the
// content index, zero extended.
IOS::ES::Content content_info;
ES::Content content_info;
if (!context.title_import_export.tmd.FindContentById(context.title_import_export.content.id,
&content_info))
return ES_EINVAL;
@@ -354,7 +354,7 @@ IPCCommandResult ESDevice::ImportContentData(Context& context, const IOCtlVReque
ImportContentData(context, content_fd, data_start, request.in_vectors[1].size));
}

static bool CheckIfContentHashMatches(const std::vector<u8>& content, const IOS::ES::Content& info)
static bool CheckIfContentHashMatches(const std::vector<u8>& content, const ES::Content& info)
{
std::array<u8, 20> sha1;
mbedtls_sha1_ret(content.data(), info.size, sha1.data());
@@ -381,7 +381,7 @@ ReturnCode ESDevice::ImportContentEnd(Context& context, u32 content_fd)
if (decrypt_ret != IPC_SUCCESS)
return decrypt_ret;

IOS::ES::Content content_info;
ES::Content content_info;
context.title_import_export.tmd.FindContentById(context.title_import_export.content.id,
&content_info);
if (!CheckIfContentHashMatches(decrypted_data, content_info))
@@ -395,7 +395,7 @@ ReturnCode ESDevice::ImportContentEnd(Context& context, u32 content_fd)
std::string content_path;
if (content_info.IsShared())
{
IOS::ES::SharedContentMap shared_content{fs};
ES::SharedContentMap shared_content{fs};
content_path = shared_content.AddSharedContent(content_info.sha1);
}
else
@@ -438,12 +438,12 @@ IPCCommandResult ESDevice::ImportContentEnd(Context& context, const IOCtlVReques
return GetDefaultReply(ImportContentEnd(context, content_fd));
}

static bool HasAllRequiredContents(IOS::HLE::Kernel& ios, const IOS::ES::TMDReader& tmd)
static bool HasAllRequiredContents(Kernel& ios, const ES::TMDReader& tmd)
{
const u64 title_id = tmd.GetTitleId();
const std::vector<IOS::ES::Content> contents = tmd.GetContents();
const IOS::ES::SharedContentMap shared_content_map{ios.GetFS()};
return std::all_of(contents.cbegin(), contents.cend(), [&](const IOS::ES::Content& content) {
const std::vector<ES::Content> contents = tmd.GetContents();
const ES::SharedContentMap shared_content_map{ios.GetFS()};
return std::all_of(contents.cbegin(), contents.cend(), [&](const ES::Content& content) {
if (content.IsOptional())
return true;

@@ -553,7 +553,7 @@ IPCCommandResult ESDevice::DeleteTitle(const IOCtlVRequest& request)
ReturnCode ESDevice::DeleteTicket(const u8* ticket_view)
{
const auto fs = m_ios.GetFS();
const u64 title_id = Common::swap64(ticket_view + offsetof(IOS::ES::TicketView, title_id));
const u64 title_id = Common::swap64(ticket_view + offsetof(ES::TicketView, title_id));

if (!CanDeleteTitle(title_id))
return ES_EINVAL;
@@ -562,7 +562,7 @@ ReturnCode ESDevice::DeleteTicket(const u8* ticket_view)
if (!ticket.IsValid())
return FS_ENOENT;

const u64 ticket_id = Common::swap64(ticket_view + offsetof(IOS::ES::TicketView, ticket_id));
const u64 ticket_id = Common::swap64(ticket_view + offsetof(ES::TicketView, ticket_id));
ticket.DeleteTicket(ticket_id);

const std::vector<u8>& new_ticket = ticket.GetBytes();
@@ -593,7 +593,7 @@ ReturnCode ESDevice::DeleteTicket(const u8* ticket_view)
IPCCommandResult ESDevice::DeleteTicket(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(1, 0) ||
request.in_vectors[0].size != sizeof(IOS::ES::TicketView))
request.in_vectors[0].size != sizeof(ES::TicketView))
{
return GetDefaultReply(ES_EINVAL);
}
@@ -635,7 +635,7 @@ ReturnCode ESDevice::DeleteContent(u64 title_id, u32 content_id) const
if (!tmd.IsValid())
return FS_ENOENT;

IOS::ES::Content content;
ES::Content content;
if (!tmd.FindContentById(content_id, &content))
return ES_EINVAL;

@@ -708,7 +708,7 @@ ReturnCode ESDevice::ExportContentBegin(Context& context, u64 title_id, u32 cont
return ES_EINVAL;
}

IOS::ES::Content content_info;
ES::Content content_info;
if (!context.title_import_export.tmd.FindContentById(content_id, &content_info))
return ES_EINVAL;

@@ -819,15 +819,15 @@ IPCCommandResult ESDevice::ExportTitleDone(Context& context, const IOCtlVRequest

ReturnCode ESDevice::DeleteSharedContent(const std::array<u8, 20>& sha1) const
{
IOS::ES::SharedContentMap map{m_ios.GetFS()};
ES::SharedContentMap map{m_ios.GetFS()};
const auto content_path = map.GetFilenameFromSHA1(sha1);
if (!content_path)
return ES_EINVAL;

// Check whether the shared content is used by a system title.
const std::vector<u64> titles = GetInstalledTitles();
const bool is_used_by_system_title = std::any_of(titles.begin(), titles.end(), [&](u64 id) {
if (!IOS::ES::IsTitleType(id, IOS::ES::TitleType::System))
if (!ES::IsTitleType(id, ES::TitleType::System))
return false;

const auto tmd = FindInstalledTMD(id);
@@ -30,9 +30,8 @@ namespace IOS::HLE
// booted from the game list, though.
static bool ShouldReturnFakeViewsForIOSes(u64 title_id, const TitleContext& context)
{
const bool ios =
IsTitleType(title_id, IOS::ES::TitleType::System) && title_id != Titles::SYSTEM_MENU;
const bool disc_title = context.active && IOS::ES::IsDiscTitle(context.tmd.GetTitleId());
const bool ios = IsTitleType(title_id, ES::TitleType::System) && title_id != Titles::SYSTEM_MENU;
const bool disc_title = context.active && ES::IsDiscTitle(context.tmd.GetTitleId());
return Core::WantsDeterminism() ||
(ios && SConfig::GetInstance().m_disc_booted_from_game_list && disc_title);
}
@@ -44,10 +43,10 @@ IPCCommandResult ESDevice::GetTicketViewCount(const IOCtlVRequest& request)

const u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);

const IOS::ES::TicketReader ticket = FindSignedTicket(TitleID);
const ES::TicketReader ticket = FindSignedTicket(TitleID);
u32 view_count = ticket.IsValid() ? static_cast<u32>(ticket.GetNumberOfTickets()) : 0;

if (!IOS::HLE::IsEmulated(TitleID))
if (!IsEmulated(TitleID))
{
view_count = 0;
ERROR_LOG_FMT(IOS_ES, "GetViewCount: Dolphin doesn't emulate IOS title {:016x}", TitleID);
@@ -73,9 +72,9 @@ IPCCommandResult ESDevice::GetTicketViews(const IOCtlVRequest& request)
const u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
const u32 maxViews = Memory::Read_U32(request.in_vectors[1].address);

const IOS::ES::TicketReader ticket = FindSignedTicket(TitleID);
const ES::TicketReader ticket = FindSignedTicket(TitleID);

if (!IOS::HLE::IsEmulated(TitleID))
if (!IsEmulated(TitleID))
{
ERROR_LOG_FMT(IOS_ES, "GetViews: Dolphin doesn't emulate IOS title {:016x}", TitleID);
}
@@ -85,13 +84,13 @@ IPCCommandResult ESDevice::GetTicketViews(const IOCtlVRequest& request)
for (u32 view = 0; view < number_of_views; ++view)
{
const std::vector<u8> ticket_view = ticket.GetRawTicketView(view);
Memory::CopyToEmu(request.io_vectors[0].address + view * sizeof(IOS::ES::TicketView),
Memory::CopyToEmu(request.io_vectors[0].address + view * sizeof(ES::TicketView),
ticket_view.data(), ticket_view.size());
}
}
else if (ShouldReturnFakeViewsForIOSes(TitleID, m_title_context))
{
Memory::Memset(request.io_vectors[0].address, 0, sizeof(IOS::ES::TicketView));
Memory::Memset(request.io_vectors[0].address, 0, sizeof(ES::TicketView));
WARN_LOG_FMT(IOS_ES, "GetViews: Faking IOS title {:016x} being present", TitleID);
}

@@ -102,8 +101,8 @@ IPCCommandResult ESDevice::GetTicketViews(const IOCtlVRequest& request)

ReturnCode ESDevice::GetV0TicketFromView(const u8* ticket_view, u8* ticket) const
{
const u64 title_id = Common::swap64(&ticket_view[offsetof(IOS::ES::TicketView, title_id)]);
const u64 ticket_id = Common::swap64(&ticket_view[offsetof(IOS::ES::TicketView, ticket_id)]);
const u64 title_id = Common::swap64(&ticket_view[offsetof(ES::TicketView, title_id)]);
const u64 ticket_id = Common::swap64(&ticket_view[offsetof(ES::TicketView, ticket_id)]);

const auto installed_ticket = FindSignedTicket(title_id);
// TODO: when we get std::optional, check for presence instead of validity.
@@ -121,10 +120,10 @@ ReturnCode ESDevice::GetV0TicketFromView(const u8* ticket_view, u8* ticket) cons
// Check for permission to export the ticket.
const u32 title_identifier = static_cast<u32>(m_title_context.tmd.GetTitleId());
const u32 permitted_title_mask =
Common::swap32(ticket_bytes.data() + offsetof(IOS::ES::Ticket, permitted_title_mask));
Common::swap32(ticket_bytes.data() + offsetof(ES::Ticket, permitted_title_mask));
const u32 permitted_title_id =
Common::swap32(ticket_bytes.data() + offsetof(IOS::ES::Ticket, permitted_title_id));
const u8 title_export_allowed = ticket_bytes[offsetof(IOS::ES::Ticket, title_export_allowed)];
Common::swap32(ticket_bytes.data() + offsetof(ES::Ticket, permitted_title_id));
const u8 title_export_allowed = ticket_bytes[offsetof(ES::Ticket, title_export_allowed)];

// This is the check present in IOS. The 5 does not correspond to any known constant, sadly.
if (!title_identifier || (title_identifier & ~permitted_title_mask) != permitted_title_id ||
@@ -139,7 +138,7 @@ ReturnCode ESDevice::GetV0TicketFromView(const u8* ticket_view, u8* ticket) cons

ReturnCode ESDevice::GetTicketFromView(const u8* ticket_view, u8* ticket, u32* ticket_size) const
{
const u8 version = ticket_view[offsetof(IOS::ES::TicketView, version)];
const u8 version = ticket_view[offsetof(ES::TicketView, version)];
if (version == 1)
{
// Currently, we have no support for v1 tickets at all (unlike IOS), so we fake it
@@ -150,19 +149,19 @@ ReturnCode ESDevice::GetTicketFromView(const u8* ticket_view, u8* ticket, u32* t
}
if (ticket != nullptr)
{
if (*ticket_size >= sizeof(IOS::ES::Ticket))
if (*ticket_size >= sizeof(ES::Ticket))
return GetV0TicketFromView(ticket_view, ticket);
return ES_EINVAL;
}
*ticket_size = sizeof(IOS::ES::Ticket);
*ticket_size = sizeof(ES::Ticket);
return IPC_SUCCESS;
}

IPCCommandResult ESDevice::GetV0TicketFromView(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(1, 1) ||
request.in_vectors[0].size != sizeof(IOS::ES::TicketView) ||
request.io_vectors[0].size != sizeof(IOS::ES::Ticket))
request.in_vectors[0].size != sizeof(ES::TicketView) ||
request.io_vectors[0].size != sizeof(ES::Ticket))
{
return GetDefaultReply(ES_EINVAL);
}
@@ -174,7 +173,7 @@ IPCCommandResult ESDevice::GetTicketSizeFromView(const IOCtlVRequest& request)
{
u32 ticket_size = 0;
if (!request.HasNumberOfValidVectors(1, 1) ||
request.in_vectors[0].size != sizeof(IOS::ES::TicketView) ||
request.in_vectors[0].size != sizeof(ES::TicketView) ||
request.io_vectors[0].size != sizeof(ticket_size))
{
return GetDefaultReply(ES_EINVAL);
@@ -188,7 +187,7 @@ IPCCommandResult ESDevice::GetTicketSizeFromView(const IOCtlVRequest& request)
IPCCommandResult ESDevice::GetTicketFromView(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(2, 1) ||
request.in_vectors[0].size != sizeof(IOS::ES::TicketView) ||
request.in_vectors[0].size != sizeof(ES::TicketView) ||
request.in_vectors[1].size != sizeof(u32))
{
return GetDefaultReply(ES_EINVAL);
@@ -209,7 +208,7 @@ IPCCommandResult ESDevice::GetTMDViewSize(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);

const u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = FindInstalledTMD(TitleID);
const ES::TMDReader tmd = FindInstalledTMD(TitleID);

if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
@@ -224,15 +223,15 @@ IPCCommandResult ESDevice::GetTMDViewSize(const IOCtlVRequest& request)
IPCCommandResult ESDevice::GetTMDViews(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(2, 1) ||
request.in_vectors[0].size != sizeof(IOS::ES::TMDHeader::title_id) ||
request.in_vectors[0].size != sizeof(ES::TMDHeader::title_id) ||
request.in_vectors[1].size != sizeof(u32) ||
Memory::Read_U32(request.in_vectors[1].address) != request.io_vectors[0].size)
{
return GetDefaultReply(ES_EINVAL);
}

const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
const ES::TMDReader tmd = FindInstalledTMD(title_id);

if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
@@ -266,7 +265,7 @@ IPCCommandResult ESDevice::DIGetTMDViewSize(const IOCtlVRequest& request)
{
std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());
const IOS::ES::TMDReader tmd{std::move(tmd_bytes)};
const ES::TMDReader tmd{std::move(tmd_bytes)};

// Yes, this returns -1017, not ES_INVALID_TMD.
// IOS simply checks whether the TMD has all required content entries.
@@ -311,7 +310,7 @@ IPCCommandResult ESDevice::DIGetTMDView(const IOCtlVRequest& request)
{
std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());
const IOS::ES::TMDReader tmd{std::move(tmd_bytes)};
const ES::TMDReader tmd{std::move(tmd_bytes)};

if (!tmd.IsValid())
return GetDefaultReply(ES_EINVAL);
@@ -337,12 +336,12 @@ IPCCommandResult ESDevice::DIGetTMDView(const IOCtlVRequest& request)
IPCCommandResult ESDevice::DIGetTicketView(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(1, 1) ||
request.io_vectors[0].size != sizeof(IOS::ES::TicketView))
request.io_vectors[0].size != sizeof(ES::TicketView))
{
return GetDefaultReply(ES_EINVAL);
}

const bool has_ticket_vector = request.in_vectors[0].size == sizeof(IOS::ES::Ticket);
const bool has_ticket_vector = request.in_vectors[0].size == sizeof(ES::Ticket);

// This ioctlv takes either a signed ticket or no ticket, in which case the ticket size must be 0.
if (!has_ticket_vector && request.in_vectors[0].size != 0)
@@ -363,7 +362,7 @@ IPCCommandResult ESDevice::DIGetTicketView(const IOCtlVRequest& request)
{
std::vector<u8> ticket_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(ticket_bytes.data(), request.in_vectors[0].address, ticket_bytes.size());
const IOS::ES::TicketReader ticket{std::move(ticket_bytes)};
const ES::TicketReader ticket{std::move(ticket_bytes)};

view = ticket.GetRawTicketView(0);
}
@@ -272,7 +272,7 @@ IPCCommandResult FSDevice::Seek(const SeekRequest& request)
return GetFSReply(ConvertResult(ResultCode::Invalid));

const Result<u32> result =
m_ios.GetFS()->SeekFile(handle.fs_fd, request.offset, IOS::HLE::FS::SeekMode(request.mode));
m_ios.GetFS()->SeekFile(handle.fs_fd, request.offset, FS::SeekMode(request.mode));
LogResult(result, "Seek({}, 0x{:08x}, {})", handle.name.data(), request.offset, request.mode);
if (!result)
return GetFSReply(ConvertResult(result.Error()));
@@ -17,7 +17,7 @@ class PointerWrap;

namespace IOS::HLE
{
constexpr IOS::HLE::FS::Fd INVALID_FD = 0xffffffff;
constexpr FS::Fd INVALID_FD = 0xffffffff;

class FSDevice : public Device
{
@@ -39,7 +39,7 @@ class FSDevice : public Device
{
u16 gid = 0;
u32 uid = 0;
IOS::HLE::FS::Fd fs_fd = INVALID_FD;
FS::Fd fs_fd = INVALID_FD;
// We use a std::array to keep this savestate friendly.
std::array<char, 64> name{};
bool superblock_flush_needed = false;
@@ -346,7 +346,7 @@ ReturnCode IOSC::VerifyPublicKeySign(const std::array<u8, 20>& sha1, Handle sign
}
}

ReturnCode IOSC::ImportCertificate(const IOS::ES::CertReader& cert, Handle signer_handle,
ReturnCode IOSC::ImportCertificate(const ES::CertReader& cert, Handle signer_handle,
Handle dest_handle, u32 pid)
{
if (!HasOwnership(signer_handle, pid) || !HasOwnership(dest_handle, pid))
@@ -214,8 +214,8 @@ class IOSC final
ReturnCode VerifyPublicKeySign(const std::array<u8, 20>& sha1, Handle signer_handle,
const std::vector<u8>& signature, u32 pid) const;
// Import a certificate (signed by the certificate in signer_handle) into dest_handle.
ReturnCode ImportCertificate(const IOS::ES::CertReader& cert, Handle signer_handle,
Handle dest_handle, u32 pid);
ReturnCode ImportCertificate(const ES::CertReader& cert, Handle signer_handle, Handle dest_handle,
u32 pid);

// Ownership
ReturnCode GetOwnership(Handle handle, u32* owner) const;
@@ -23,7 +23,7 @@

namespace IOS::HLE
{
WII_SSL NetSSLDevice::_SSL[IOS::HLE::NET_SSL_MAXINSTANCES];
WII_SSL NetSSLDevice::_SSL[NET_SSL_MAXINSTANCES];

static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = {
/* Hashes from SHA-1 and above */
@@ -53,7 +53,7 @@ namespace
// field during the certificate verification process.
int SSLSendWithoutSNI(void* ctx, const unsigned char* buf, size_t len)
{
auto* ssl = static_cast<IOS::HLE::WII_SSL*>(ctx);
auto* ssl = static_cast<WII_SSL*>(ctx);

if (ssl->ctx.state == MBEDTLS_SSL_SERVER_HELLO)
mbedtls_ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str());
@@ -62,7 +62,7 @@ int SSLSendWithoutSNI(void* ctx, const unsigned char* buf, size_t len)

int SSLRecv(void* ctx, unsigned char* buf, size_t len)
{
auto* ssl = static_cast<IOS::HLE::WII_SSL*>(ctx);
auto* ssl = static_cast<WII_SSL*>(ctx);

return mbedtls_net_recv(&ssl->hostfd, buf, len);
}
@@ -100,6 +100,6 @@ class NetSSLDevice : public Device

constexpr bool IsSSLIDValid(int id)
{
return (id >= 0 && id < NET_SSL_MAXINSTANCES && IOS::HLE::NetSSLDevice::_SSL[id].active);
return (id >= 0 && id < NET_SSL_MAXINSTANCES && NetSSLDevice::_SSL[id].active);
}
} // namespace IOS::HLE
@@ -374,7 +374,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
if (it->is_ssl)
{
int sslID = Memory::Read_U32(BufferOut) - 1;
if (IOS::HLE::IsSSLIDValid(sslID))
if (IsSSLIDValid(sslID))
{
switch (it->ssl_type)
{
@@ -68,7 +68,7 @@ NetWDCommandDevice::NetWDCommandDevice(Kernel& ios, const std::string& device_na
m_nitro_enabled_channels = LegalNitroChannelMask;

// TODO: Set the version string here. This is exposed to the PPC.
m_info.mac = IOS::Net::GetMACAddress();
m_info.mac = Net::GetMACAddress();
m_info.enabled_channels = 0xfffe;
m_info.channel = SelectWifiChannel(m_info.enabled_channels, 0);
// The country code is supposed to be null terminated as it is logged with printf in WD.
@@ -388,8 +388,7 @@ bool IsEmulated(u32 major_version)

bool IsEmulated(u64 title_id)
{
const bool ios =
IsTitleType(title_id, IOS::ES::TitleType::System) && title_id != Titles::SYSTEM_MENU;
const bool ios = IsTitleType(title_id, ES::TitleType::System) && title_id != Titles::SYSTEM_MENU;
if (!ios)
return true;
const u32 version = static_cast<u32>(title_id);
@@ -150,7 +150,7 @@ IPCCommandResult WFSIDevice::IOCtl(const IOCtlRequest& request)
WFS::NativePath(content_dir + "/_default.dol"));
}

if (!IOS::ES::IsValidTMDSize(tmd_size))
if (!ES::IsValidTMDSize(tmd_size))
{
ERROR_LOG_FMT(IOS_WFS, "IOCTL_WFSI_IMPORT_TITLE_INIT: TMD size too large ({})", tmd_size);
return_error_code = IPC_EINVAL;
@@ -161,7 +161,7 @@ IPCCommandResult WFSIDevice::IOCtl(const IOCtlRequest& request)
Memory::CopyFromEmu(tmd_bytes.data(), tmd_addr, tmd_size);
m_tmd.SetBytes(std::move(tmd_bytes));

const IOS::ES::TicketReader ticket = m_ios.GetES()->FindSignedTicket(m_tmd.GetTitleId());
const ES::TicketReader ticket = m_ios.GetES()->FindSignedTicket(m_tmd.GetTitleId());
if (!ticket.IsValid())
{
return_error_code = -11028;
@@ -193,7 +193,7 @@ IPCCommandResult WFSIDevice::IOCtl(const IOCtlRequest& request)

// Initializes the IV from the index of the content in the TMD contents.
const u32 content_id = Memory::Read_U32(request.buffer_in + 8);
IOS::ES::Content content_info;
ES::Content content_info;
if (!m_tmd.FindContentById(content_id, &content_info))
{
WARN_LOG_FMT(IOS_WFS, "{}: Content id {:08x} not found", ioctl_name, content_id);
@@ -349,10 +349,10 @@ IPCCommandResult WFSIDevice::IOCtl(const IOCtlRequest& request)
return_error_code = -3;
if (homedir_path_len > 0x1FD)
break;
auto device = IOS::HLE::GetIOS()->GetDeviceByName("/dev/usb/wfssrv");
auto device = GetIOS()->GetDeviceByName("/dev/usb/wfssrv");
if (!device)
break;
std::static_pointer_cast<IOS::HLE::WFSSRVDevice>(device)->SetHomeDir(homedir_path);
std::static_pointer_cast<WFSSRVDevice>(device)->SetHomeDir(homedir_path);
return_error_code = IPC_SUCCESS;
break;
}
@@ -389,7 +389,7 @@ IPCCommandResult WFSIDevice::IOCtl(const IOCtlRequest& request)
break;
}

const IOS::ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(tid);
const ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(tid);
SetCurrentTitleIdAndGroupId(tmd.GetTitleId(), tmd.GetGroupId());
break;
}
@@ -55,7 +55,7 @@ class WFSIDevice : public Device
u8 m_aes_key[0x10] = {};
u8 m_aes_iv[0x10] = {};

IOS::ES::TMDReader m_tmd;
ES::TMDReader m_tmd;
std::string m_base_extract_path;

u64 m_current_title_id;