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\ES\ES.h" />
<ClInclude Include="IOS\ES\Formats.h" />
<ClInclude Include="IOS\ES\NandUtils.h" />
<ClInclude Include="IOS\FS\FileIO.h" />
<ClInclude Include="IOS\FS\FS.h" />
<ClInclude Include="IOS\Network\ICMPLin.h" />

View File

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

View File

@ -19,7 +19,6 @@
#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
@ -35,26 +34,6 @@ static TitleContext s_title_context;
// Title to launch after IOS has been reset and reloaded (similar to /sys/launch.sys).
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)
{
FinishAllStaleImports();
@ -193,7 +172,7 @@ IPCCommandResult ES::SetUID(u32 uid, const IOCtlVRequest& request)
return GetDefaultReply(ret);
}
const auto tmd = IOS::ES::FindInstalledTMD(title_id);
const auto tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);

View File

@ -97,6 +97,20 @@ public:
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
ReturnCode ImportTicket(const std::vector<u8>& ticket_bytes);
ReturnCode ImportTmd(Context& context, const std::vector<u8>& tmd_bytes);
@ -292,6 +306,16 @@ private:
ReturnCode CheckStreamKeyPermissions(u32 uid, const u8* ticket_view,
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);
u32 OpenTitleContent(u32 CFD, u64 TitleID, u16 Index);

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <algorithm>
#include <array>
#include <cctype>
#include <cinttypes>
#include <iterator>
@ -15,14 +16,16 @@
#include "Common/Logging/Log.h"
#include "Common/NandPaths.h"
#include "Common/StringUtil.h"
#include "Core/IOS/ES/ES.h"
#include "Core/IOS/ES/Formats.h"
#include "Core/IOS/ES/NandUtils.h"
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");
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()))
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");
}
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));
}
@ -88,17 +91,17 @@ static std::vector<u64> GetTitlesInTitleOrImport(const std::string& titles_dir)
return title_ids;
}
std::vector<u64> GetInstalledTitles()
std::vector<u64> ES::GetInstalledTitles() const
{
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");
}
std::vector<u64> GetTitlesWithTickets()
std::vector<u64> ES::GetTitlesWithTickets() const
{
const std::string tickets_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/ticket";
if (!File::IsDirectory(tickets_dir))
@ -138,15 +141,15 @@ std::vector<u64> GetTitlesWithTickets()
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())
return {};
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),
[&tmd, &shared](const auto& content) {
@ -163,7 +166,7 @@ std::vector<Content> GetStoredContentsFromTMD(const TMDReader& tmd)
return stored_contents;
}
u32 GetSharedContentsCount()
u32 ES::GetSharedContentsCount() const
{
const std::string shared1_path = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/shared1";
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};
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 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);
// 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;
}
bool FinishImport(const IOS::ES::TMDReader& tmd)
bool ES::FinishImport(const IOS::ES::TMDReader& tmd)
{
const u64 title_id = tmd.GetTitleId();
const std::string import_content_dir = Common::GetImportTitlePath(title_id) + "/content";
@ -244,7 +247,7 @@ bool FinishImport(const IOS::ES::TMDReader& tmd)
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";
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";
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

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 "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h"
#include "Core/IOS/ES/NandUtils.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS
@ -32,7 +31,7 @@ IPCCommandResult ES::GetStoredContentsCount(const IOS::ES::TMDReader& tmd,
if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid())
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);
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);
}
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);
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));
@ -67,7 +66,7 @@ IPCCommandResult ES::GetStoredContentsCount(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
return GetStoredContentsCount(tmd, request);
@ -79,7 +78,7 @@ IPCCommandResult ES::GetStoredContents(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
return GetStoredContents(tmd, request);
@ -131,14 +130,14 @@ IPCCommandResult ES::GetTitles(const std::vector<u64>& titles, const IOCtlVReque
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());
return GetTitleCount(titles, request);
}
IPCCommandResult ES::GetTitles(const IOCtlVRequest& request)
{
return GetTitles(IOS::ES::GetInstalledTitles(), request);
return GetTitles(GetInstalledTitles(), request);
}
IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
@ -147,7 +146,7 @@ IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
@ -165,7 +164,7 @@ IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request)
return GetDefaultReply(ES_EINVAL);
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id);
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return GetDefaultReply(FS_ENOENT);
@ -184,14 +183,14 @@ IPCCommandResult ES::GetStoredTMD(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());
return GetTitleCount(titles, request);
}
IPCCommandResult ES::GetOwnedTitles(const IOCtlVRequest& request)
{
return GetTitles(IOS::ES::GetTitlesWithTickets(), request);
return GetTitles(GetTitlesWithTickets(), 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))
return GetDefaultReply(ES_EINVAL);
const u32 count = IOS::ES::GetSharedContentsCount();
const u32 count = GetSharedContentsCount();
Memory::Write_U32(count, request.io_vectors[0].address);
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)
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);
Memory::CopyToEmu(request.io_vectors[0].address, hashes.data(), 20 * count);

View File

@ -20,7 +20,6 @@
#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"
@ -96,7 +95,7 @@ ReturnCode ES::ImportTmd(Context& context, const std::vector<u8>& tmd_bytes)
if (!context.title_import.tmd.IsValid())
return ES_EINVAL;
if (!IOS::ES::InitImport(context.title_import.tmd.GetTitleId()))
if (!InitImport(context.title_import.tmd.GetTitleId()))
return ES_EIO;
return IPC_SUCCESS;
@ -115,15 +114,6 @@ IPCCommandResult ES::ImportTmd(Context& context, const IOCtlVRequest& request)
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)
{
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).
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;
// TODO: check and use the other vectors.
@ -340,7 +330,7 @@ ReturnCode ES::ImportTitleCancel(Context& context)
if (!context.title_import.tmd.IsValid())
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());
context.title_import.tmd.SetBytes({});
@ -467,7 +457,7 @@ ReturnCode ES::DeleteContent(u64 title_id, u32 content_id) const
if (!CanDeleteTitle(title_id))
return ES_EINVAL;
const auto tmd = IOS::ES::FindInstalledTMD(title_id);
const auto tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return FS_ENOENT;
@ -501,7 +491,7 @@ ReturnCode ES::ExportTitleInit(Context& context, u64 title_id, u8* tmd_bytes, u3
if (context.title_export.valid)
return ES_EINVAL;
const auto tmd = IOS::ES::FindInstalledTMD(title_id);
const auto tmd = FindInstalledTMD(title_id);
if (!tmd.IsValid())
return FS_ENOENT;
@ -686,12 +676,12 @@ ReturnCode ES::DeleteSharedContent(const std::array<u8, 20>& sha1) const
return ES_EINVAL;
// Check whether the shared content is used by a system title.
const std::vector<u64> titles = IOS::ES::GetInstalledTitles();
const bool is_used_by_system_title = std::any_of(titles.begin(), titles.end(), [&sha1](u64 id) {
const std::vector<u64> titles = GetInstalledTitles();
const bool is_used_by_system_title = std::any_of(titles.begin(), titles.end(), [&](u64 id) {
if (!IOS::ES::IsTitleType(id, IOS::ES::TitleType::System))
return false;
const auto tmd = IOS::ES::FindInstalledTMD(id);
const auto tmd = FindInstalledTMD(id);
if (!tmd.IsValid())
return true;

View File

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