Skip to content

Commit

Permalink
NandPaths: Return paths that are relative to Wii NAND
Browse files Browse the repository at this point in the history
Since all FS access will go through the new FS interface (PR dolphin-emu#6421)
in order to keep track of metadata properly, there is no need to return
absolute paths anymore.

In fact, returning host paths is a roadblock to using the FS interface.

This starts the migration work by adding a way to get paths that are
relative to the Wii NAND instead of always getting absolute paths
on the host FS.

To prepare for future changes, this commit also makes returned paths
canonical by removing the trailing slash when it's unneeded.

Eventually, once everything has been migrated to the new interface,
we can remove the "from" parameter.
  • Loading branch information
leoetlino committed Apr 8, 2018
1 parent 9dbc760 commit 9b54533
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 20 deletions.
19 changes: 12 additions & 7 deletions Source/Core/Common/NandPaths.cpp
Expand Up @@ -24,41 +24,46 @@ std::string RootUserPath(FromWhichRoot from)
return File::GetUserPath(idx);
}

std::string GetImportTitlePath(u64 title_id, FromWhichRoot from)
static std::string RootUserPath(std::optional<FromWhichRoot> from)
{
return from ? RootUserPath(*from) : "";
}

std::string GetImportTitlePath(u64 title_id, std::optional<FromWhichRoot> from)
{
return RootUserPath(from) + StringFromFormat("/import/%08x/%08x",
static_cast<u32>(title_id >> 32),
static_cast<u32>(title_id));
}

std::string GetTicketFileName(u64 _titleID, FromWhichRoot from)
std::string GetTicketFileName(u64 _titleID, std::optional<FromWhichRoot> from)
{
return StringFromFormat("%s/ticket/%08x/%08x.tik", RootUserPath(from).c_str(),
(u32)(_titleID >> 32), (u32)_titleID);
}

std::string GetTitlePath(u64 title_id, FromWhichRoot from)
std::string GetTitlePath(u64 title_id, std::optional<FromWhichRoot> from)
{
return StringFromFormat("%s/title/%08x/%08x/", RootUserPath(from).c_str(),
static_cast<u32>(title_id >> 32), static_cast<u32>(title_id));
}

std::string GetTitleDataPath(u64 _titleID, FromWhichRoot from)
std::string GetTitleDataPath(u64 _titleID, std::optional<FromWhichRoot> from)
{
return GetTitlePath(_titleID, from) + "data/";
}

std::string GetTitleContentPath(u64 _titleID, FromWhichRoot from)
std::string GetTitleContentPath(u64 _titleID, std::optional<FromWhichRoot> from)
{
return GetTitlePath(_titleID, from) + "content/";
}

std::string GetTMDFileName(u64 _titleID, FromWhichRoot from)
std::string GetTMDFileName(u64 _titleID, std::optional<FromWhichRoot> from)
{
return GetTitleContentPath(_titleID, from) + "title.tmd";
}

bool IsTitlePath(const std::string& path, FromWhichRoot from, u64* title_id)
bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from, u64* title_id)
{
std::string expected_prefix = RootUserPath(from) + "/title/";
if (!StringBeginsWith(path, expected_prefix))
Expand Down
20 changes: 13 additions & 7 deletions Source/Core/Common/NandPaths.h
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include <optional>
#include <string>
#include <utility>
#include <vector>
Expand All @@ -20,17 +21,22 @@ enum FromWhichRoot

std::string RootUserPath(FromWhichRoot from);

// The following functions return paths relative to the NAND root.
// If a FromWhichRoot is passed, the NAND root on the host filesystem will be prepended to the path.
// TODO: remove the from parameter after all code is migrated off direct FS access.

// Returns /import/%08x/%08x. Intended for use by ES.
std::string GetImportTitlePath(u64 title_id, FromWhichRoot from = FROM_SESSION_ROOT);
std::string GetImportTitlePath(u64 title_id, std::optional<FromWhichRoot> from);

std::string GetTicketFileName(u64 _titleID, FromWhichRoot from);
std::string GetTitlePath(u64 title_id, FromWhichRoot from);
std::string GetTitleDataPath(u64 _titleID, FromWhichRoot from);
std::string GetTitleContentPath(u64 _titleID, FromWhichRoot from);
std::string GetTMDFileName(u64 _titleID, FromWhichRoot from);
std::string GetTicketFileName(u64 _titleID, std::optional<FromWhichRoot> from);
std::string GetTitlePath(u64 title_id, std::optional<FromWhichRoot> from);
std::string GetTitleDataPath(u64 _titleID, std::optional<FromWhichRoot> from);
std::string GetTitleContentPath(u64 _titleID, std::optional<FromWhichRoot> from);
std::string GetTMDFileName(u64 _titleID, std::optional<FromWhichRoot> from);

// Returns whether a path is within an installed title's directory.
bool IsTitlePath(const std::string& path, FromWhichRoot from, u64* title_id = nullptr);
bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from,
u64* title_id = nullptr);

// Escapes characters that are invalid or have special meanings in the host file system
std::string EscapeFileName(const std::string& filename);
Expand Down
15 changes: 10 additions & 5 deletions Source/Core/Core/IOS/ES/NandUtils.cpp
Expand Up @@ -42,7 +42,8 @@ static IOS::ES::TMDReader FindTMD(u64 title_id, const std::string& tmd_path)

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, Common::FROM_SESSION_ROOT) +
"/content/title.tmd");
}

IOS::ES::TMDReader ES::FindInstalledTMD(u64 title_id) const
Expand Down Expand Up @@ -218,7 +219,8 @@ bool ES::InitImport(u64 title_id)
// IOS moves the title content directory to /import if the TMD exists during an import.
if (File::Exists(Common::GetTMDFileName(title_id, Common::FROM_SESSION_ROOT)))
{
const std::string import_content_dir = Common::GetImportTitlePath(title_id) + "/content";
const std::string import_content_dir =
Common::GetImportTitlePath(title_id, Common::FROM_SESSION_ROOT) + "/content";
File::CreateFullPath(import_content_dir);
if (!File::Rename(content_dir, import_content_dir))
{
Expand All @@ -233,7 +235,8 @@ bool ES::InitImport(u64 title_id)
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";
const std::string import_content_dir =
Common::GetImportTitlePath(title_id, Common::FROM_SESSION_ROOT) + "/content";

// Remove everything not listed in the TMD.
std::unordered_set<std::string> expected_entries = {"title.tmd"};
Expand Down Expand Up @@ -274,15 +277,17 @@ bool ES::WriteImportTMD(const IOS::ES::TMDReader& tmd)
return false;
}

const std::string dest = Common::GetImportTitlePath(tmd.GetTitleId()) + "/content/title.tmd";
const std::string dest = Common::GetImportTitlePath(tmd.GetTitleId(), Common::FROM_SESSION_ROOT) +
"/content/title.tmd";
return File::Rename(tmd_path, dest);
}

void ES::FinishStaleImport(u64 title_id)
{
const auto import_tmd = FindImportTMD(title_id);
if (!import_tmd.IsValid())
File::DeleteDirRecursively(Common::GetImportTitlePath(title_id) + "/content");
File::DeleteDirRecursively(Common::GetImportTitlePath(title_id, Common::FROM_SESSION_ROOT) +
"/content");
else
FinishImport(import_tmd);
}
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/IOS/ES/TitleManagement.cpp
Expand Up @@ -341,7 +341,8 @@ static bool CheckIfContentHashMatches(const std::vector<u8>& content, const IOS:

static std::string GetImportContentPath(u64 title_id, u32 content_id)
{
return Common::GetImportTitlePath(title_id) + StringFromFormat("/content/%08x.app", content_id);
return Common::GetImportTitlePath(title_id, Common::FROM_SESSION_ROOT) +
StringFromFormat("/content/%08x.app", content_id);
}

ReturnCode ES::ImportContentEnd(Context& context, u32 content_fd)
Expand Down

0 comments on commit 9b54533

Please sign in to comment.