Skip to content

Commit

Permalink
Merge pull request dolphin-emu#8539 from leoetlino/fs-accuracy
Browse files Browse the repository at this point in the history
IOS/FS: Reimplement many functions in a more accurate way
  • Loading branch information
Tilka authored Jan 25, 2020
2 parents 2edcb29 + c02e7de commit 73aea8a
Show file tree
Hide file tree
Showing 10 changed files with 699 additions and 147 deletions.
6 changes: 0 additions & 6 deletions Source/Core/Core/IOS/ES/NandUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,6 @@ static std::vector<u64> GetTitlesInTitleOrImport(FS::FileSystem* fs, const std::
}
}

// On a real Wii, the title list is not in any particular order. However, because of how
// the flash filesystem works, titles such as 1-2 are *never* in the first position.
// We must keep this behaviour, or some versions of the System Menu may break.

std::sort(title_ids.begin(), title_ids.end(), std::greater<>());

return title_ids;
}

Expand Down
24 changes: 18 additions & 6 deletions Source/Core/Core/IOS/FS/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@

namespace IOS::HLE::FS
{
bool IsValidPath(std::string_view path)
{
return path == "/" || IsValidNonRootPath(path);
}

bool IsValidNonRootPath(std::string_view path)
{
return path.length() > 1 && path.length() <= MaxPathLength && path[0] == '/' &&
path.back() != '/';
}

SplitPathResult SplitPathAndBasename(std::string_view path)
{
const auto last_separator = path.rfind('/');
return {std::string(path.substr(0, std::max<size_t>(1, last_separator))),
std::string(path.substr(last_separator + 1))};
}

std::unique_ptr<FileSystem> MakeFileSystem(Location location)
{
const std::string nand_root =
Expand Down Expand Up @@ -66,12 +84,6 @@ Result<FileStatus> FileHandle::GetStatus() const
return m_fs->GetFileStatus(*m_fd);
}

void FileSystem::Init()
{
if (Delete(0, 0, "/tmp") == ResultCode::Success)
CreateDirectory(0, 0, "/tmp", 0, {Mode::ReadWrite, Mode::ReadWrite, Mode::ReadWrite});
}

Result<FileHandle> FileSystem::CreateAndOpenFile(Uid uid, Gid gid, const std::string& path,
Modes modes)
{
Expand Down
46 changes: 43 additions & 3 deletions Source/Core/Core/IOS/FS/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#ifdef _WIN32
Expand Down Expand Up @@ -76,6 +77,16 @@ struct Modes
{
Mode owner, group, other;
};
inline bool operator==(const Modes& lhs, const Modes& rhs)
{
const auto fields = [](const Modes& obj) { return std::tie(obj.owner, obj.group, obj.other); };
return fields(lhs) == fields(rhs);
}

inline bool operator!=(const Modes& lhs, const Modes& rhs)
{
return !(lhs == rhs);
}

struct Metadata
{
Expand Down Expand Up @@ -111,6 +122,38 @@ struct FileStatus
u32 size;
};

/// The maximum number of components a path can have.
constexpr size_t MaxPathDepth = 8;
/// The maximum number of characters a path can have.
constexpr size_t MaxPathLength = 64;

/// Returns whether a Wii path is valid.
bool IsValidPath(std::string_view path);
bool IsValidNonRootPath(std::string_view path);

struct SplitPathResult
{
std::string parent;
std::string file_name;
};
inline bool operator==(const SplitPathResult& lhs, const SplitPathResult& rhs)
{
const auto fields = [](const SplitPathResult& obj) {
return std::tie(obj.parent, obj.file_name);
};
return fields(lhs) == fields(rhs);
}

inline bool operator!=(const SplitPathResult& lhs, const SplitPathResult& rhs)
{
return !(lhs == rhs);
}

/// Split a path into a parent path and the file name. Takes a *valid non-root* path.
///
/// Example: /shared2/sys/SYSCONF => {/shared2/sys, SYSCONF}
SplitPathResult SplitPathAndBasename(std::string_view path);

class FileSystem;
class FileHandle final
{
Expand Down Expand Up @@ -196,9 +239,6 @@ class FileSystem
virtual Result<NandStats> GetNandStats() = 0;
/// Get usage information about a directory (used cluster and inode counts).
virtual Result<DirectoryStats> GetDirectoryStats(const std::string& path) = 0;

protected:
void Init();
};

template <typename T>
Expand Down
6 changes: 6 additions & 0 deletions Source/Core/Core/IOS/FS/FileSystemProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Core/HW/Memmap.h"
#include "Core/HW/SystemTimers.h"
#include "Core/IOS/FS/FileSystem.h"
#include "Core/IOS/Uids.h"

namespace IOS::HLE::Device
{
Expand All @@ -37,6 +38,11 @@ constexpr size_t CLUSTER_DATA_SIZE = 0x4000;

FS::FS(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
{
if (ios.GetFS()->Delete(PID_KERNEL, PID_KERNEL, "/tmp") == ResultCode::Success)
{
ios.GetFS()->CreateDirectory(PID_KERNEL, PID_KERNEL, "/tmp", 0,
{Mode::ReadWrite, Mode::ReadWrite, Mode::ReadWrite});
}
}

void FS::DoState(PointerWrap& p)
Expand Down
Loading

0 comments on commit 73aea8a

Please sign in to comment.