Merge pull request #9506 from leoetlino/less-verbose-names

IOS: Simplify unnecessarily qualified names
This commit is contained in:
Léo Lam 2021-02-13 12:41:17 +01:00 committed by GitHub
commit 389b01dae9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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;