Merge pull request #5563 from leoetlino/internal-functions

IOS/ES: Make NandUtils member functions
This commit is contained in:
Leo Lam 2017-06-09 17:52:09 +02:00 committed by GitHub
commit 25850dd366
9 changed files with 91 additions and 121 deletions

View File

@ -438,7 +438,6 @@
<ClInclude Include="IOS\DI\DI.h" /> <ClInclude Include="IOS\DI\DI.h" />
<ClInclude Include="IOS\ES\ES.h" /> <ClInclude Include="IOS\ES\ES.h" />
<ClInclude Include="IOS\ES\Formats.h" /> <ClInclude Include="IOS\ES\Formats.h" />
<ClInclude Include="IOS\ES\NandUtils.h" />
<ClInclude Include="IOS\FS\FileIO.h" /> <ClInclude Include="IOS\FS\FileIO.h" />
<ClInclude Include="IOS\FS\FS.h" /> <ClInclude Include="IOS\FS\FS.h" />
<ClInclude Include="IOS\Network\ICMPLin.h" /> <ClInclude Include="IOS\Network\ICMPLin.h" />

View File

@ -1385,9 +1385,6 @@
<ClInclude Include="IOS\ES\ES.h"> <ClInclude Include="IOS\ES\ES.h">
<Filter>IOS\ES</Filter> <Filter>IOS\ES</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="IOS\ES\NandUtils.h">
<Filter>IOS\ES</Filter>
</ClInclude>
<ClInclude Include="IOS\FS\FileIO.h"> <ClInclude Include="IOS\FS\FileIO.h">
<Filter>IOS\FS</Filter> <Filter>IOS\FS</Filter>
</ClInclude> </ClInclude>

View File

@ -19,7 +19,6 @@
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h" #include "Core/IOS/ES/Formats.h"
#include "Core/IOS/ES/NandUtils.h"
#include "DiscIO/NANDContentLoader.h" #include "DiscIO/NANDContentLoader.h"
namespace IOS namespace IOS
@ -35,26 +34,6 @@ static TitleContext s_title_context;
// Title to launch after IOS has been reset and reloaded (similar to /sys/launch.sys). // Title to launch after IOS has been reset and reloaded (similar to /sys/launch.sys).
static u64 s_title_to_launch; static u64 s_title_to_launch;
static void FinishAllStaleImports()
{
const std::vector<u64> titles = IOS::ES::GetTitleImports();
for (const u64& title_id : titles)
{
const IOS::ES::TMDReader tmd = IOS::ES::FindImportTMD(title_id);
if (!tmd.IsValid())
{
File::DeleteDirRecursively(Common::GetImportTitlePath(title_id) + "/content");
continue;
}
FinishImport(tmd);
}
const std::string import_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/import";
File::DeleteDirRecursively(import_dir);
File::CreateDir(import_dir);
}
ES::ES(Kernel& ios, const std::string& device_name) : Device(ios, device_name) ES::ES(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
{ {
FinishAllStaleImports(); FinishAllStaleImports();
@ -193,7 +172,7 @@ IPCCommandResult ES::SetUID(u32 uid, const IOCtlVRequest& request)
return GetDefaultReply(ret); return GetDefaultReply(ret);
} }
const auto tmd = IOS::ES::FindInstalledTMD(title_id); const auto tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);

View File

@ -97,6 +97,20 @@ public:
s32 ipc_fd = -1; s32 ipc_fd = -1;
}; };
IOS::ES::TMDReader FindImportTMD(u64 title_id) const;
IOS::ES::TMDReader FindInstalledTMD(u64 title_id) const;
// Get installed titles (in /title) without checking for TMDs at all.
std::vector<u64> GetInstalledTitles() const;
// Get titles which are being imported (in /import) without checking for TMDs at all.
std::vector<u64> GetTitleImports() const;
// Get titles for which there is a ticket (in /ticket).
std::vector<u64> GetTitlesWithTickets() const;
std::vector<IOS::ES::Content> GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd) const;
u32 GetSharedContentsCount() const;
std::vector<std::array<u8, 20>> GetSharedContents() const;
// Title management // Title management
ReturnCode ImportTicket(const std::vector<u8>& ticket_bytes); ReturnCode ImportTicket(const std::vector<u8>& ticket_bytes);
ReturnCode ImportTmd(Context& context, const std::vector<u8>& tmd_bytes); ReturnCode ImportTmd(Context& context, const std::vector<u8>& tmd_bytes);
@ -292,6 +306,16 @@ private:
ReturnCode CheckStreamKeyPermissions(u32 uid, const u8* ticket_view, ReturnCode CheckStreamKeyPermissions(u32 uid, const u8* ticket_view,
const IOS::ES::TMDReader& tmd) const; const IOS::ES::TMDReader& tmd) const;
// Start a title import.
bool InitImport(u64 title_id);
// Clean up the import content directory and move it back to /title.
bool FinishImport(const IOS::ES::TMDReader& tmd);
// Write a TMD for a title in /import atomically.
bool WriteImportTMD(const IOS::ES::TMDReader& tmd);
// Finish stale imports and clear the import directory.
void FinishStaleImport(u64 title_id);
void FinishAllStaleImports();
static const DiscIO::NANDContentLoader& AccessContentDevice(u64 title_id); static const DiscIO::NANDContentLoader& AccessContentDevice(u64 title_id);
u32 OpenTitleContent(u32 CFD, u64 TitleID, u16 Index); u32 OpenTitleContent(u32 CFD, u64 TitleID, u16 Index);

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm> #include <algorithm>
#include <array>
#include <cctype> #include <cctype>
#include <cinttypes> #include <cinttypes>
#include <iterator> #include <iterator>
@ -15,14 +16,16 @@
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/NandPaths.h" #include "Common/NandPaths.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Core/IOS/ES/ES.h"
#include "Core/IOS/ES/Formats.h" #include "Core/IOS/ES/Formats.h"
#include "Core/IOS/ES/NandUtils.h"
namespace IOS namespace IOS
{ {
namespace ES namespace HLE
{ {
static TMDReader FindTMD(u64 title_id, const std::string& tmd_path) namespace Device
{
static IOS::ES::TMDReader FindTMD(u64 title_id, const std::string& tmd_path)
{ {
File::IOFile file(tmd_path, "rb"); File::IOFile file(tmd_path, "rb");
if (!file) if (!file)
@ -32,15 +35,15 @@ static TMDReader FindTMD(u64 title_id, const std::string& tmd_path)
if (!file.ReadBytes(tmd_bytes.data(), tmd_bytes.size())) if (!file.ReadBytes(tmd_bytes.data(), tmd_bytes.size()))
return {}; return {};
return TMDReader{std::move(tmd_bytes)}; return IOS::ES::TMDReader{std::move(tmd_bytes)};
} }
TMDReader FindImportTMD(u64 title_id) IOS::ES::TMDReader ES::FindImportTMD(u64 title_id) const
{ {
return FindTMD(title_id, Common::GetImportTitlePath(title_id) + "/content/title.tmd"); return FindTMD(title_id, Common::GetImportTitlePath(title_id) + "/content/title.tmd");
} }
TMDReader FindInstalledTMD(u64 title_id) IOS::ES::TMDReader ES::FindInstalledTMD(u64 title_id) const
{ {
return FindTMD(title_id, Common::GetTMDFileName(title_id, Common::FROM_SESSION_ROOT)); return FindTMD(title_id, Common::GetTMDFileName(title_id, Common::FROM_SESSION_ROOT));
} }
@ -88,17 +91,17 @@ static std::vector<u64> GetTitlesInTitleOrImport(const std::string& titles_dir)
return title_ids; return title_ids;
} }
std::vector<u64> GetInstalledTitles() std::vector<u64> ES::GetInstalledTitles() const
{ {
return GetTitlesInTitleOrImport(Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/title"); return GetTitlesInTitleOrImport(Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/title");
} }
std::vector<u64> GetTitleImports() std::vector<u64> ES::GetTitleImports() const
{ {
return GetTitlesInTitleOrImport(Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/import"); return GetTitlesInTitleOrImport(Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/import");
} }
std::vector<u64> GetTitlesWithTickets() std::vector<u64> ES::GetTitlesWithTickets() const
{ {
const std::string tickets_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/ticket"; const std::string tickets_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/ticket";
if (!File::IsDirectory(tickets_dir)) if (!File::IsDirectory(tickets_dir))
@ -138,15 +141,15 @@ std::vector<u64> GetTitlesWithTickets()
return title_ids; return title_ids;
} }
std::vector<Content> GetStoredContentsFromTMD(const TMDReader& tmd) std::vector<IOS::ES::Content> ES::GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd) const
{ {
if (!tmd.IsValid()) if (!tmd.IsValid())
return {}; return {};
const IOS::ES::SharedContentMap shared{Common::FROM_SESSION_ROOT}; const IOS::ES::SharedContentMap shared{Common::FROM_SESSION_ROOT};
const std::vector<Content> contents = tmd.GetContents(); const std::vector<IOS::ES::Content> contents = tmd.GetContents();
std::vector<Content> stored_contents; std::vector<IOS::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),
[&tmd, &shared](const auto& content) { [&tmd, &shared](const auto& content) {
@ -163,7 +166,7 @@ std::vector<Content> GetStoredContentsFromTMD(const TMDReader& tmd)
return stored_contents; return stored_contents;
} }
u32 GetSharedContentsCount() u32 ES::GetSharedContentsCount() const
{ {
const std::string shared1_path = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/shared1"; const std::string shared1_path = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/shared1";
const auto entries = File::ScanDirectoryTree(shared1_path, false); const auto entries = File::ScanDirectoryTree(shared1_path, false);
@ -174,13 +177,13 @@ u32 GetSharedContentsCount()
})); }));
} }
std::vector<std::array<u8, 20>> GetSharedContents() std::vector<std::array<u8, 20>> ES::GetSharedContents() const
{ {
const IOS::ES::SharedContentMap map{Common::FROM_SESSION_ROOT}; const IOS::ES::SharedContentMap map{Common::FROM_SESSION_ROOT};
return map.GetHashes(); return map.GetHashes();
} }
bool InitImport(u64 title_id) bool ES::InitImport(u64 title_id)
{ {
const std::string content_dir = Common::GetTitleContentPath(title_id, Common::FROM_SESSION_ROOT); const std::string content_dir = Common::GetTitleContentPath(title_id, Common::FROM_SESSION_ROOT);
const std::string data_dir = Common::GetTitleDataPath(title_id, Common::FROM_SESSION_ROOT); const std::string data_dir = Common::GetTitleDataPath(title_id, Common::FROM_SESSION_ROOT);
@ -193,7 +196,7 @@ bool InitImport(u64 title_id)
} }
} }
UIDSys uid_sys{Common::FROM_CONFIGURED_ROOT}; IOS::ES::UIDSys uid_sys{Common::FROM_CONFIGURED_ROOT};
uid_sys.GetOrInsertUIDForTitle(title_id); uid_sys.GetOrInsertUIDForTitle(title_id);
// IOS moves the title content directory to /import if the TMD exists during an import. // IOS moves the title content directory to /import if the TMD exists during an import.
@ -211,7 +214,7 @@ bool InitImport(u64 title_id)
return true; return true;
} }
bool FinishImport(const IOS::ES::TMDReader& tmd) bool ES::FinishImport(const IOS::ES::TMDReader& tmd)
{ {
const u64 title_id = tmd.GetTitleId(); const u64 title_id = tmd.GetTitleId();
const std::string import_content_dir = Common::GetImportTitlePath(title_id) + "/content"; const std::string import_content_dir = Common::GetImportTitlePath(title_id) + "/content";
@ -244,7 +247,7 @@ bool FinishImport(const IOS::ES::TMDReader& tmd)
return true; return true;
} }
bool WriteImportTMD(const IOS::ES::TMDReader& tmd) bool ES::WriteImportTMD(const IOS::ES::TMDReader& tmd)
{ {
const std::string tmd_path = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/tmp/title.tmd"; const std::string tmd_path = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/tmp/title.tmd";
File::CreateFullPath(tmd_path); File::CreateFullPath(tmd_path);
@ -258,5 +261,26 @@ bool WriteImportTMD(const IOS::ES::TMDReader& tmd)
const std::string dest = Common::GetImportTitlePath(tmd.GetTitleId()) + "/content/title.tmd"; const std::string dest = Common::GetImportTitlePath(tmd.GetTitleId()) + "/content/title.tmd";
return File::Rename(tmd_path, dest); return File::Rename(tmd_path, dest);
} }
} // namespace ES
void ES::FinishStaleImport(u64 title_id)
{
const auto import_tmd = FindImportTMD(title_id);
if (!import_tmd.IsValid())
File::DeleteDirRecursively(Common::GetImportTitlePath(title_id) + "/content");
else
FinishImport(import_tmd);
}
void ES::FinishAllStaleImports()
{
const std::vector<u64> titles = GetTitleImports();
for (const u64& title_id : titles)
FinishStaleImport(title_id);
const std::string import_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/import";
File::DeleteDirRecursively(import_dir);
File::CreateDir(import_dir);
}
} // namespace Device
} // namespace HLE
} // namespace IOS } // namespace IOS

View File

@ -1,41 +0,0 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <array>
#include <vector>
#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<u64> GetInstalledTitles();
// Get titles which are being imported (in /import) without checking for TMDs at all.
std::vector<u64> GetTitleImports();
// Get titles for which there is a ticket (in /ticket).
std::vector<u64> GetTitlesWithTickets();
std::vector<Content> GetStoredContentsFromTMD(const TMDReader& tmd);
u32 GetSharedContentsCount();
std::vector<std::array<u8, 20>> GetSharedContents();
// Start a title import.
bool InitImport(u64 title_id);
// Clean up the import content directory and move it back to /title.
bool FinishImport(const IOS::ES::TMDReader& tmd);
// Write a TMD for a title in /import atomically.
bool WriteImportTMD(const IOS::ES::TMDReader& tmd);
} // namespace ES
} // namespace IOS

View File

@ -15,7 +15,6 @@
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h" #include "Core/IOS/ES/Formats.h"
#include "Core/IOS/ES/NandUtils.h"
#include "DiscIO/NANDContentLoader.h" #include "DiscIO/NANDContentLoader.h"
namespace IOS namespace IOS
@ -32,7 +31,7 @@ IPCCommandResult ES::GetStoredContentsCount(const IOS::ES::TMDReader& tmd,
if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid()) if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid())
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
const u16 num_contents = static_cast<u16>(IOS::ES::GetStoredContentsFromTMD(tmd).size()); const u16 num_contents = static_cast<u16>(GetStoredContentsFromTMD(tmd).size());
Memory::Write_U32(num_contents, request.io_vectors[0].address); 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, INFO_LOG(IOS_ES, "GetStoredContentsCount (0x%x): %u content(s) for %016" PRIx64, request.request,
@ -53,7 +52,7 @@ IPCCommandResult ES::GetStoredContents(const IOS::ES::TMDReader& tmd, const IOCt
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
} }
const auto contents = IOS::ES::GetStoredContentsFromTMD(tmd); const auto contents = GetStoredContentsFromTMD(tmd);
const u32 max_content_count = Memory::Read_U32(request.in_vectors[1].address); const u32 max_content_count = Memory::Read_U32(request.in_vectors[1].address);
for (u32 i = 0; i < std::min(static_cast<u32>(contents.size()), max_content_count); ++i) for (u32 i = 0; i < std::min(static_cast<u32>(contents.size()), max_content_count); ++i)
Memory::Write_U32(contents[i].id, request.io_vectors[0].address + i * sizeof(u32)); Memory::Write_U32(contents[i].id, request.io_vectors[0].address + i * sizeof(u32));
@ -67,7 +66,7 @@ IPCCommandResult ES::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 = IOS::ES::FindInstalledTMD(title_id); const IOS::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);
@ -79,7 +78,7 @@ IPCCommandResult ES::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 = IOS::ES::FindInstalledTMD(title_id); const IOS::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);
@ -131,14 +130,14 @@ IPCCommandResult ES::GetTitles(const std::vector<u64>& titles, const IOCtlVReque
IPCCommandResult ES::GetTitleCount(const IOCtlVRequest& request) IPCCommandResult ES::GetTitleCount(const IOCtlVRequest& request)
{ {
const std::vector<u64> titles = IOS::ES::GetInstalledTitles(); const std::vector<u64> titles = GetInstalledTitles();
INFO_LOG(IOS_ES, "GetTitleCount: %zu titles", titles.size()); INFO_LOG(IOS_ES, "GetTitleCount: %zu titles", titles.size());
return GetTitleCount(titles, request); return GetTitleCount(titles, request);
} }
IPCCommandResult ES::GetTitles(const IOCtlVRequest& request) IPCCommandResult ES::GetTitles(const IOCtlVRequest& request)
{ {
return GetTitles(IOS::ES::GetInstalledTitles(), request); return GetTitles(GetInstalledTitles(), request);
} }
IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request) IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
@ -147,7 +146,7 @@ IPCCommandResult ES::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 = IOS::ES::FindInstalledTMD(title_id); const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
@ -165,7 +164,7 @@ IPCCommandResult ES::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 = IOS::ES::FindInstalledTMD(title_id); const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
@ -184,14 +183,14 @@ IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request)
IPCCommandResult ES::GetOwnedTitleCount(const IOCtlVRequest& request) IPCCommandResult ES::GetOwnedTitleCount(const IOCtlVRequest& request)
{ {
const std::vector<u64> titles = IOS::ES::GetTitlesWithTickets(); const std::vector<u64> titles = GetTitlesWithTickets();
INFO_LOG(IOS_ES, "GetOwnedTitleCount: %zu titles", titles.size()); INFO_LOG(IOS_ES, "GetOwnedTitleCount: %zu titles", titles.size());
return GetTitleCount(titles, request); return GetTitleCount(titles, request);
} }
IPCCommandResult ES::GetOwnedTitles(const IOCtlVRequest& request) IPCCommandResult ES::GetOwnedTitles(const IOCtlVRequest& request)
{ {
return GetTitles(IOS::ES::GetTitlesWithTickets(), request); return GetTitles(GetTitlesWithTickets(), request);
} }
IPCCommandResult ES::GetBoot2Version(const IOCtlVRequest& request) IPCCommandResult ES::GetBoot2Version(const IOCtlVRequest& request)
@ -211,7 +210,7 @@ IPCCommandResult ES::GetSharedContentsCount(const IOCtlVRequest& request) const
if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != sizeof(u32)) if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != sizeof(u32))
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
const u32 count = IOS::ES::GetSharedContentsCount(); const u32 count = GetSharedContentsCount();
Memory::Write_U32(count, request.io_vectors[0].address); Memory::Write_U32(count, request.io_vectors[0].address);
INFO_LOG(IOS_ES, "GetSharedContentsCount: %u contents", count); INFO_LOG(IOS_ES, "GetSharedContentsCount: %u contents", count);
@ -227,7 +226,7 @@ IPCCommandResult ES::GetSharedContents(const IOCtlVRequest& request) const
if (request.io_vectors[0].size != 20 * max_count) if (request.io_vectors[0].size != 20 * max_count)
return GetDefaultReply(ES_EINVAL); return GetDefaultReply(ES_EINVAL);
const std::vector<std::array<u8, 20>> hashes = IOS::ES::GetSharedContents(); const std::vector<std::array<u8, 20>> hashes = GetSharedContents();
const u32 count = std::min(static_cast<u32>(hashes.size()), max_count); const u32 count = std::min(static_cast<u32>(hashes.size()), max_count);
Memory::CopyToEmu(request.io_vectors[0].address, hashes.data(), 20 * count); Memory::CopyToEmu(request.io_vectors[0].address, hashes.data(), 20 * count);

View File

@ -20,7 +20,6 @@
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h" #include "Core/IOS/ES/Formats.h"
#include "Core/IOS/ES/NandUtils.h"
#include "Core/ec_wii.h" #include "Core/ec_wii.h"
#include "DiscIO/NANDContentLoader.h" #include "DiscIO/NANDContentLoader.h"
@ -96,7 +95,7 @@ ReturnCode ES::ImportTmd(Context& context, const std::vector<u8>& tmd_bytes)
if (!context.title_import.tmd.IsValid()) if (!context.title_import.tmd.IsValid())
return ES_EINVAL; return ES_EINVAL;
if (!IOS::ES::InitImport(context.title_import.tmd.GetTitleId())) if (!InitImport(context.title_import.tmd.GetTitleId()))
return ES_EIO; return ES_EIO;
return IPC_SUCCESS; return IPC_SUCCESS;
@ -115,15 +114,6 @@ IPCCommandResult ES::ImportTmd(Context& context, const IOCtlVRequest& request)
return GetDefaultReply(ImportTmd(context, tmd)); return GetDefaultReply(ImportTmd(context, tmd));
} }
static void CleanUpStaleImport(const u64 title_id)
{
const auto import_tmd = IOS::ES::FindImportTMD(title_id);
if (!import_tmd.IsValid())
File::DeleteDirRecursively(Common::GetImportTitlePath(title_id) + "/content");
else
IOS::ES::FinishImport(import_tmd);
}
ReturnCode ES::ImportTitleInit(Context& context, const std::vector<u8>& tmd_bytes) ReturnCode ES::ImportTitleInit(Context& context, const std::vector<u8>& tmd_bytes)
{ {
INFO_LOG(IOS_ES, "ImportTitleInit"); INFO_LOG(IOS_ES, "ImportTitleInit");
@ -135,9 +125,9 @@ ReturnCode ES::ImportTitleInit(Context& context, const std::vector<u8>& tmd_byte
} }
// Finish a previous import (if it exists). // Finish a previous import (if it exists).
CleanUpStaleImport(context.title_import.tmd.GetTitleId()); FinishStaleImport(context.title_import.tmd.GetTitleId());
if (!IOS::ES::InitImport(context.title_import.tmd.GetTitleId())) if (!InitImport(context.title_import.tmd.GetTitleId()))
return ES_EIO; return ES_EIO;
// TODO: check and use the other vectors. // TODO: check and use the other vectors.
@ -340,7 +330,7 @@ ReturnCode ES::ImportTitleCancel(Context& context)
if (!context.title_import.tmd.IsValid()) if (!context.title_import.tmd.IsValid())
return ES_EINVAL; return ES_EINVAL;
CleanUpStaleImport(context.title_import.tmd.GetTitleId()); FinishStaleImport(context.title_import.tmd.GetTitleId());
INFO_LOG(IOS_ES, "ImportTitleCancel: title %016" PRIx64, context.title_import.tmd.GetTitleId()); INFO_LOG(IOS_ES, "ImportTitleCancel: title %016" PRIx64, context.title_import.tmd.GetTitleId());
context.title_import.tmd.SetBytes({}); context.title_import.tmd.SetBytes({});
@ -467,7 +457,7 @@ ReturnCode ES::DeleteContent(u64 title_id, u32 content_id) const
if (!CanDeleteTitle(title_id)) if (!CanDeleteTitle(title_id))
return ES_EINVAL; return ES_EINVAL;
const auto tmd = IOS::ES::FindInstalledTMD(title_id); const auto tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid()) if (!tmd.IsValid())
return FS_ENOENT; return FS_ENOENT;
@ -501,7 +491,7 @@ ReturnCode ES::ExportTitleInit(Context& context, u64 title_id, u8* tmd_bytes, u3
if (context.title_export.valid) if (context.title_export.valid)
return ES_EINVAL; return ES_EINVAL;
const auto tmd = IOS::ES::FindInstalledTMD(title_id); const auto tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid()) if (!tmd.IsValid())
return FS_ENOENT; return FS_ENOENT;
@ -686,12 +676,12 @@ ReturnCode ES::DeleteSharedContent(const std::array<u8, 20>& sha1) const
return ES_EINVAL; return ES_EINVAL;
// 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 = IOS::ES::GetInstalledTitles(); const std::vector<u64> titles = GetInstalledTitles();
const bool is_used_by_system_title = std::any_of(titles.begin(), titles.end(), [&sha1](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 (!IOS::ES::IsTitleType(id, IOS::ES::TitleType::System))
return false; return false;
const auto tmd = IOS::ES::FindInstalledTMD(id); const auto tmd = FindInstalledTMD(id);
if (!tmd.IsValid()) if (!tmd.IsValid())
return true; return true;

View File

@ -16,7 +16,6 @@
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h" #include "Core/IOS/ES/Formats.h"
#include "Core/IOS/ES/NandUtils.h"
#include "DiscIO/NANDContentLoader.h" #include "DiscIO/NANDContentLoader.h"
namespace IOS namespace IOS
@ -206,7 +205,7 @@ IPCCommandResult ES::GetTMDViewSize(const IOCtlVRequest& request)
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(TitleID); const IOS::ES::TMDReader tmd = FindInstalledTMD(TitleID);
if (!tmd.IsValid()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);
@ -229,7 +228,7 @@ IPCCommandResult ES::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 = IOS::ES::FindInstalledTMD(title_id); const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid()) if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT); return GetDefaultReply(FS_ENOENT);