IOS: Simplify unnecessarily qualified names

Now that the ES class (now called ESDevice) and the ES namespace do
not conflict anymore, "IOS::" can be dropped in a lot of cases.

This also removes "IOS::HLE::" for code that is already in that
namespace. Some of those names used to be explicitly qualified
only for historical reasons.

There are no functional changes.
This commit is contained in:
Léo Lam
2021-02-13 01:30:28 +01:00
parent a2fa89b15e
commit 99fc1c682a
21 changed files with 182 additions and 190 deletions

View File

@ -539,7 +539,7 @@ std::optional<DIDevice::DIResult> DIDevice::StartImmediateTransfer(const IOCtlRe
static std::shared_ptr<DIDevice> GetDevice() static std::shared_ptr<DIDevice> GetDevice()
{ {
auto ios = IOS::HLE::GetIOS(); auto ios = GetIOS();
if (!ios) if (!ios)
return nullptr; return nullptr;
auto di = ios->GetDeviceByName("/dev/di"); auto di = ios->GetDeviceByName("/dev/di");
@ -667,7 +667,7 @@ IPCCommandResult DIDevice::IOCtlV(const IOCtlVRequest& request)
INFO_LOG_FMT(IOS_DI, "DVDLowOpenPartition: partition_offset {:#011x}", partition_offset); INFO_LOG_FMT(IOS_DI, "DVDLowOpenPartition: partition_offset {:#011x}", partition_offset);
// Read TMD to the buffer // Read TMD to the buffer
const IOS::ES::TMDReader tmd = DVDThread::GetTMD(m_current_partition); const ES::TMDReader tmd = DVDThread::GetTMD(m_current_partition);
const std::vector<u8>& raw_tmd = tmd.GetBytes(); const std::vector<u8>& raw_tmd = tmd.GetBytes();
Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size()); Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size());

View File

@ -99,7 +99,7 @@ void TitleContext::DoState(PointerWrap& p)
p.Do(active); p.Do(active);
} }
void TitleContext::Update(const IOS::ES::TMDReader& tmd_, const IOS::ES::TicketReader& ticket_, void TitleContext::Update(const ES::TMDReader& tmd_, const ES::TicketReader& ticket_,
DiscIO::Platform platform) DiscIO::Platform platform)
{ {
if (!tmd_.IsValid() || !ticket_.IsValid()) if (!tmd_.IsValid() || !ticket_.IsValid())
@ -159,9 +159,9 @@ IPCCommandResult ESDevice::GetTitleId(const IOCtlVRequest& request)
return GetDefaultReply(IPC_SUCCESS); return GetDefaultReply(IPC_SUCCESS);
} }
static bool UpdateUIDAndGID(Kernel& kernel, const IOS::ES::TMDReader& tmd) static bool UpdateUIDAndGID(Kernel& kernel, const ES::TMDReader& tmd)
{ {
IOS::ES::UIDSys uid_sys{kernel.GetFS()}; ES::UIDSys uid_sys{kernel.GetFS()};
const u64 title_id = tmd.GetTitleId(); const u64 title_id = tmd.GetTitleId();
const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id); const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id);
if (uid == 0) if (uid == 0)
@ -175,9 +175,9 @@ static bool UpdateUIDAndGID(Kernel& kernel, const IOS::ES::TMDReader& tmd)
} }
static ReturnCode CheckIsAllowedToSetUID(Kernel& kernel, const u32 caller_uid, static ReturnCode CheckIsAllowedToSetUID(Kernel& kernel, const u32 caller_uid,
const IOS::ES::TMDReader& active_tmd) const ES::TMDReader& active_tmd)
{ {
IOS::ES::UIDSys uid_map{kernel.GetFS()}; ES::UIDSys uid_map{kernel.GetFS()};
const u32 system_menu_uid = uid_map.GetOrInsertUIDForTitle(Titles::SYSTEM_MENU); const u32 system_menu_uid = uid_map.GetOrInsertUIDForTitle(Titles::SYSTEM_MENU);
if (!system_menu_uid) if (!system_menu_uid)
return ES_SHORT_READ; return ES_SHORT_READ;
@ -246,7 +246,7 @@ bool ESDevice::LaunchTitle(u64 title_id, bool skip_reload)
return LaunchTitle(Titles::SYSTEM_MENU); return LaunchTitle(Titles::SYSTEM_MENU);
} }
if (IsTitleType(title_id, IOS::ES::TitleType::System) && title_id != Titles::SYSTEM_MENU) if (IsTitleType(title_id, ES::TitleType::System) && title_id != Titles::SYSTEM_MENU)
return LaunchIOS(title_id); return LaunchIOS(title_id);
return LaunchPPCTitle(title_id, skip_reload); return LaunchPPCTitle(title_id, skip_reload);
} }
@ -272,9 +272,9 @@ bool ESDevice::LaunchIOS(u64 ios_title_id)
// so only have this check for MIOS (for which having the binary is *required*). // so only have this check for MIOS (for which having the binary is *required*).
if (ios_title_id == Titles::MIOS) if (ios_title_id == Titles::MIOS)
{ {
const IOS::ES::TMDReader tmd = FindInstalledTMD(ios_title_id); const ES::TMDReader tmd = FindInstalledTMD(ios_title_id);
const IOS::ES::TicketReader ticket = FindSignedTicket(ios_title_id); const ES::TicketReader ticket = FindSignedTicket(ios_title_id);
IOS::ES::Content content; ES::Content content;
if (!tmd.IsValid() || !ticket.IsValid() || !tmd.GetContent(tmd.GetBootIndex(), &content) || if (!tmd.IsValid() || !ticket.IsValid() || !tmd.GetContent(tmd.GetBootIndex(), &content) ||
!m_ios.BootIOS(ios_title_id, GetContentPath(ios_title_id, content))) !m_ios.BootIOS(ios_title_id, GetContentPath(ios_title_id, content)))
{ {
@ -291,8 +291,8 @@ bool ESDevice::LaunchIOS(u64 ios_title_id)
bool ESDevice::LaunchPPCTitle(u64 title_id, bool skip_reload) bool ESDevice::LaunchPPCTitle(u64 title_id, bool skip_reload)
{ {
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id); const ES::TMDReader tmd = FindInstalledTMD(title_id);
const IOS::ES::TicketReader ticket = FindSignedTicket(title_id); const ES::TicketReader ticket = FindSignedTicket(title_id);
if (!tmd.IsValid() || !ticket.IsValid()) if (!tmd.IsValid() || !ticket.IsValid())
{ {
@ -332,7 +332,7 @@ bool ESDevice::LaunchPPCTitle(u64 title_id, bool skip_reload)
return false; return false;
} }
IOS::ES::Content content; ES::Content content;
if (!tmd.GetContent(tmd.GetBootIndex(), &content)) if (!tmd.GetContent(tmd.GetBootIndex(), &content))
return false; return false;
@ -597,7 +597,7 @@ IPCCommandResult ESDevice::Launch(const IOCtlVRequest& request)
view, ticketid, devicetype, titleid, access); view, ticketid, devicetype, titleid, access);
// Prevent loading installed IOSes that are not emulated. // Prevent loading installed IOSes that are not emulated.
if (!IOS::HLE::IsEmulated(title_id)) if (!IsEmulated(title_id))
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
// IOS replies to the request through the mailbox on failure, and acks if the launch succeeds. // IOS replies to the request through the mailbox on failure, and acks if the launch succeeds.
@ -635,7 +635,7 @@ IPCCommandResult ESDevice::DIVerify(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
} }
static ReturnCode WriteTmdForDiVerify(FS::FileSystem* fs, const IOS::ES::TMDReader& tmd) static ReturnCode WriteTmdForDiVerify(FS::FileSystem* fs, const ES::TMDReader& tmd)
{ {
const std::string temp_path = "/tmp/title.tmd"; const std::string temp_path = "/tmp/title.tmd";
fs->Delete(PID_KERNEL, PID_KERNEL, temp_path); fs->Delete(PID_KERNEL, PID_KERNEL, temp_path);
@ -659,7 +659,7 @@ static ReturnCode WriteTmdForDiVerify(FS::FileSystem* fs, const IOS::ES::TMDRead
return FS::ConvertResult(fs->Rename(PID_KERNEL, PID_KERNEL, temp_path, tmd_path)); return FS::ConvertResult(fs->Rename(PID_KERNEL, PID_KERNEL, temp_path, tmd_path));
} }
ReturnCode ESDevice::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& ticket) ReturnCode ESDevice::DIVerify(const ES::TMDReader& tmd, const ES::TicketReader& ticket)
{ {
m_title_context.Clear(); m_title_context.Clear();
INFO_LOG_FMT(IOS_ES, "ES_DIVerify: Title context changed: (none)"); INFO_LOG_FMT(IOS_ES, "ES_DIVerify: Title context changed: (none)");
@ -700,14 +700,14 @@ ReturnCode ESDevice::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::Tick
} }
ReturnCode ESDevice::CheckStreamKeyPermissions(const u32 uid, const u8* ticket_view, ReturnCode ESDevice::CheckStreamKeyPermissions(const u32 uid, const u8* ticket_view,
const IOS::ES::TMDReader& tmd) const const ES::TMDReader& tmd) const
{ {
const u32 title_flags = tmd.GetTitleFlags(); const u32 title_flags = tmd.GetTitleFlags();
// Only allow using this function with some titles (WFS titles). // Only allow using this function with some titles (WFS titles).
// The following is the exact check from IOS. Unfortunately, other than knowing that the // The following is the exact check from IOS. Unfortunately, other than knowing that the
// title type is what IOS checks, we don't know much about the constants used here. // title type is what IOS checks, we don't know much about the constants used here.
constexpr u32 WFS_AND_0x4_FLAG = IOS::ES::TITLE_TYPE_0x4 | IOS::ES::TITLE_TYPE_WFS_MAYBE; constexpr u32 WFS_AND_0x4_FLAG = ES::TITLE_TYPE_0x4 | ES::TITLE_TYPE_WFS_MAYBE;
if ((!(title_flags & IOS::ES::TITLE_TYPE_0x4) && ~(title_flags >> 5) & 1) || if ((!(title_flags & ES::TITLE_TYPE_0x4) && ~(title_flags >> 5) & 1) ||
(title_flags & WFS_AND_0x4_FLAG) == WFS_AND_0x4_FLAG) (title_flags & WFS_AND_0x4_FLAG) == WFS_AND_0x4_FLAG)
{ {
return ES_EINVAL; return ES_EINVAL;
@ -721,18 +721,18 @@ ReturnCode ESDevice::CheckStreamKeyPermissions(const u32 uid, const u8* ticket_v
return ES_EINVAL; return ES_EINVAL;
// If the title type is of this specific type, then this function is limited to WFS. // If the title type is of this specific type, then this function is limited to WFS.
if (title_flags & IOS::ES::TITLE_TYPE_WFS_MAYBE && uid != PID_UNKNOWN) if (title_flags & ES::TITLE_TYPE_WFS_MAYBE && uid != PID_UNKNOWN)
return ES_EINVAL; return ES_EINVAL;
const u64 view_title_id = Common::swap64(ticket_view + offsetof(IOS::ES::TicketView, title_id)); const u64 view_title_id = Common::swap64(ticket_view + offsetof(ES::TicketView, title_id));
if (view_title_id != tmd.GetTitleId()) if (view_title_id != tmd.GetTitleId())
return ES_EINVAL; return ES_EINVAL;
// More permission checks. // More permission checks.
const u32 permitted_title_mask = const u32 permitted_title_mask =
Common::swap32(ticket_view + offsetof(IOS::ES::TicketView, permitted_title_mask)); Common::swap32(ticket_view + offsetof(ES::TicketView, permitted_title_mask));
const u32 permitted_title_id = const u32 permitted_title_id =
Common::swap32(ticket_view + offsetof(IOS::ES::TicketView, permitted_title_id)); Common::swap32(ticket_view + offsetof(ES::TicketView, permitted_title_id));
if ((uid == PID_UNKNOWN && (~permitted_title_mask & 0x13) != permitted_title_id) || if ((uid == PID_UNKNOWN && (~permitted_title_mask & 0x13) != permitted_title_id) ||
!IsActiveTitlePermittedByTicket(ticket_view)) !IsActiveTitlePermittedByTicket(ticket_view))
{ {
@ -742,8 +742,8 @@ ReturnCode ESDevice::CheckStreamKeyPermissions(const u32 uid, const u8* ticket_v
return IPC_SUCCESS; return IPC_SUCCESS;
} }
ReturnCode ESDevice::SetUpStreamKey(const u32 uid, const u8* ticket_view, ReturnCode ESDevice::SetUpStreamKey(const u32 uid, const u8* ticket_view, const ES::TMDReader& tmd,
const IOS::ES::TMDReader& tmd, u32* handle) u32* handle)
{ {
ReturnCode ret = CheckStreamKeyPermissions(uid, ticket_view, tmd); ReturnCode ret = CheckStreamKeyPermissions(uid, ticket_view, tmd);
if (ret != IPC_SUCCESS) if (ret != IPC_SUCCESS)
@ -752,9 +752,9 @@ ReturnCode ESDevice::SetUpStreamKey(const u32 uid, const u8* ticket_view,
// TODO (for the future): signature checks. // TODO (for the future): signature checks.
// Find a signed ticket from the view. // Find a signed ticket from the view.
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)]);
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)]);
const IOS::ES::TicketReader installed_ticket = FindSignedTicket(title_id); const ES::TicketReader installed_ticket = FindSignedTicket(title_id);
// Unlike the other "get ticket from view" function, this returns a FS error, not ES_NO_TICKET. // Unlike the other "get ticket from view" function, this returns a FS error, not ES_NO_TICKET.
if (!installed_ticket.IsValid()) if (!installed_ticket.IsValid())
return FS_ENOENT; return FS_ENOENT;
@ -788,28 +788,26 @@ ReturnCode ESDevice::SetUpStreamKey(const u32 uid, const u8* ticket_view,
if (ret != IPC_SUCCESS) if (ret != IPC_SUCCESS)
return ret; return ret;
const u8 index = ticket_bytes[offsetof(IOS::ES::Ticket, common_key_index)]; const u8 index = ticket_bytes[offsetof(ES::Ticket, common_key_index)];
if (index >= IOSC::COMMON_KEY_HANDLES.size()) if (index >= IOSC::COMMON_KEY_HANDLES.size())
return ES_INVALID_TICKET; return ES_INVALID_TICKET;
return m_ios.GetIOSC().ImportSecretKey(*handle, IOSC::COMMON_KEY_HANDLES[index], iv.data(), return m_ios.GetIOSC().ImportSecretKey(*handle, IOSC::COMMON_KEY_HANDLES[index], iv.data(),
&ticket_bytes[offsetof(IOS::ES::Ticket, title_key)], &ticket_bytes[offsetof(ES::Ticket, title_key)], PID_ES);
PID_ES);
} }
IPCCommandResult ESDevice::SetUpStreamKey(const Context& context, const IOCtlVRequest& request) IPCCommandResult ESDevice::SetUpStreamKey(const Context& context, const IOCtlVRequest& request)
{ {
if (!request.HasNumberOfValidVectors(2, 1) || if (!request.HasNumberOfValidVectors(2, 1) ||
request.in_vectors[0].size != sizeof(IOS::ES::TicketView) || request.in_vectors[0].size != sizeof(ES::TicketView) ||
!IOS::ES::IsValidTMDSize(request.in_vectors[1].size) || !ES::IsValidTMDSize(request.in_vectors[1].size) || request.io_vectors[0].size != sizeof(u32))
request.io_vectors[0].size != sizeof(u32))
{ {
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
} }
std::vector<u8> tmd_bytes(request.in_vectors[1].size); std::vector<u8> tmd_bytes(request.in_vectors[1].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[1].address, tmd_bytes.size()); Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[1].address, tmd_bytes.size());
const IOS::ES::TMDReader tmd{std::move(tmd_bytes)}; const ES::TMDReader tmd{std::move(tmd_bytes)};
if (!tmd.IsValid()) if (!tmd.IsValid())
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
@ -837,14 +835,13 @@ bool ESDevice::IsActiveTitlePermittedByTicket(const u8* ticket_view) const
const u32 title_identifier = static_cast<u32>(m_title_context.tmd.GetTitleId()); const u32 title_identifier = static_cast<u32>(m_title_context.tmd.GetTitleId());
const u32 permitted_title_mask = const u32 permitted_title_mask =
Common::swap32(ticket_view + offsetof(IOS::ES::TicketView, permitted_title_mask)); Common::swap32(ticket_view + offsetof(ES::TicketView, permitted_title_mask));
const u32 permitted_title_id = const u32 permitted_title_id =
Common::swap32(ticket_view + offsetof(IOS::ES::TicketView, permitted_title_id)); Common::swap32(ticket_view + offsetof(ES::TicketView, permitted_title_id));
return title_identifier && (title_identifier & ~permitted_title_mask) == permitted_title_id; return title_identifier && (title_identifier & ~permitted_title_mask) == permitted_title_id;
} }
bool ESDevice::IsIssuerCorrect(VerifyContainerType type, bool ESDevice::IsIssuerCorrect(VerifyContainerType type, const ES::CertReader& issuer_cert) const
const IOS::ES::CertReader& issuer_cert) const
{ {
switch (type) switch (type)
{ {
@ -874,14 +871,14 @@ ReturnCode ESDevice::ReadCertStore(std::vector<u8>* buffer) const
return IPC_SUCCESS; return IPC_SUCCESS;
} }
ReturnCode ESDevice::WriteNewCertToStore(const IOS::ES::CertReader& cert) ReturnCode ESDevice::WriteNewCertToStore(const ES::CertReader& cert)
{ {
// Read the current store to determine if the new cert needs to be written. // Read the current store to determine if the new cert needs to be written.
std::vector<u8> current_store; std::vector<u8> current_store;
const ReturnCode ret = ReadCertStore(&current_store); const ReturnCode ret = ReadCertStore(&current_store);
if (ret == IPC_SUCCESS) if (ret == IPC_SUCCESS)
{ {
const std::map<std::string, IOS::ES::CertReader> certs = IOS::ES::ParseCertChain(current_store); const std::map<std::string, ES::CertReader> certs = ES::ParseCertChain(current_store);
// The cert is already present in the store. Nothing to do. // The cert is already present in the store. Nothing to do.
if (certs.find(cert.GetName()) != certs.end()) if (certs.find(cert.GetName()) != certs.end())
return IPC_SUCCESS; return IPC_SUCCESS;
@ -900,7 +897,7 @@ ReturnCode ESDevice::WriteNewCertToStore(const IOS::ES::CertReader& cert)
} }
ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode, ReturnCode ESDevice::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_out) const std::vector<u8>& cert_chain, u32* issuer_handle_out)
{ {
if (!signed_blob.IsSignatureValid()) if (!signed_blob.IsSignatureValid())
@ -914,13 +911,13 @@ ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
return ES_EINVAL; return ES_EINVAL;
// Find the direct issuer and the CA certificates for the blob. // Find the direct issuer and the CA certificates for the blob.
const std::map<std::string, IOS::ES::CertReader> certs = IOS::ES::ParseCertChain(cert_chain); const std::map<std::string, ES::CertReader> certs = ES::ParseCertChain(cert_chain);
const auto issuer_cert_iterator = certs.find(parents[2]); const auto issuer_cert_iterator = certs.find(parents[2]);
const auto ca_cert_iterator = certs.find(parents[1]); const auto ca_cert_iterator = certs.find(parents[1]);
if (issuer_cert_iterator == certs.end() || ca_cert_iterator == certs.end()) if (issuer_cert_iterator == certs.end() || ca_cert_iterator == certs.end())
return ES_UNKNOWN_ISSUER; return ES_UNKNOWN_ISSUER;
const IOS::ES::CertReader& issuer_cert = issuer_cert_iterator->second; const ES::CertReader& issuer_cert = issuer_cert_iterator->second;
const IOS::ES::CertReader& ca_cert = ca_cert_iterator->second; const ES::CertReader& ca_cert = ca_cert_iterator->second;
// Some blobs can only be signed by specific certificates. // Some blobs can only be signed by specific certificates.
if (!IsIssuerCorrect(type, issuer_cert)) if (!IsIssuerCorrect(type, issuer_cert))
@ -992,8 +989,8 @@ ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
} }
ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode, ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
const IOS::ES::CertReader& cert, const ES::CertReader& cert, const std::vector<u8>& cert_chain,
const std::vector<u8>& cert_chain, u32 certificate_iosc_handle) u32 certificate_iosc_handle)
{ {
IOSC::Handle issuer_handle; IOSC::Handle issuer_handle;
ReturnCode ret = VerifyContainer(type, mode, cert, cert_chain, &issuer_handle); ReturnCode ret = VerifyContainer(type, mode, cert, cert_chain, &issuer_handle);

View File

@ -29,11 +29,11 @@ struct TitleContext
{ {
void Clear(); void Clear();
void DoState(PointerWrap& p); 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); DiscIO::Platform platform);
IOS::ES::TicketReader ticket; ES::TicketReader ticket;
IOS::ES::TMDReader tmd; ES::TMDReader tmd;
bool active = false; bool active = false;
bool first_change = true; bool first_change = true;
}; };
@ -43,7 +43,7 @@ class ESDevice final : public Device
public: public:
ESDevice(Kernel& ios, const std::string& device_name); 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); bool LaunchTitle(u64 title_id, bool skip_reload = false);
void DoState(PointerWrap& p) override; void DoState(PointerWrap& p) override;
@ -57,7 +57,7 @@ public:
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
bool valid = false; bool valid = false;
IOS::ES::TMDReader tmd; ES::TMDReader tmd;
IOSC::Handle key_handle = 0; IOSC::Handle key_handle = 0;
struct ContentContext struct ContentContext
{ {
@ -87,9 +87,9 @@ public:
No = false, No = false,
}; };
IOS::ES::TMDReader FindImportTMD(u64 title_id) const; ES::TMDReader FindImportTMD(u64 title_id) const;
IOS::ES::TMDReader FindInstalledTMD(u64 title_id) const; ES::TMDReader FindInstalledTMD(u64 title_id) const;
IOS::ES::TicketReader FindSignedTicket(u64 title_id) const; ES::TicketReader FindSignedTicket(u64 title_id) const;
// Get installed titles (in /title) without checking for TMDs at all. // Get installed titles (in /title) without checking for TMDs at all.
std::vector<u64> GetInstalledTitles() const; std::vector<u64> GetInstalledTitles() const;
@ -98,14 +98,14 @@ public:
// Get titles for which there is a ticket (in /ticket). // Get titles for which there is a ticket (in /ticket).
std::vector<u64> GetTitlesWithTickets() const; std::vector<u64> GetTitlesWithTickets() const;
std::vector<IOS::ES::Content> std::vector<ES::Content>
GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd, GetStoredContentsFromTMD(const ES::TMDReader& tmd,
CheckContentHashes check_content_hashes = CheckContentHashes::No) const; CheckContentHashes check_content_hashes = CheckContentHashes::No) const;
u32 GetSharedContentsCount() const; u32 GetSharedContentsCount() const;
std::vector<std::array<u8, 20>> GetSharedContents() const; std::vector<std::array<u8, 20>> GetSharedContents() const;
// Title contents // 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); ReturnCode CloseContent(u32 cfd, u32 uid);
s32 ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid); s32 ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid);
s32 SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid); s32 SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid);
@ -158,8 +158,7 @@ public:
ReturnCode GetV0TicketFromView(const u8* ticket_view, u8* ticket) const; ReturnCode GetV0TicketFromView(const u8* ticket_view, u8* ticket) const;
ReturnCode GetTicketFromView(const u8* ticket_view, u8* ticket, u32* ticket_size) 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, ReturnCode SetUpStreamKey(u32 uid, const u8* ticket_view, const ES::TMDReader& tmd, u32* handle);
u32* handle);
bool CreateTitleDirectories(u64 title_id, u16 group_id) const; bool CreateTitleDirectories(u64 title_id, u16 group_id) const;
@ -178,11 +177,11 @@ public:
// On success, if issuer_handle is non-null, the IOSC object for the issuer will be written to it. // 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. // The caller is responsible for using IOSC_DeleteObject.
ReturnCode VerifyContainer(VerifyContainerType type, VerifyMode mode, 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); const std::vector<u8>& cert_chain, u32* issuer_handle = nullptr);
ReturnCode VerifyContainer(VerifyContainerType type, VerifyMode mode, ReturnCode VerifyContainer(VerifyContainerType type, VerifyMode mode,
const IOS::ES::CertReader& certificate, const ES::CertReader& certificate, const std::vector<u8>& cert_chain,
const std::vector<u8>& cert_chain, u32 certificate_iosc_handle); u32 certificate_iosc_handle);
private: private:
enum enum
@ -316,9 +315,8 @@ private:
IPCCommandResult GetTitleCount(const IOCtlVRequest& request); IPCCommandResult GetTitleCount(const IOCtlVRequest& request);
IPCCommandResult GetTitles(const IOCtlVRequest& request); IPCCommandResult GetTitles(const IOCtlVRequest& request);
IPCCommandResult GetBoot2Version(const IOCtlVRequest& request); IPCCommandResult GetBoot2Version(const IOCtlVRequest& request);
IPCCommandResult GetStoredContentsCount(const IOS::ES::TMDReader& tmd, IPCCommandResult GetStoredContentsCount(const ES::TMDReader& tmd, const IOCtlVRequest& request);
const IOCtlVRequest& request); IPCCommandResult GetStoredContents(const ES::TMDReader& tmd, const IOCtlVRequest& request);
IPCCommandResult GetStoredContents(const IOS::ES::TMDReader& tmd, const IOCtlVRequest& request);
IPCCommandResult GetStoredContentsCount(const IOCtlVRequest& request); IPCCommandResult GetStoredContentsCount(const IOCtlVRequest& request);
IPCCommandResult GetStoredContents(const IOCtlVRequest& request); IPCCommandResult GetStoredContents(const IOCtlVRequest& request);
IPCCommandResult GetTMDStoredContentsCount(const IOCtlVRequest& request); IPCCommandResult GetTMDStoredContentsCount(const IOCtlVRequest& request);
@ -350,32 +348,32 @@ private:
bool IsActiveTitlePermittedByTicket(const u8* ticket_view) const; bool IsActiveTitlePermittedByTicket(const u8* ticket_view) const;
ReturnCode CheckStreamKeyPermissions(u32 uid, const u8* ticket_view, 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 ReadCertStore(std::vector<u8>* buffer) const;
ReturnCode WriteNewCertToStore(const IOS::ES::CertReader& cert); ReturnCode WriteNewCertToStore(const ES::CertReader& cert);
// Start a title import. // 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. // 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. // 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. // Finish stale imports and clear the import directory.
void FinishStaleImport(u64 title_id); void FinishStaleImport(u64 title_id);
void FinishAllStaleImports(); void FinishAllStaleImports();
std::string GetContentPath(u64 title_id, const IOS::ES::Content& content, std::string GetContentPath(u64 title_id, const ES::Content& content,
const IOS::ES::SharedContentMap& map) const; const 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;
struct OpenedContent struct OpenedContent
{ {
bool m_opened = false; bool m_opened = false;
FS::Fd m_fd; FS::Fd m_fd;
u64 m_title_id = 0; u64 m_title_id = 0;
IOS::ES::Content m_content; ES::Content m_content;
u32 m_uid = 0; u32 m_uid = 0;
}; };

View File

@ -380,10 +380,10 @@ std::vector<u8> TicketReader::GetRawTicket(u64 ticket_id_to_find) const
{ {
for (size_t i = 0; i < GetNumberOfTickets(); ++i) for (size_t i = 0; i < GetNumberOfTickets(); ++i)
{ {
const auto ticket_begin = m_bytes.begin() + sizeof(IOS::ES::Ticket) * i; const auto ticket_begin = m_bytes.begin() + sizeof(ES::Ticket) * i;
const u64 ticket_id = Common::swap64(&*ticket_begin + offsetof(IOS::ES::Ticket, ticket_id)); const u64 ticket_id = Common::swap64(&*ticket_begin + offsetof(ES::Ticket, ticket_id));
if (ticket_id == ticket_id_to_find) 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 {}; return {};
} }

View File

@ -120,7 +120,7 @@ IPCCommandResult ESDevice::Sign(const IOCtlVRequest& request)
ReturnCode ESDevice::VerifySign(const std::vector<u8>& hash, const std::vector<u8>& ecc_signature, ReturnCode ESDevice::VerifySign(const std::vector<u8>& hash, const std::vector<u8>& ecc_signature,
const std::vector<u8>& certs_bytes) 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()) if (certs.empty())
return ES_EINVAL; return ES_EINVAL;
@ -129,13 +129,13 @@ ReturnCode ESDevice::VerifySign(const std::vector<u8>& hash, const std::vector<u
}); });
if (ap_iterator == certs.end()) if (ap_iterator == certs.end())
return ES_UNKNOWN_ISSUER; 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 ap_issuers = SplitString(ap.GetIssuer(), '-');
const auto ng_iterator = ap_issuers.size() > 1 ? certs.find(*ap_issuers.rbegin()) : certs.end(); const auto ng_iterator = ap_issuers.size() > 1 ? certs.find(*ap_issuers.rbegin()) : certs.end();
if (ng_iterator == certs.end()) if (ng_iterator == certs.end())
return ES_UNKNOWN_ISSUER; 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& iosc = m_ios.GetIOSC();
IOSC::Handle ng_cert; IOSC::Handle ng_cert;

View File

@ -24,7 +24,7 @@
namespace IOS::HLE 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); const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, tmd_path, FS::Mode::Read);
if (!file) 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())) if (!file->Read(tmd_bytes.data(), tmd_bytes.size()))
return {}; 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, return FindTMD(m_ios.GetFS().get(), title_id,
Common::GetImportTitlePath(title_id) + "/content/title.tmd"); 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)); 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 std::string path = Common::GetTicketFileName(title_id);
const auto ticket_file = m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::Read); 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())) if (!ticket_file->Read(signed_ticket.data(), signed_ticket.size()))
return {}; return {};
return IOS::ES::TicketReader{std::move(signed_ticket)}; return ES::TicketReader{std::move(signed_ticket)};
} }
static bool IsValidPartOfTitleID(const std::string& string) static bool IsValidPartOfTitleID(const std::string& string)
@ -164,20 +164,20 @@ std::vector<u64> ESDevice::GetTitlesWithTickets() const
return title_ids; return title_ids;
} }
std::vector<IOS::ES::Content> std::vector<ES::Content>
ESDevice::GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd, ESDevice::GetStoredContentsFromTMD(const ES::TMDReader& tmd,
CheckContentHashes check_content_hashes) const CheckContentHashes check_content_hashes) const
{ {
if (!tmd.IsValid()) if (!tmd.IsValid())
return {}; return {};
const IOS::ES::SharedContentMap map{m_ios.GetFS()}; const ES::SharedContentMap map{m_ios.GetFS()};
const std::vector<IOS::ES::Content> contents = tmd.GetContents(); 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), 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 auto fs = m_ios.GetFS();
const std::string path = GetContentPath(tmd.GetTitleId(), content, map); 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 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(); return map.GetHashes();
} }
@ -267,7 +267,7 @@ bool ESDevice::CreateTitleDirectories(u64 title_id, u16 group_id) const
return false; return false;
} }
IOS::ES::UIDSys uid_sys{fs}; ES::UIDSys uid_sys{fs};
const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id); const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id);
if (fs->SetMetadata(0, data_dir, uid, group_id, 0, data_dir_modes) != FS::ResultCode::Success) 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; return true;
} }
bool ESDevice::InitImport(const IOS::ES::TMDReader& tmd) bool ESDevice::InitImport(const ES::TMDReader& tmd)
{ {
if (!CreateTitleDirectories(tmd.GetTitleId(), tmd.GetGroupId())) if (!CreateTitleDirectories(tmd.GetTitleId(), tmd.GetGroupId()))
return false; return false;
@ -310,7 +310,7 @@ bool ESDevice::InitImport(const IOS::ES::TMDReader& tmd)
return true; return true;
} }
bool ESDevice::FinishImport(const IOS::ES::TMDReader& tmd) bool ESDevice::FinishImport(const ES::TMDReader& tmd)
{ {
const auto fs = m_ios.GetFS(); const auto fs = m_ios.GetFS();
const u64 title_id = tmd.GetTitleId(); const u64 title_id = tmd.GetTitleId();
@ -343,7 +343,7 @@ bool ESDevice::FinishImport(const IOS::ES::TMDReader& tmd)
return true; return true;
} }
bool ESDevice::WriteImportTMD(const IOS::ES::TMDReader& tmd) bool ESDevice::WriteImportTMD(const ES::TMDReader& tmd)
{ {
const auto fs = m_ios.GetFS(); const auto fs = m_ios.GetFS();
const std::string tmd_path = "/tmp/title.tmd"; const std::string tmd_path = "/tmp/title.tmd";
@ -381,17 +381,17 @@ void ESDevice::FinishAllStaleImports()
FinishStaleImport(title_id); FinishStaleImport(title_id);
} }
std::string ESDevice::GetContentPath(const u64 title_id, const IOS::ES::Content& content, std::string ESDevice::GetContentPath(const u64 title_id, const ES::Content& content,
const IOS::ES::SharedContentMap& content_map) const const ES::SharedContentMap& content_map) const
{ {
if (content.IsShared()) if (content.IsShared())
return content_map.GetFilenameFromSHA1(content.sha1).value_or(""); return content_map.GetFilenameFromSHA1(content.sha1).value_or("");
return fmt::format("{}/{:08x}.app", Common::GetTitleContentPath(title_id), content.id); 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); return GetContentPath(title_id, content, map);
} }
} // namespace IOS::HLE } // namespace IOS::HLE

View File

@ -15,11 +15,11 @@
namespace IOS::HLE 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(); const u64 title_id = tmd.GetTitleId();
IOS::ES::Content content; ES::Content content;
if (!tmd.GetContent(content_index, &content)) if (!tmd.GetContent(content_index, &content))
return ES_EINVAL; 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) IPCCommandResult ESDevice::OpenContent(u32 uid, const IOCtlVRequest& request)
{ {
if (!request.HasNumberOfValidVectors(3, 0) || request.in_vectors[0].size != sizeof(u64) || 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)) request.in_vectors[2].size != sizeof(u32))
{ {
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
@ -76,7 +76,7 @@ IPCCommandResult ESDevice::OpenActiveTitleContent(u32 caller_uid, const IOCtlVRe
if (!m_title_context.active) if (!m_title_context.active)
return GetDefaultReply(ES_EINVAL); 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()); const u32 uid = uid_map.GetOrInsertUIDForTitle(m_title_context.tmd.GetTitleId());
if (caller_uid != 0 && caller_uid != uid) if (caller_uid != 0 && caller_uid != uid)
return GetDefaultReply(ES_EACCES); return GetDefaultReply(ES_EACCES);

View File

@ -16,7 +16,7 @@ namespace IOS::HLE
{ {
// Used by the GetStoredContents ioctlvs. This assumes that the first output vector // Used by the GetStoredContents ioctlvs. This assumes that the first output vector
// is used for the content count (u32). // 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) const IOCtlVRequest& request)
{ {
if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid()) 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 // 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). // 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, IPCCommandResult ESDevice::GetStoredContents(const ES::TMDReader& tmd, const IOCtlVRequest& request)
const IOCtlVRequest& request)
{ {
if (!tmd.IsValid()) if (!tmd.IsValid())
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
@ -58,7 +57,7 @@ IPCCommandResult ESDevice::GetStoredContentsCount(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); 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()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
return GetStoredContentsCount(tmd, request); return GetStoredContentsCount(tmd, request);
@ -70,7 +69,7 @@ IPCCommandResult ESDevice::GetStoredContents(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); 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()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
return GetStoredContents(tmd, request); return GetStoredContents(tmd, request);
@ -83,7 +82,7 @@ IPCCommandResult ESDevice::GetTMDStoredContentsCount(const IOCtlVRequest& reques
std::vector<u8> tmd_bytes(request.in_vectors[0].size); std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.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) 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); std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.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()) if (!tmd.IsValid())
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
@ -153,7 +152,7 @@ IPCCommandResult ESDevice::GetStoredTMDSize(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); 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()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
@ -171,7 +170,7 @@ IPCCommandResult ESDevice::GetStoredTMD(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); 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()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);

View File

@ -24,7 +24,7 @@
namespace IOS::HLE 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(); 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, const std::vector<u8>& cert_chain, TicketImportType type,
VerifySignature verify_signature) VerifySignature verify_signature)
{ {
IOS::ES::TicketReader ticket{ticket_bytes}; ES::TicketReader ticket{ticket_bytes};
if (!ticket.IsValid()) if (!ticket.IsValid())
return ES_EINVAL; return ES_EINVAL;
@ -116,7 +116,7 @@ static ReturnCode InitBackupKey(u64 tid, u32 title_flags, IOSC& iosc, IOSC::Hand
// Ignore the region byte. // Ignore the region byte.
const u64 title_id = tid | 0xff; 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 || if (title_id == Titles::SYSTEM_MENU || (title_flags & affected_type) != affected_type ||
!(title_id == 0x00010005735841ff || title_id - 0x00010005735a41ff <= 0x700)) !(title_id == 0x00010005735841ff || title_id - 0x00010005735a41ff <= 0x700))
{ {
@ -185,7 +185,7 @@ IPCCommandResult ESDevice::ImportTmd(Context& context, const IOCtlVRequest& requ
if (!request.HasNumberOfValidVectors(1, 0)) if (!request.HasNumberOfValidVectors(1, 0))
return GetDefaultReply(ES_EINVAL); 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); return GetDefaultReply(ES_EINVAL);
std::vector<u8> tmd(request.in_vectors[0].size); 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; return ret;
std::array<u8, 16> iv{}; std::array<u8, 16> iv{};
std::copy_n(&ticket_bytes[offsetof(IOS::ES::Ticket, title_id)], sizeof(u64), iv.begin()); std::copy_n(&ticket_bytes[offsetof(ES::Ticket, title_id)], sizeof(u64), iv.begin());
const u8 index = ticket_bytes[offsetof(IOS::ES::Ticket, common_key_index)]; const u8 index = ticket_bytes[offsetof(ES::Ticket, common_key_index)];
if (index >= IOSC::COMMON_KEY_HANDLES.size()) if (index >= IOSC::COMMON_KEY_HANDLES.size())
return ES_INVALID_TICKET; return ES_INVALID_TICKET;
return iosc.ImportSecretKey(*handle, IOSC::COMMON_KEY_HANDLES[index], iv.data(), 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, 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)) if (!request.HasNumberOfValidVectors(4, 0))
return GetDefaultReply(ES_EINVAL); 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); return GetDefaultReply(ES_EINVAL);
std::vector<u8> tmd(request.in_vectors[0].size); 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 // The IV for title content decryption is the lower two bytes of the
// content index, zero extended. // 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, if (!context.title_import_export.tmd.FindContentById(context.title_import_export.content.id,
&content_info)) &content_info))
return ES_EINVAL; 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)); 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; std::array<u8, 20> sha1;
mbedtls_sha1_ret(content.data(), info.size, sha1.data()); 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) if (decrypt_ret != IPC_SUCCESS)
return decrypt_ret; return decrypt_ret;
IOS::ES::Content content_info; ES::Content content_info;
context.title_import_export.tmd.FindContentById(context.title_import_export.content.id, context.title_import_export.tmd.FindContentById(context.title_import_export.content.id,
&content_info); &content_info);
if (!CheckIfContentHashMatches(decrypted_data, content_info)) if (!CheckIfContentHashMatches(decrypted_data, content_info))
@ -395,7 +395,7 @@ ReturnCode ESDevice::ImportContentEnd(Context& context, u32 content_fd)
std::string content_path; std::string content_path;
if (content_info.IsShared()) if (content_info.IsShared())
{ {
IOS::ES::SharedContentMap shared_content{fs}; ES::SharedContentMap shared_content{fs};
content_path = shared_content.AddSharedContent(content_info.sha1); content_path = shared_content.AddSharedContent(content_info.sha1);
} }
else else
@ -438,12 +438,12 @@ IPCCommandResult ESDevice::ImportContentEnd(Context& context, const IOCtlVReques
return GetDefaultReply(ImportContentEnd(context, content_fd)); 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 u64 title_id = tmd.GetTitleId();
const std::vector<IOS::ES::Content> contents = tmd.GetContents(); const std::vector<ES::Content> contents = tmd.GetContents();
const IOS::ES::SharedContentMap shared_content_map{ios.GetFS()}; const ES::SharedContentMap shared_content_map{ios.GetFS()};
return std::all_of(contents.cbegin(), contents.cend(), [&](const IOS::ES::Content& content) { return std::all_of(contents.cbegin(), contents.cend(), [&](const ES::Content& content) {
if (content.IsOptional()) if (content.IsOptional())
return true; return true;
@ -553,7 +553,7 @@ IPCCommandResult ESDevice::DeleteTitle(const IOCtlVRequest& request)
ReturnCode ESDevice::DeleteTicket(const u8* ticket_view) ReturnCode ESDevice::DeleteTicket(const u8* ticket_view)
{ {
const auto fs = m_ios.GetFS(); 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)) if (!CanDeleteTitle(title_id))
return ES_EINVAL; return ES_EINVAL;
@ -562,7 +562,7 @@ ReturnCode ESDevice::DeleteTicket(const u8* ticket_view)
if (!ticket.IsValid()) if (!ticket.IsValid())
return FS_ENOENT; 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); ticket.DeleteTicket(ticket_id);
const std::vector<u8>& new_ticket = ticket.GetBytes(); 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) IPCCommandResult ESDevice::DeleteTicket(const IOCtlVRequest& request)
{ {
if (!request.HasNumberOfValidVectors(1, 0) || 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); return GetDefaultReply(ES_EINVAL);
} }
@ -635,7 +635,7 @@ ReturnCode ESDevice::DeleteContent(u64 title_id, u32 content_id) const
if (!tmd.IsValid()) if (!tmd.IsValid())
return FS_ENOENT; return FS_ENOENT;
IOS::ES::Content content; ES::Content content;
if (!tmd.FindContentById(content_id, &content)) if (!tmd.FindContentById(content_id, &content))
return ES_EINVAL; return ES_EINVAL;
@ -708,7 +708,7 @@ ReturnCode ESDevice::ExportContentBegin(Context& context, u64 title_id, u32 cont
return ES_EINVAL; return ES_EINVAL;
} }
IOS::ES::Content content_info; ES::Content content_info;
if (!context.title_import_export.tmd.FindContentById(content_id, &content_info)) if (!context.title_import_export.tmd.FindContentById(content_id, &content_info))
return ES_EINVAL; return ES_EINVAL;
@ -819,7 +819,7 @@ IPCCommandResult ESDevice::ExportTitleDone(Context& context, const IOCtlVRequest
ReturnCode ESDevice::DeleteSharedContent(const std::array<u8, 20>& sha1) const 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); const auto content_path = map.GetFilenameFromSHA1(sha1);
if (!content_path) if (!content_path)
return ES_EINVAL; return ES_EINVAL;
@ -827,7 +827,7 @@ ReturnCode ESDevice::DeleteSharedContent(const std::array<u8, 20>& sha1) const
// Check whether the shared content is used by a system title. // Check whether the shared content is used by a system title.
const std::vector<u64> titles = GetInstalledTitles(); const std::vector<u64> titles = GetInstalledTitles();
const bool is_used_by_system_title = std::any_of(titles.begin(), titles.end(), [&](u64 id) { 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; return false;
const auto tmd = FindInstalledTMD(id); const auto tmd = FindInstalledTMD(id);

View File

@ -30,9 +30,8 @@ namespace IOS::HLE
// booted from the game list, though. // booted from the game list, though.
static bool ShouldReturnFakeViewsForIOSes(u64 title_id, const TitleContext& context) static bool ShouldReturnFakeViewsForIOSes(u64 title_id, const TitleContext& context)
{ {
const bool ios = const bool ios = IsTitleType(title_id, ES::TitleType::System) && title_id != Titles::SYSTEM_MENU;
IsTitleType(title_id, IOS::ES::TitleType::System) && title_id != Titles::SYSTEM_MENU; const bool disc_title = context.active && ES::IsDiscTitle(context.tmd.GetTitleId());
const bool disc_title = context.active && IOS::ES::IsDiscTitle(context.tmd.GetTitleId());
return Core::WantsDeterminism() || return Core::WantsDeterminism() ||
(ios && SConfig::GetInstance().m_disc_booted_from_game_list && disc_title); (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 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; u32 view_count = ticket.IsValid() ? static_cast<u32>(ticket.GetNumberOfTickets()) : 0;
if (!IOS::HLE::IsEmulated(TitleID)) if (!IsEmulated(TitleID))
{ {
view_count = 0; view_count = 0;
ERROR_LOG_FMT(IOS_ES, "GetViewCount: Dolphin doesn't emulate IOS title {:016x}", TitleID); 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 u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
const u32 maxViews = Memory::Read_U32(request.in_vectors[1].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); 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) for (u32 view = 0; view < number_of_views; ++view)
{ {
const std::vector<u8> ticket_view = ticket.GetRawTicketView(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()); ticket_view.data(), ticket_view.size());
} }
} }
else if (ShouldReturnFakeViewsForIOSes(TitleID, m_title_context)) 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); 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 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 title_id = Common::swap64(&ticket_view[offsetof(ES::TicketView, title_id)]);
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)]);
const auto installed_ticket = FindSignedTicket(title_id); const auto installed_ticket = FindSignedTicket(title_id);
// TODO: when we get std::optional, check for presence instead of validity. // 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. // Check for permission to export the ticket.
const u32 title_identifier = static_cast<u32>(m_title_context.tmd.GetTitleId()); const u32 title_identifier = static_cast<u32>(m_title_context.tmd.GetTitleId());
const u32 permitted_title_mask = 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 = const u32 permitted_title_id =
Common::swap32(ticket_bytes.data() + offsetof(IOS::ES::Ticket, permitted_title_id)); Common::swap32(ticket_bytes.data() + offsetof(ES::Ticket, permitted_title_id));
const u8 title_export_allowed = ticket_bytes[offsetof(IOS::ES::Ticket, title_export_allowed)]; 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. // 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 || 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 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) if (version == 1)
{ {
// Currently, we have no support for v1 tickets at all (unlike IOS), so we fake it // 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 != nullptr)
{ {
if (*ticket_size >= sizeof(IOS::ES::Ticket)) if (*ticket_size >= sizeof(ES::Ticket))
return GetV0TicketFromView(ticket_view, ticket); return GetV0TicketFromView(ticket_view, ticket);
return ES_EINVAL; return ES_EINVAL;
} }
*ticket_size = sizeof(IOS::ES::Ticket); *ticket_size = sizeof(ES::Ticket);
return IPC_SUCCESS; return IPC_SUCCESS;
} }
IPCCommandResult ESDevice::GetV0TicketFromView(const IOCtlVRequest& request) IPCCommandResult ESDevice::GetV0TicketFromView(const IOCtlVRequest& request)
{ {
if (!request.HasNumberOfValidVectors(1, 1) || 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(IOS::ES::Ticket)) request.io_vectors[0].size != sizeof(ES::Ticket))
{ {
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
} }
@ -174,7 +173,7 @@ IPCCommandResult ESDevice::GetTicketSizeFromView(const IOCtlVRequest& request)
{ {
u32 ticket_size = 0; u32 ticket_size = 0;
if (!request.HasNumberOfValidVectors(1, 1) || 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)) request.io_vectors[0].size != sizeof(ticket_size))
{ {
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
@ -188,7 +187,7 @@ IPCCommandResult ESDevice::GetTicketSizeFromView(const IOCtlVRequest& request)
IPCCommandResult ESDevice::GetTicketFromView(const IOCtlVRequest& request) IPCCommandResult ESDevice::GetTicketFromView(const IOCtlVRequest& request)
{ {
if (!request.HasNumberOfValidVectors(2, 1) || 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)) request.in_vectors[1].size != sizeof(u32))
{ {
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
@ -209,7 +208,7 @@ IPCCommandResult ESDevice::GetTMDViewSize(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
const u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); 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()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
@ -224,7 +223,7 @@ IPCCommandResult ESDevice::GetTMDViewSize(const IOCtlVRequest& request)
IPCCommandResult ESDevice::GetTMDViews(const IOCtlVRequest& request) IPCCommandResult ESDevice::GetTMDViews(const IOCtlVRequest& request)
{ {
if (!request.HasNumberOfValidVectors(2, 1) || 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) || request.in_vectors[1].size != sizeof(u32) ||
Memory::Read_U32(request.in_vectors[1].address) != request.io_vectors[0].size) Memory::Read_U32(request.in_vectors[1].address) != request.io_vectors[0].size)
{ {
@ -232,7 +231,7 @@ IPCCommandResult ESDevice::GetTMDViews(const IOCtlVRequest& request)
} }
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); 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()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
@ -266,7 +265,7 @@ IPCCommandResult ESDevice::DIGetTMDViewSize(const IOCtlVRequest& request)
{ {
std::vector<u8> tmd_bytes(request.in_vectors[0].size); std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.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. // Yes, this returns -1017, not ES_INVALID_TMD.
// IOS simply checks whether the TMD has all required content entries. // 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); std::vector<u8> tmd_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.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()) if (!tmd.IsValid())
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
@ -337,12 +336,12 @@ IPCCommandResult ESDevice::DIGetTMDView(const IOCtlVRequest& request)
IPCCommandResult ESDevice::DIGetTicketView(const IOCtlVRequest& request) IPCCommandResult ESDevice::DIGetTicketView(const IOCtlVRequest& request)
{ {
if (!request.HasNumberOfValidVectors(1, 1) || 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); 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. // 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) 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); std::vector<u8> ticket_bytes(request.in_vectors[0].size);
Memory::CopyFromEmu(ticket_bytes.data(), request.in_vectors[0].address, ticket_bytes.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); view = ticket.GetRawTicketView(0);
} }

View File

@ -272,7 +272,7 @@ IPCCommandResult FSDevice::Seek(const SeekRequest& request)
return GetFSReply(ConvertResult(ResultCode::Invalid)); return GetFSReply(ConvertResult(ResultCode::Invalid));
const Result<u32> result = 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); LogResult(result, "Seek({}, 0x{:08x}, {})", handle.name.data(), request.offset, request.mode);
if (!result) if (!result)
return GetFSReply(ConvertResult(result.Error())); return GetFSReply(ConvertResult(result.Error()));

View File

@ -17,7 +17,7 @@ class PointerWrap;
namespace IOS::HLE namespace IOS::HLE
{ {
constexpr IOS::HLE::FS::Fd INVALID_FD = 0xffffffff; constexpr FS::Fd INVALID_FD = 0xffffffff;
class FSDevice : public Device class FSDevice : public Device
{ {
@ -39,7 +39,7 @@ private:
{ {
u16 gid = 0; u16 gid = 0;
u32 uid = 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. // We use a std::array to keep this savestate friendly.
std::array<char, 64> name{}; std::array<char, 64> name{};
bool superblock_flush_needed = false; bool superblock_flush_needed = false;

View File

@ -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) Handle dest_handle, u32 pid)
{ {
if (!HasOwnership(signer_handle, pid) || !HasOwnership(dest_handle, pid)) if (!HasOwnership(signer_handle, pid) || !HasOwnership(dest_handle, pid))

View File

@ -214,8 +214,8 @@ public:
ReturnCode VerifyPublicKeySign(const std::array<u8, 20>& sha1, Handle signer_handle, ReturnCode VerifyPublicKeySign(const std::array<u8, 20>& sha1, Handle signer_handle,
const std::vector<u8>& signature, u32 pid) const; const std::vector<u8>& signature, u32 pid) const;
// Import a certificate (signed by the certificate in signer_handle) into dest_handle. // Import a certificate (signed by the certificate in signer_handle) into dest_handle.
ReturnCode ImportCertificate(const IOS::ES::CertReader& cert, Handle signer_handle, ReturnCode ImportCertificate(const ES::CertReader& cert, Handle signer_handle, Handle dest_handle,
Handle dest_handle, u32 pid); u32 pid);
// Ownership // Ownership
ReturnCode GetOwnership(Handle handle, u32* owner) const; ReturnCode GetOwnership(Handle handle, u32* owner) const;

View File

@ -23,7 +23,7 @@
namespace IOS::HLE 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 = { static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = {
/* Hashes from SHA-1 and above */ /* Hashes from SHA-1 and above */
@ -53,7 +53,7 @@ namespace
// field during the certificate verification process. // field during the certificate verification process.
int SSLSendWithoutSNI(void* ctx, const unsigned char* buf, size_t len) 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) if (ssl->ctx.state == MBEDTLS_SSL_SERVER_HELLO)
mbedtls_ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str()); 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) 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); return mbedtls_net_recv(&ssl->hostfd, buf, len);
} }

View File

@ -100,6 +100,6 @@ private:
constexpr bool IsSSLIDValid(int id) 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 } // namespace IOS::HLE

View File

@ -374,7 +374,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
if (it->is_ssl) if (it->is_ssl)
{ {
int sslID = Memory::Read_U32(BufferOut) - 1; int sslID = Memory::Read_U32(BufferOut) - 1;
if (IOS::HLE::IsSSLIDValid(sslID)) if (IsSSLIDValid(sslID))
{ {
switch (it->ssl_type) switch (it->ssl_type)
{ {

View File

@ -68,7 +68,7 @@ NetWDCommandDevice::NetWDCommandDevice(Kernel& ios, const std::string& device_na
m_nitro_enabled_channels = LegalNitroChannelMask; m_nitro_enabled_channels = LegalNitroChannelMask;
// TODO: Set the version string here. This is exposed to the PPC. // 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.enabled_channels = 0xfffe;
m_info.channel = SelectWifiChannel(m_info.enabled_channels, 0); 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. // The country code is supposed to be null terminated as it is logged with printf in WD.

View File

@ -388,8 +388,7 @@ bool IsEmulated(u32 major_version)
bool IsEmulated(u64 title_id) bool IsEmulated(u64 title_id)
{ {
const bool ios = const bool ios = IsTitleType(title_id, ES::TitleType::System) && title_id != Titles::SYSTEM_MENU;
IsTitleType(title_id, IOS::ES::TitleType::System) && title_id != Titles::SYSTEM_MENU;
if (!ios) if (!ios)
return true; return true;
const u32 version = static_cast<u32>(title_id); const u32 version = static_cast<u32>(title_id);

View File

@ -150,7 +150,7 @@ IPCCommandResult WFSIDevice::IOCtl(const IOCtlRequest& request)
WFS::NativePath(content_dir + "/_default.dol")); 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); ERROR_LOG_FMT(IOS_WFS, "IOCTL_WFSI_IMPORT_TITLE_INIT: TMD size too large ({})", tmd_size);
return_error_code = IPC_EINVAL; return_error_code = IPC_EINVAL;
@ -161,7 +161,7 @@ IPCCommandResult WFSIDevice::IOCtl(const IOCtlRequest& request)
Memory::CopyFromEmu(tmd_bytes.data(), tmd_addr, tmd_size); Memory::CopyFromEmu(tmd_bytes.data(), tmd_addr, tmd_size);
m_tmd.SetBytes(std::move(tmd_bytes)); 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()) if (!ticket.IsValid())
{ {
return_error_code = -11028; 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. // Initializes the IV from the index of the content in the TMD contents.
const u32 content_id = Memory::Read_U32(request.buffer_in + 8); 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)) if (!m_tmd.FindContentById(content_id, &content_info))
{ {
WARN_LOG_FMT(IOS_WFS, "{}: Content id {:08x} not found", ioctl_name, content_id); 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; return_error_code = -3;
if (homedir_path_len > 0x1FD) if (homedir_path_len > 0x1FD)
break; break;
auto device = IOS::HLE::GetIOS()->GetDeviceByName("/dev/usb/wfssrv"); auto device = GetIOS()->GetDeviceByName("/dev/usb/wfssrv");
if (!device) if (!device)
break; 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; return_error_code = IPC_SUCCESS;
break; break;
} }
@ -389,7 +389,7 @@ IPCCommandResult WFSIDevice::IOCtl(const IOCtlRequest& request)
break; break;
} }
const IOS::ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(tid); const ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(tid);
SetCurrentTitleIdAndGroupId(tmd.GetTitleId(), tmd.GetGroupId()); SetCurrentTitleIdAndGroupId(tmd.GetTitleId(), tmd.GetGroupId());
break; break;
} }

View File

@ -55,7 +55,7 @@ private:
u8 m_aes_key[0x10] = {}; u8 m_aes_key[0x10] = {};
u8 m_aes_iv[0x10] = {}; u8 m_aes_iv[0x10] = {};
IOS::ES::TMDReader m_tmd; ES::TMDReader m_tmd;
std::string m_base_extract_path; std::string m_base_extract_path;
u64 m_current_title_id; u64 m_current_title_id;