diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index 0c8ed8946a..c9704450ab 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -150,6 +150,7 @@ set(SRCS
IOS/ES/ES.cpp
IOS/ES/Formats.cpp
IOS/ES/Identity.cpp
+ IOS/ES/NandUtils.cpp
IOS/ES/TitleContents.cpp
IOS/ES/TitleInformation.cpp
IOS/ES/TitleManagement.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 549bc38c35..86edd95d87 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -177,6 +177,7 @@
+
@@ -427,6 +428,7 @@
+
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 1d5792cc33..18bce72497 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -759,6 +759,9 @@
IOS\ES
+
+ IOS\ES
+
IOS\ES
@@ -1370,6 +1373,9 @@
IOS\ES
+
+ IOS\ES
+
IOS\FS
diff --git a/Source/Core/Core/IOS/ES/NandUtils.cpp b/Source/Core/Core/IOS/ES/NandUtils.cpp
new file mode 100644
index 0000000000..b30609a255
--- /dev/null
+++ b/Source/Core/Core/IOS/ES/NandUtils.cpp
@@ -0,0 +1,165 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include
+#include
+#include
+#include
+#include
+
+#include "Common/CommonTypes.h"
+#include "Common/FileUtil.h"
+#include "Common/Logging/Log.h"
+#include "Common/NandPaths.h"
+#include "Common/StringUtil.h"
+#include "Core/IOS/ES/Formats.h"
+#include "Core/IOS/ES/NandUtils.h"
+#include "DiscIO/NANDContentLoader.h"
+
+namespace IOS
+{
+namespace ES
+{
+static TMDReader FindTMD(u64 title_id, const std::string& tmd_path)
+{
+ File::IOFile file(tmd_path, "rb");
+ if (!file)
+ return {};
+
+ std::vector tmd_bytes(file.GetSize());
+ if (!file.ReadBytes(tmd_bytes.data(), tmd_bytes.size()))
+ return {};
+
+ return TMDReader{std::move(tmd_bytes)};
+}
+
+TMDReader FindImportTMD(u64 title_id)
+{
+ return FindTMD(title_id, Common::GetImportTitlePath(title_id) + "/content/title.tmd");
+}
+
+TMDReader FindInstalledTMD(u64 title_id)
+{
+ return FindTMD(title_id, Common::GetTMDFileName(title_id, Common::FROM_SESSION_ROOT));
+}
+
+static bool IsValidPartOfTitleID(const std::string& string)
+{
+ if (string.length() != 8)
+ return false;
+ return std::all_of(string.begin(), string.end(),
+ [](const auto character) { return std::isxdigit(character) != 0; });
+}
+
+static std::vector GetTitlesInTitleOrImport(const std::string& titles_dir)
+{
+ if (!File::IsDirectory(titles_dir))
+ {
+ ERROR_LOG(IOS_ES, "%s is not a directory", titles_dir.c_str());
+ return {};
+ }
+
+ std::vector title_ids;
+
+ // The /title and /import directories contain one directory per title type, and each of them has
+ // a directory per title (where the name is the low 32 bits of the title ID in %08x format).
+ const auto entries = File::ScanDirectoryTree(titles_dir, true);
+ for (const File::FSTEntry& title_type : entries.children)
+ {
+ if (!title_type.isDirectory || !IsValidPartOfTitleID(title_type.virtualName))
+ continue;
+
+ if (title_type.children.empty())
+ continue;
+
+ for (const File::FSTEntry& title_identifier : title_type.children)
+ {
+ if (!title_identifier.isDirectory || !IsValidPartOfTitleID(title_identifier.virtualName))
+ continue;
+
+ const u32 type = std::stoul(title_type.virtualName, nullptr, 16);
+ const u32 identifier = std::stoul(title_identifier.virtualName, nullptr, 16);
+ title_ids.push_back(static_cast(type) << 32 | identifier);
+ }
+ }
+
+ return title_ids;
+}
+
+std::vector GetInstalledTitles()
+{
+ return GetTitlesInTitleOrImport(Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/title");
+}
+
+std::vector GetTitleImports()
+{
+ return GetTitlesInTitleOrImport(Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/import");
+}
+
+std::vector GetTitlesWithTickets()
+{
+ const std::string tickets_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/ticket";
+ if (!File::IsDirectory(tickets_dir))
+ {
+ ERROR_LOG(IOS_ES, "/ticket is not a directory");
+ return {};
+ }
+
+ std::vector title_ids;
+
+ // The /ticket directory contains one directory per title type, and each of them contains
+ // one ticket per title (where the name is the low 32 bits of the title ID in %08x format).
+ const auto entries = File::ScanDirectoryTree(tickets_dir, true);
+ for (const File::FSTEntry& title_type : entries.children)
+ {
+ if (!title_type.isDirectory || !IsValidPartOfTitleID(title_type.virtualName))
+ continue;
+
+ if (title_type.children.empty())
+ continue;
+
+ for (const File::FSTEntry& ticket : title_type.children)
+ {
+ const std::string name_without_ext = ticket.virtualName.substr(0, 8);
+ if (ticket.isDirectory || !IsValidPartOfTitleID(name_without_ext) ||
+ name_without_ext + ".tik" != ticket.virtualName)
+ {
+ continue;
+ }
+
+ const u32 type = std::stoul(title_type.virtualName, nullptr, 16);
+ const u32 identifier = std::stoul(name_without_ext, nullptr, 16);
+ title_ids.push_back(static_cast(type) << 32 | identifier);
+ }
+ }
+
+ return title_ids;
+}
+
+std::vector GetStoredContentsFromTMD(const TMDReader& tmd)
+{
+ if (!tmd.IsValid())
+ return {};
+
+ const DiscIO::CSharedContent shared{Common::FROM_SESSION_ROOT};
+ const std::vector contents = tmd.GetContents();
+
+ std::vector stored_contents;
+
+ std::copy_if(contents.begin(), contents.end(), std::back_inserter(stored_contents),
+ [&tmd, &shared](const auto& content) {
+ if (content.IsShared())
+ {
+ const std::string path = shared.GetFilenameFromSHA1(content.sha1.data());
+ return path != "unk" && File::Exists(path);
+ }
+ return File::Exists(
+ Common::GetTitleContentPath(tmd.GetTitleId(), Common::FROM_SESSION_ROOT) +
+ StringFromFormat("%08x.app", content.id));
+ });
+
+ return stored_contents;
+}
+} // namespace ES
+} // namespace IOS
diff --git a/Source/Core/Core/IOS/ES/NandUtils.h b/Source/Core/Core/IOS/ES/NandUtils.h
new file mode 100644
index 0000000000..d9df9a74f2
--- /dev/null
+++ b/Source/Core/Core/IOS/ES/NandUtils.h
@@ -0,0 +1,30 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+
+#include "Common/CommonTypes.h"
+
+namespace IOS
+{
+namespace ES
+{
+struct Content;
+class TMDReader;
+
+TMDReader FindImportTMD(u64 title_id);
+TMDReader FindInstalledTMD(u64 title_id);
+
+// Get installed titles (in /title) without checking for TMDs at all.
+std::vector GetInstalledTitles();
+// Get titles which are being imported (in /import) without checking for TMDs at all.
+std::vector GetTitleImports();
+// Get titles for which there is a ticket (in /ticket).
+std::vector GetTitlesWithTickets();
+
+std::vector GetStoredContentsFromTMD(const TMDReader& tmd);
+} // namespace ES
+} // namespace IOS
diff --git a/Source/Core/Core/IOS/ES/TitleInformation.cpp b/Source/Core/Core/IOS/ES/TitleInformation.cpp
index dea38aa386..a70ac5b247 100644
--- a/Source/Core/Core/IOS/ES/TitleInformation.cpp
+++ b/Source/Core/Core/IOS/ES/TitleInformation.cpp
@@ -4,11 +4,8 @@
#include "Core/IOS/ES/ES.h"
-#include
-#include
#include
#include
-#include
#include
#include
@@ -18,6 +15,7 @@
#include "Common/StringUtil.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h"
+#include "Core/IOS/ES/NandUtils.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS
@@ -26,31 +24,6 @@ namespace HLE
{
namespace Device
{
-static std::vector GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd)
-{
- if (!tmd.IsValid())
- return {};
-
- const DiscIO::CSharedContent shared{Common::FROM_SESSION_ROOT};
- const std::vector contents = tmd.GetContents();
-
- std::vector stored_contents;
-
- std::copy_if(contents.begin(), contents.end(), std::back_inserter(stored_contents),
- [&tmd, &shared](const auto& content) {
- if (content.IsShared())
- {
- const std::string path = shared.GetFilenameFromSHA1(content.sha1.data());
- return path != "unk" && File::Exists(path);
- }
- return File::Exists(
- Common::GetTitleContentPath(tmd.GetTitleId(), Common::FROM_SESSION_ROOT) +
- StringFromFormat("%08x.app", content.id));
- });
-
- return stored_contents;
-}
-
// Used by the GetStoredContents ioctlvs. This assumes that the first output vector
// is used for the content count (u32).
IPCCommandResult ES::GetStoredContentsCount(const IOS::ES::TMDReader& tmd,
@@ -59,7 +32,7 @@ IPCCommandResult ES::GetStoredContentsCount(const IOS::ES::TMDReader& tmd,
if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid())
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
- const u16 num_contents = static_cast(GetStoredContentsFromTMD(tmd).size());
+ const u16 num_contents = static_cast(IOS::ES::GetStoredContentsFromTMD(tmd).size());
Memory::Write_U32(num_contents, request.io_vectors[0].address);
INFO_LOG(IOS_ES, "GetStoredContentsCount (0x%x): %u content(s) for %016" PRIx64, request.request,
@@ -80,7 +53,7 @@ IPCCommandResult ES::GetStoredContents(const IOS::ES::TMDReader& tmd, const IOCt
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
}
- const auto contents = GetStoredContentsFromTMD(tmd);
+ const auto contents = IOS::ES::GetStoredContentsFromTMD(tmd);
const u32 max_content_count = Memory::Read_U32(request.in_vectors[1].address);
for (u32 i = 0; i < std::min(static_cast(contents.size()), max_content_count); ++i)
Memory::Write_U32(contents[i].id, request.io_vectors[0].address + i * sizeof(u32));
@@ -94,10 +67,10 @@ IPCCommandResult ES::GetStoredContentsCount(const IOCtlVRequest& request)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
- const DiscIO::CNANDContentLoader& content_loader = AccessContentDevice(title_id);
- if (!content_loader.IsValid())
- return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
- return GetStoredContentsCount(content_loader.GetTMD(), request);
+ const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id);
+ if (!tmd.IsValid())
+ return GetDefaultReply(FS_ENOENT);
+ return GetStoredContentsCount(tmd, request);
}
IPCCommandResult ES::GetStoredContents(const IOCtlVRequest& request)
@@ -106,10 +79,10 @@ IPCCommandResult ES::GetStoredContents(const IOCtlVRequest& request)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
- const DiscIO::CNANDContentLoader& content_loader = AccessContentDevice(title_id);
- if (!content_loader.IsValid())
- return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
- return GetStoredContents(content_loader.GetTMD(), request);
+ const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id);
+ if (!tmd.IsValid())
+ return GetDefaultReply(FS_ENOENT);
+ return GetStoredContents(tmd, request);
}
IPCCommandResult ES::GetTMDStoredContentsCount(const IOCtlVRequest& request)
@@ -132,92 +105,6 @@ IPCCommandResult ES::GetTMDStoredContents(const IOCtlVRequest& request)
return GetStoredContents(IOS::ES::TMDReader{std::move(tmd_bytes)}, request);
}
-static bool IsValidPartOfTitleID(const std::string& string)
-{
- if (string.length() != 8)
- return false;
- return std::all_of(string.begin(), string.end(),
- [](const auto character) { return std::isxdigit(character) != 0; });
-}
-
-// Returns a vector of title IDs. IOS does not check the TMD at all here.
-static std::vector GetInstalledTitles()
-{
- const std::string titles_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/title";
- if (!File::IsDirectory(titles_dir))
- {
- ERROR_LOG(IOS_ES, "/title is not a directory");
- return {};
- }
-
- std::vector title_ids;
-
- // The /title directory contains one directory per title type, and each of them contains
- // a directory per title (where the name is the low 32 bits of the title ID in %08x format).
- const auto entries = File::ScanDirectoryTree(titles_dir, true);
- for (const File::FSTEntry& title_type : entries.children)
- {
- if (!title_type.isDirectory || !IsValidPartOfTitleID(title_type.virtualName))
- continue;
-
- if (title_type.children.empty())
- continue;
-
- for (const File::FSTEntry& title_identifier : title_type.children)
- {
- if (!title_identifier.isDirectory || !IsValidPartOfTitleID(title_identifier.virtualName))
- continue;
-
- const u32 type = std::stoul(title_type.virtualName, nullptr, 16);
- const u32 identifier = std::stoul(title_identifier.virtualName, nullptr, 16);
- title_ids.push_back(static_cast(type) << 32 | identifier);
- }
- }
-
- return title_ids;
-}
-
-// Returns a vector of title IDs for which there is a ticket.
-static std::vector GetTitlesWithTickets()
-{
- const std::string titles_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/ticket";
- if (!File::IsDirectory(titles_dir))
- {
- ERROR_LOG(IOS_ES, "/ticket is not a directory");
- return {};
- }
-
- std::vector title_ids;
-
- // The /ticket directory contains one directory per title type, and each of them contains
- // one ticket per title (where the name is the low 32 bits of the title ID in %08x format).
- const auto entries = File::ScanDirectoryTree(titles_dir, true);
- for (const File::FSTEntry& title_type : entries.children)
- {
- if (!title_type.isDirectory || !IsValidPartOfTitleID(title_type.virtualName))
- continue;
-
- if (title_type.children.empty())
- continue;
-
- for (const File::FSTEntry& ticket : title_type.children)
- {
- const std::string name_without_ext = ticket.virtualName.substr(0, 8);
- if (ticket.isDirectory || !IsValidPartOfTitleID(name_without_ext) ||
- name_without_ext + ".tik" != ticket.virtualName)
- {
- continue;
- }
-
- const u32 type = std::stoul(title_type.virtualName, nullptr, 16);
- const u32 identifier = std::stoul(name_without_ext, nullptr, 16);
- title_ids.push_back(static_cast(type) << 32 | identifier);
- }
- }
-
- return title_ids;
-}
-
IPCCommandResult ES::GetTitleCount(const std::vector& titles, const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != 4)
@@ -244,14 +131,14 @@ IPCCommandResult ES::GetTitles(const std::vector& titles, const IOCtlVReque
IPCCommandResult ES::GetTitleCount(const IOCtlVRequest& request)
{
- const std::vector titles = GetInstalledTitles();
+ const std::vector titles = IOS::ES::GetInstalledTitles();
INFO_LOG(IOS_ES, "GetTitleCount: %zu titles", titles.size());
return GetTitleCount(titles, request);
}
IPCCommandResult ES::GetTitles(const IOCtlVRequest& request)
{
- return GetTitles(GetInstalledTitles(), request);
+ return GetTitles(IOS::ES::GetInstalledTitles(), request);
}
IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
@@ -259,17 +146,15 @@ IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
if (!request.HasNumberOfValidVectors(1, 1))
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
- u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
- const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID);
-
- if (!Loader.IsValid() || !Loader.GetTMD().IsValid())
+ const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
+ const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id);
+ if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
- const u32 tmd_size = static_cast(Loader.GetTMD().GetRawTMD().size());
+ const u32 tmd_size = static_cast(tmd.GetRawTMD().size());
Memory::Write_U32(tmd_size, request.io_vectors[0].address);
- INFO_LOG(IOS_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)",
- (u32)(TitleID >> 32), (u32)TitleID, tmd_size);
+ INFO_LOG(IOS_ES, "GetStoredTMDSize: %u bytes for %016" PRIx64, tmd_size, title_id);
return GetDefaultReply(IPC_SUCCESS);
}
@@ -279,35 +164,34 @@ IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request)
if (!request.HasNumberOfValidVectors(2, 1))
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
- u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
- // TODO: actually use this param in when writing to the outbuffer :/
- const u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address);
- const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID);
-
- if (!Loader.IsValid() || !Loader.GetTMD().IsValid())
+ const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
+ const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id);
+ if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
- const std::vector raw_tmd = Loader.GetTMD().GetRawTMD();
+ // TODO: actually use this param in when writing to the outbuffer :/
+ const u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address);
+
+ const std::vector raw_tmd = tmd.GetRawTMD();
if (raw_tmd.size() != request.io_vectors[0].size)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size());
- INFO_LOG(IOS_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)",
- (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
+ INFO_LOG(IOS_ES, "GetStoredTMD: title %016" PRIx64 " (buffer size: %u)", title_id, MaxCount);
return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult ES::GetOwnedTitleCount(const IOCtlVRequest& request)
{
- const std::vector titles = GetTitlesWithTickets();
+ const std::vector titles = IOS::ES::GetTitlesWithTickets();
INFO_LOG(IOS_ES, "GetOwnedTitleCount: %zu titles", titles.size());
return GetTitleCount(titles, request);
}
IPCCommandResult ES::GetOwnedTitles(const IOCtlVRequest& request)
{
- return GetTitles(GetTitlesWithTickets(), request);
+ return GetTitles(IOS::ES::GetTitlesWithTickets(), request);
}
IPCCommandResult ES::GetBoot2Version(const IOCtlVRequest& request)
diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp
index 5a275fa954..dd327ee1cb 100644
--- a/Source/Core/Core/IOS/ES/TitleManagement.cpp
+++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp
@@ -19,6 +19,7 @@
#include "Common/StringUtil.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h"
+#include "Core/IOS/ES/NandUtils.h"
#include "Core/ec_wii.h"
#include "DiscIO/NANDContentLoader.h"
@@ -403,13 +404,11 @@ IPCCommandResult ES::ExportTitleInit(const IOCtlVRequest& request)
if (m_export_title_context.valid)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
- const auto& content_loader = AccessContentDevice(Memory::Read_U64(request.in_vectors[0].address));
- if (!content_loader.IsValid())
+ const auto tmd = IOS::ES::FindInstalledTMD(Memory::Read_U64(request.in_vectors[0].address));
+ if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
- if (!content_loader.GetTMD().IsValid())
- return GetDefaultReply(ES_INVALID_TMD);
- m_export_title_context.tmd = content_loader.GetTMD();
+ m_export_title_context.tmd = tmd;
const auto ticket = DiscIO::FindSignedTicket(m_export_title_context.tmd.GetTitleId());
if (!ticket.IsValid())
diff --git a/Source/Core/Core/IOS/ES/Views.cpp b/Source/Core/Core/IOS/ES/Views.cpp
index 3e18385078..e5b6bdb75a 100644
--- a/Source/Core/Core/IOS/ES/Views.cpp
+++ b/Source/Core/Core/IOS/ES/Views.cpp
@@ -14,6 +14,7 @@
#include "Core/ConfigManager.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h"
+#include "Core/IOS/ES/NandUtils.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS
@@ -96,16 +97,15 @@ IPCCommandResult ES::GetTMDViewSize(const IOCtlVRequest& request)
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
- const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID);
+ const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(TitleID);
- if (!Loader.IsValid())
+ if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
- const u32 view_size = static_cast(Loader.GetTMD().GetRawView().size());
+ const u32 view_size = static_cast(tmd.GetRawView().size());
Memory::Write_U32(view_size, request.io_vectors[0].address);
- INFO_LOG(IOS_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32),
- (u32)TitleID, view_size);
+ INFO_LOG(IOS_ES, "GetTMDViewSize: %u bytes for title %016" PRIx64, view_size, TitleID);
return GetDefaultReply(IPC_SUCCESS);
}
@@ -117,22 +117,18 @@ IPCCommandResult ES::GetTMDViews(const IOCtlVRequest& request)
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
u32 MaxCount = Memory::Read_U32(request.in_vectors[1].address);
- const DiscIO::CNANDContentLoader& Loader = AccessContentDevice(TitleID);
+ const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(TitleID);
- INFO_LOG(IOS_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x buffer size: %i",
- (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
-
- if (!Loader.IsValid())
+ if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
- const std::vector raw_view = Loader.GetTMD().GetRawView();
+ const std::vector raw_view = tmd.GetRawView();
if (raw_view.size() != request.io_vectors[0].size)
return GetDefaultReply(ES_PARAMETER_SIZE_OR_ALIGNMENT);
Memory::CopyToEmu(request.io_vectors[0].address, raw_view.data(), raw_view.size());
- INFO_LOG(IOS_ES, "IOCTL_ES_GETTMDVIEWS: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32),
- (u32)TitleID, MaxCount);
+ INFO_LOG(IOS_ES, "GetTMDView: %u bytes for title %016" PRIx64, MaxCount, TitleID);
return GetDefaultReply(IPC_SUCCESS);
}
diff --git a/Source/Core/DiscIO/NANDContentLoader.h b/Source/Core/DiscIO/NANDContentLoader.h
index edeea6431a..5b428bf5b4 100644
--- a/Source/Core/DiscIO/NANDContentLoader.h
+++ b/Source/Core/DiscIO/NANDContentLoader.h
@@ -23,6 +23,7 @@ namespace DiscIO
{
enum class Region;
+// TODO: move some of these to Core/IOS/ES.
bool AddTicket(const IOS::ES::TicketReader& signed_ticket);
IOS::ES::TicketReader FindSignedTicket(u64 title_id);