subrepo:
  subdir:   "libraries"
  merged:   "07af583b"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "07af583b"
git-subrepo:
  version:  "0.4.0"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "5d6aba9"
This commit is contained in:
Michael Scire
2019-12-09 03:57:37 -08:00
committed by SciresM
parent 28717bfd27
commit 0105455086
294 changed files with 29915 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2018-2019 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "interface_adapters/fssrv_storage_interface_adapter.hpp"
#include "interface_adapters/fssrv_filesystem_interface_adapter.hpp"

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2018-2019 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../fs/fs_common.hpp"
namespace ams::fssrv {
/* This is in fssrv::detail in official code. */
/* TODO: Consider moving to ::impl? */
class PathNormalizer {
public:
enum Option : u32 {
Option_None = BIT(0),
Option_PreserveUnc = BIT(1),
Option_PreserveTailSeparator = BIT(2),
Option_HasMountName = BIT(3),
Option_AcceptEmpty = BIT(4),
};
private:
using Buffer = std::unique_ptr<char[]>;
private:
Buffer buffer;
const char *path;
Result result;
private:
static Result Normalize(const char **out_path, Buffer *out_buf, const char *path, bool preserve_unc, bool preserve_tail_sep, bool has_mount_name);
public:
explicit PathNormalizer(const char *p) : buffer(), path(nullptr), result(ResultSuccess()) {
this->result = Normalize(&this->path, &this->buffer, p, false, false, false);
}
PathNormalizer(const char *p, u32 option) : buffer(), path(nullptr), result(ResultSuccess()) {
if ((option & Option_AcceptEmpty) && p[0] == '\x00') {
this->path = path;
} else {
const bool preserve_unc = (option & Option_PreserveUnc);
const bool preserve_tail_sep = (option & Option_PreserveTailSeparator);
const bool has_mount_name = (option & Option_HasMountName);
this->result = Normalize(&this->path, &this->buffer, p, preserve_unc, preserve_tail_sep, has_mount_name);
}
}
inline Result GetResult() const {
return this->result;
}
inline const char * GetPath() const {
return this->path;
}
};
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2018-2019 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../fs/fs_common.hpp"
#include "../fs/fs_directory.hpp"
#include "../sf/sf_buffer_tags.hpp"
namespace ams::fssrv::sf {
struct Path : ams::sf::LargeData {
char str[fs::EntryNameLengthMax + 1];
static constexpr Path Encode(const char *p) {
Path path = {};
for (size_t i = 0; i < sizeof(path) - 1; i++) {
path.str[i] = p[i];
if (p[i] == '\x00') {
break;
}
}
return path;
}
static constexpr size_t GetPathLength(const Path &path) {
size_t len = 0;
for (size_t i = 0; i < sizeof(path) - 1 && path.str[i] != '\x00'; i++) {
len++;
}
return len;
}
};
static_assert(std::is_pod<Path>::value && sizeof(Path) == FS_MAX_PATH);
using FspPath = Path;
}

View File

@@ -0,0 +1,192 @@
/*
* Copyright (c) 2018-2019 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../../fs/fs_common.hpp"
#include "../../fs/fs_file.hpp"
#include "../../fs/fs_directory.hpp"
#include "../../fs/fs_filesystem.hpp"
#include "../../fs/fs_query_range.hpp"
#include "../../fssrv/fssrv_sf_path.hpp"
#include "../../fssystem/fssystem_utility.hpp"
namespace ams::fs::fsa {
class IFile;
class IDirectory;
class IFileSystem;
}
namespace ams::fssrv::impl {
class FileSystemInterfaceAdapter;
class FileInterfaceAdapter final : public ams::sf::IServiceObject {
NON_COPYABLE(FileInterfaceAdapter);
public:
enum class CommandId {
Read = 0,
Write = 1,
Flush = 2,
SetSize = 3,
GetSize = 4,
OperateRange = 5,
};
private:
std::shared_ptr<FileSystemInterfaceAdapter> parent_filesystem;
std::unique_ptr<fs::fsa::IFile> base_file;
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
public:
FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, std::shared_ptr<FileSystemInterfaceAdapter> &&parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema);
~FileInterfaceAdapter();
private:
void InvalidateCache();
public:
/* Command API. */
Result Read(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size, fs::ReadOption option);
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size, fs::WriteOption option);
Result Flush();
Result SetSize(s64 size);
Result GetSize(ams::sf::Out<s64> out);
Result OperateRange(ams::sf::Out<fs::FileQueryRangeInfo> out, s32 op_id, s64 offset, s64 size);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 1.0.0- */
MAKE_SERVICE_COMMAND_META(Read),
MAKE_SERVICE_COMMAND_META(Write),
MAKE_SERVICE_COMMAND_META(Flush),
MAKE_SERVICE_COMMAND_META(SetSize),
MAKE_SERVICE_COMMAND_META(GetSize),
/* 4.0.0- */
MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_400),
};
};
class DirectoryInterfaceAdapter final : public ams::sf::IServiceObject {
NON_COPYABLE(DirectoryInterfaceAdapter);
public:
enum class CommandId {
Read = 0,
GetEntryCount = 1,
};
private:
std::shared_ptr<FileSystemInterfaceAdapter> parent_filesystem;
std::unique_ptr<fs::fsa::IDirectory> base_dir;
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
public:
DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, std::shared_ptr<FileSystemInterfaceAdapter> &&parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema);
~DirectoryInterfaceAdapter();
public:
/* Command API */
Result Read(ams::sf::Out<s64> out, const ams::sf::OutBuffer &out_entries);
Result GetEntryCount(ams::sf::Out<s64> out);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(Read),
MAKE_SERVICE_COMMAND_META(GetEntryCount),
};
};
class FileSystemInterfaceAdapter final : public std::enable_shared_from_this<FileSystemInterfaceAdapter>, public ams::sf::IServiceObject {
NON_COPYABLE(FileSystemInterfaceAdapter);
public:
enum class CommandId {
/* 1.0.0+ */
CreateFile = 0,
DeleteFile = 1,
CreateDirectory = 2,
DeleteDirectory = 3,
DeleteDirectoryRecursively = 4,
RenameFile = 5,
RenameDirectory = 6,
GetEntryType = 7,
OpenFile = 8,
OpenDirectory = 9,
Commit = 10,
GetFreeSpaceSize = 11,
GetTotalSpaceSize = 12,
/* 3.0.0+ */
CleanDirectoryRecursively = 13,
GetFileTimeStampRaw = 14,
/* 4.0.0+ */
QueryEntry = 15,
};
private:
std::shared_ptr<fs::fsa::IFileSystem> base_fs;
std::unique_lock<fssystem::SemaphoreAdapter> mount_count_semaphore;
os::ReadWriteLock invalidation_lock;
bool open_count_limited;
bool deep_retry_enabled = false;
public:
FileSystemInterfaceAdapter(std::shared_ptr<fs::fsa::IFileSystem> &&fs, bool open_limited);
/* TODO: Other constructors. */
~FileSystemInterfaceAdapter();
public:
bool IsDeepRetryEnabled() const;
bool IsAccessFailureDetectionObserved() const;
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
os::ReadWriteLock &GetReadWriteLockForCacheInvalidation();
public:
/* Command API. */
Result CreateFile(const fssrv::sf::Path &path, s64 size, s32 option);
Result DeleteFile(const fssrv::sf::Path &path);
Result CreateDirectory(const fssrv::sf::Path &path);
Result DeleteDirectory(const fssrv::sf::Path &path);
Result DeleteDirectoryRecursively(const fssrv::sf::Path &path);
Result RenameFile(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path);
Result RenameDirectory(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path);
Result GetEntryType(ams::sf::Out<u32> out, const fssrv::sf::Path &path);
Result OpenFile(ams::sf::Out<std::shared_ptr<FileInterfaceAdapter>> out, const fssrv::sf::Path &path, u32 mode);
Result OpenDirectory(ams::sf::Out<std::shared_ptr<DirectoryInterfaceAdapter>> out, const fssrv::sf::Path &path, u32 mode);
Result Commit();
Result GetFreeSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path);
Result GetTotalSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path);
Result CleanDirectoryRecursively(const fssrv::sf::Path &path);
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path);
Result QueryEntry(const ams::sf::OutBuffer &out_buf, const ams::sf::InBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 1.0.0- */
MAKE_SERVICE_COMMAND_META(CreateFile),
MAKE_SERVICE_COMMAND_META(DeleteFile),
MAKE_SERVICE_COMMAND_META(CreateDirectory),
MAKE_SERVICE_COMMAND_META(DeleteDirectory),
MAKE_SERVICE_COMMAND_META(DeleteDirectoryRecursively),
MAKE_SERVICE_COMMAND_META(RenameFile),
MAKE_SERVICE_COMMAND_META(RenameDirectory),
MAKE_SERVICE_COMMAND_META(GetEntryType),
MAKE_SERVICE_COMMAND_META(OpenFile),
MAKE_SERVICE_COMMAND_META(OpenDirectory),
MAKE_SERVICE_COMMAND_META(Commit),
MAKE_SERVICE_COMMAND_META(GetFreeSpaceSize),
MAKE_SERVICE_COMMAND_META(GetTotalSpaceSize),
/* 3.0.0- */
MAKE_SERVICE_COMMAND_META(CleanDirectoryRecursively, hos::Version_300),
MAKE_SERVICE_COMMAND_META(GetFileTimeStampRaw, hos::Version_300),
/* 4.0.0- */
MAKE_SERVICE_COMMAND_META(QueryEntry, hos::Version_400),
};
};
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2018-2019 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../../fs/fs_common.hpp"
#include "../../fs/fs_query_range.hpp"
#include "../../fssystem/fssystem_utility.hpp"
namespace ams::fs {
class IStorage;
}
namespace ams::fssrv::impl {
class StorageInterfaceAdapter final : public ams::sf::IServiceObject {
NON_COPYABLE(StorageInterfaceAdapter);
public:
enum class CommandId {
Read = 0,
Write = 1,
Flush = 2,
SetSize = 3,
GetSize = 4,
OperateRange = 5,
};
private:
/* TODO: Nintendo uses fssystem::AsynchronousAccessStorage here. */
std::shared_ptr<fs::IStorage> base_storage;
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
os::ReadWriteLock invalidation_lock;
/* TODO: DataStorageContext. */
bool deep_retry_enabled = false;
public:
StorageInterfaceAdapter(fs::IStorage *storage);
StorageInterfaceAdapter(std::unique_ptr<fs::IStorage> storage);
explicit StorageInterfaceAdapter(std::shared_ptr<fs::IStorage> &&storage);
/* TODO: Other constructors. */
~StorageInterfaceAdapter();
private:
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
private:
/* Command API. */
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size);
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size);
Result Flush();
Result SetSize(s64 size);
Result GetSize(ams::sf::Out<s64> out);
Result OperateRange(ams::sf::Out<fs::StorageQueryRangeInfo> out, s32 op_id, s64 offset, s64 size);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 1.0.0- */
MAKE_SERVICE_COMMAND_META(Read),
MAKE_SERVICE_COMMAND_META(Write),
MAKE_SERVICE_COMMAND_META(Flush),
MAKE_SERVICE_COMMAND_META(SetSize),
MAKE_SERVICE_COMMAND_META(GetSize),
/* 4.0.0- */
MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_400),
};
};
}