Revert "hoc-clk: add live vdd2, live boost clock and basic pwm dimming"
This reverts commit 15b7df8ef1.
This commit is contained in:
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/common/fs_dbm_rom_types.hpp>
|
||||
#include <stratosphere/fs/common/fs_dbm_rom_path_tool.hpp>
|
||||
#include <stratosphere/fs/common/fs_dbm_rom_key_value_storage.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
class HierarchicalRomFileTable {
|
||||
public:
|
||||
using Position = u32;
|
||||
using StorageSizeType = u32;
|
||||
|
||||
struct FindPosition {
|
||||
Position next_dir;
|
||||
Position next_file;
|
||||
};
|
||||
static_assert(util::is_pod<FindPosition>::value);
|
||||
|
||||
using FileInfo = RomFileInfo;
|
||||
|
||||
static constexpr RomFileId PositionToFileId(Position pos) {
|
||||
return static_cast<RomFileId>(pos);
|
||||
}
|
||||
|
||||
static constexpr Position FileIdToPosition(RomFileId id) {
|
||||
return static_cast<Position>(id);
|
||||
}
|
||||
private:
|
||||
static constexpr inline Position InvalidPosition = ~Position();
|
||||
static constexpr inline Position RootPosition = 0;
|
||||
static constexpr inline size_t ReservedDirectoryCount = 1;
|
||||
|
||||
static constexpr RomDirectoryId PositionToDirectoryId(Position pos) {
|
||||
return static_cast<RomDirectoryId>(pos);
|
||||
}
|
||||
|
||||
static constexpr Position DirectoryIdToPosition(RomDirectoryId id) {
|
||||
return static_cast<Position>(id);
|
||||
}
|
||||
|
||||
static_assert(std::is_same<RomDirectoryId, RomFileId>::value);
|
||||
|
||||
struct RomDirectoryEntry {
|
||||
Position next;
|
||||
Position dir;
|
||||
Position file;
|
||||
};
|
||||
static_assert(util::is_pod<RomDirectoryEntry>::value);
|
||||
|
||||
struct RomFileEntry {
|
||||
Position next;
|
||||
FileInfo info;
|
||||
};
|
||||
static_assert(util::is_pod<RomFileEntry>::value);
|
||||
|
||||
static constexpr inline u32 MaxKeyLength = RomPathTool::MaxPathLength;
|
||||
|
||||
template<typename ImplKeyType, typename ClientKeyType, typename ValueType>
|
||||
class EntryMapTable : public KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength> {
|
||||
public:
|
||||
using ImplKey = ImplKeyType;
|
||||
using ClientKey = ClientKeyType;
|
||||
using Value = ValueType;
|
||||
using Position = HierarchicalRomFileTable::Position;
|
||||
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
|
||||
public:
|
||||
Result Add(Position *out, const ClientKeyType &key, const Value &value) {
|
||||
R_RETURN(Base::AddInternal(out, key.key, key.Hash(), key.name.begin(), key.name.length(), value));
|
||||
}
|
||||
|
||||
Result Get(Position *out_pos, Value *out_val, const ClientKeyType &key) {
|
||||
R_RETURN(Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.begin(), key.name.length()));
|
||||
}
|
||||
|
||||
Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) {
|
||||
R_RETURN(Base::GetByPosition(out_key, out_val, pos));
|
||||
}
|
||||
|
||||
Result GetByPosition(ImplKey *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
|
||||
R_RETURN(Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos));
|
||||
}
|
||||
|
||||
Result SetByPosition(Position pos, const Value &value) {
|
||||
R_RETURN(Base::SetByPosition(pos, value));
|
||||
}
|
||||
};
|
||||
|
||||
struct RomEntryKey {
|
||||
Position parent;
|
||||
|
||||
bool IsEqual(const RomEntryKey &rhs, const void *aux_lhs, size_t aux_lhs_size, const void *aux_rhs, size_t aux_rhs_size) const {
|
||||
if (this->parent != rhs.parent) {
|
||||
return false;
|
||||
}
|
||||
if (aux_lhs_size != aux_rhs_size) {
|
||||
return false;
|
||||
}
|
||||
return RomPathTool::IsEqualPath(reinterpret_cast<const RomPathChar *>(aux_lhs), reinterpret_cast<const RomPathChar *>(aux_rhs), aux_lhs_size / sizeof(RomPathChar));
|
||||
}
|
||||
};
|
||||
static_assert(util::is_pod<RomEntryKey>::value);
|
||||
|
||||
struct EntryKey {
|
||||
RomEntryKey key;
|
||||
RomPathTool::RomEntryName name;
|
||||
|
||||
constexpr u32 Hash() const {
|
||||
u32 hash = this->key.parent ^ 123456789;
|
||||
const RomPathChar * cur = this->name.begin();
|
||||
const RomPathChar * const end = this->name.end();
|
||||
while (cur < end) {
|
||||
const u32 c = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(cur++)));
|
||||
hash = ((hash >> 5) | (hash << 27)) ^ c;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
|
||||
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;
|
||||
private:
|
||||
DirectoryEntryMapTable m_dir_table;
|
||||
FileEntryMapTable m_file_table;
|
||||
public:
|
||||
static s64 QueryDirectoryEntryBucketStorageSize(StorageSizeType count);
|
||||
static s64 QueryDirectoryEntrySize(StorageSizeType aux_size);
|
||||
static s64 QueryFileEntryBucketStorageSize(StorageSizeType count);
|
||||
static s64 QueryFileEntrySize(StorageSizeType aux_size);
|
||||
|
||||
static Result Format(SubStorage dir_bucket, SubStorage file_bucket);
|
||||
public:
|
||||
HierarchicalRomFileTable();
|
||||
|
||||
Result Initialize(SubStorage dir_bucket, SubStorage dir_entry, SubStorage file_bucket, SubStorage file_entry);
|
||||
void Finalize();
|
||||
|
||||
Result CreateRootDirectory();
|
||||
Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path);
|
||||
Result CreateFile(RomFileId *out, const RomPathChar *path, const FileInfo &info);
|
||||
Result ConvertPathToDirectoryId(RomDirectoryId *out, const RomPathChar *path);
|
||||
Result ConvertPathToFileId(RomFileId *out, const RomPathChar *path);
|
||||
|
||||
Result OpenFile(FileInfo *out, const RomPathChar *path);
|
||||
Result OpenFile(FileInfo *out, RomFileId id);
|
||||
|
||||
Result FindOpen(FindPosition *out, const RomPathChar *path);
|
||||
Result FindOpen(FindPosition *out, RomDirectoryId id);
|
||||
|
||||
Result FindNextDirectory(RomPathChar *out, FindPosition *find, size_t length);
|
||||
Result FindNextFile(RomPathChar *out, FindPosition *find, size_t length);
|
||||
|
||||
Result QueryRomFileSystemSize(s64 *out_dir_entry_size, s64 *out_file_entry_size);
|
||||
private:
|
||||
Result GetParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path);
|
||||
|
||||
Result FindParentDirectoryRecursive(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, RomPathTool::PathParser *parser, const RomPathChar *path);
|
||||
|
||||
Result FindPathRecursive(EntryKey *out_key, RomDirectoryEntry *out_dir_entry, bool is_dir, const RomPathChar *path);
|
||||
Result FindDirectoryRecursive(EntryKey *out_key, RomDirectoryEntry *out_dir_entry, const RomPathChar *path);
|
||||
Result FindFileRecursive(EntryKey *out_key, RomDirectoryEntry *out_dir_entry, const RomPathChar *path);
|
||||
|
||||
Result CheckSameEntryExists(const EntryKey &key, Result if_exists);
|
||||
|
||||
Result GetDirectoryEntry(Position *out_pos, RomDirectoryEntry *out_entry, const EntryKey &key);
|
||||
Result GetDirectoryEntry(RomDirectoryEntry *out_entry, RomDirectoryId id);
|
||||
|
||||
Result GetFileEntry(Position *out_pos, RomFileEntry *out_entry, const EntryKey &key);
|
||||
Result GetFileEntry(RomFileEntry *out_entry, RomFileId id);
|
||||
|
||||
Result OpenFile(FileInfo *out, const EntryKey &key);
|
||||
|
||||
Result FindOpen(FindPosition *out, const EntryKey &key);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/common/fs_dbm_rom_types.hpp>
|
||||
#include <stratosphere/fs/fs_substorage.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
|
||||
class KeyValueRomStorageTemplate {
|
||||
public:
|
||||
using Key = KeyType;
|
||||
using Value = ValueType;
|
||||
using Position = u32;
|
||||
using BucketIndex = s64;
|
||||
|
||||
using StorageSizeType = u32;
|
||||
|
||||
struct FindIndex {
|
||||
BucketIndex ind;
|
||||
Position pos;
|
||||
};
|
||||
static_assert(util::is_pod<FindIndex>::value);
|
||||
private:
|
||||
static constexpr inline Position InvalidPosition = ~Position();
|
||||
|
||||
struct Element {
|
||||
Key key;
|
||||
Value value;
|
||||
Position next;
|
||||
StorageSizeType size;
|
||||
};
|
||||
static_assert(util::is_pod<Element>::value);
|
||||
private:
|
||||
s64 m_bucket_count;
|
||||
SubStorage m_bucket_storage;
|
||||
SubStorage m_kv_storage;
|
||||
s64 m_total_entry_size;
|
||||
u32 m_entry_count;
|
||||
public:
|
||||
static constexpr s64 QueryBucketStorageSize(s64 num) {
|
||||
return num * sizeof(Position);
|
||||
}
|
||||
|
||||
static constexpr s64 QueryBucketCount(StorageSizeType size) {
|
||||
return size / sizeof(Position);
|
||||
}
|
||||
|
||||
static constexpr size_t QueryEntrySize(StorageSizeType aux_size) {
|
||||
return util::AlignUp<size_t>(sizeof(Element) + aux_size, alignof(Element));
|
||||
}
|
||||
|
||||
static Result Format(SubStorage bucket, StorageSizeType count) {
|
||||
const Position pos = InvalidPosition;
|
||||
for (auto i = 0u; i < count; i++) {
|
||||
R_TRY(bucket.Write(i * sizeof(pos), std::addressof(pos), sizeof(pos)));
|
||||
}
|
||||
R_SUCCEED();
|
||||
}
|
||||
public:
|
||||
constexpr KeyValueRomStorageTemplate() : m_bucket_count(), m_bucket_storage(), m_kv_storage(), m_total_entry_size(), m_entry_count() { /* ... */ }
|
||||
|
||||
Result Initialize(const SubStorage &bucket, s64 count, const SubStorage &kv) {
|
||||
AMS_ASSERT(count > 0);
|
||||
m_bucket_storage = bucket;
|
||||
m_bucket_count = count;
|
||||
m_kv_storage = kv;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
m_bucket_storage = SubStorage();
|
||||
m_bucket_count = 0;
|
||||
m_kv_storage = SubStorage();
|
||||
}
|
||||
|
||||
s64 GetTotalEntrySize() const {
|
||||
return m_total_entry_size;
|
||||
}
|
||||
protected:
|
||||
Result AddInternal(Position *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(aux != nullptr || aux_size == 0);
|
||||
AMS_ASSERT(m_bucket_count > 0);
|
||||
|
||||
{
|
||||
Position pos, prev_pos;
|
||||
Element elem;
|
||||
|
||||
const Result find_res = this->FindInternal(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size);
|
||||
R_UNLESS(R_FAILED(find_res), fs::ResultDbmAlreadyExists());
|
||||
R_UNLESS(fs::ResultDbmKeyNotFound::Includes(find_res), find_res);
|
||||
}
|
||||
|
||||
Position pos;
|
||||
R_TRY(this->AllocateEntry(std::addressof(pos), static_cast<StorageSizeType>(aux_size)));
|
||||
|
||||
Position next_pos;
|
||||
R_TRY(this->LinkEntry(std::addressof(next_pos), pos, hash_key));
|
||||
|
||||
const Element elem = { key, value, next_pos, static_cast<StorageSizeType>(aux_size) };
|
||||
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size));
|
||||
|
||||
*out = pos;
|
||||
m_entry_count++;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetInternal(Position *out_pos, Value *out_val, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_val != nullptr);
|
||||
AMS_ASSERT(aux != nullptr);
|
||||
|
||||
Position pos, prev_pos;
|
||||
Element elem;
|
||||
R_TRY(this->FindInternal(std::addressof(pos), std::addressof(prev_pos), std::addressof(elem), key, hash_key, aux, aux_size));
|
||||
|
||||
*out_pos = pos;
|
||||
*out_val = elem.value;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetByPosition(Key *out_key, Value *out_val, Position pos) {
|
||||
AMS_ASSERT(out_key != nullptr);
|
||||
AMS_ASSERT(out_val != nullptr);
|
||||
|
||||
Element elem;
|
||||
R_TRY(this->ReadKeyValue(std::addressof(elem), pos));
|
||||
|
||||
*out_key = elem.key;
|
||||
*out_val = elem.value;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetByPosition(Key *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
|
||||
AMS_ASSERT(out_key != nullptr);
|
||||
AMS_ASSERT(out_val != nullptr);
|
||||
AMS_ASSERT(out_aux != nullptr);
|
||||
AMS_ASSERT(out_aux_size != nullptr);
|
||||
|
||||
Element elem;
|
||||
R_TRY(this->ReadKeyValue(std::addressof(elem), out_aux, out_aux_size, pos));
|
||||
|
||||
*out_key = elem.key;
|
||||
*out_val = elem.value;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result SetByPosition(Position pos, const Value &value) {
|
||||
Element elem;
|
||||
R_TRY(this->ReadKeyValue(std::addressof(elem), pos));
|
||||
elem.value = value;
|
||||
R_RETURN(this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0));
|
||||
}
|
||||
private:
|
||||
BucketIndex HashToBucket(u32 hash_key) const {
|
||||
return hash_key % m_bucket_count;
|
||||
}
|
||||
|
||||
Result FindInternal(Position *out_pos, Position *out_prev, Element *out_elem, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||
AMS_ASSERT(out_pos != nullptr);
|
||||
AMS_ASSERT(out_prev != nullptr);
|
||||
AMS_ASSERT(out_elem != nullptr);
|
||||
AMS_ASSERT(aux != nullptr || aux_size == 0);
|
||||
AMS_ASSERT(m_bucket_count > 0);
|
||||
|
||||
*out_pos = 0;
|
||||
*out_prev = 0;
|
||||
|
||||
const BucketIndex ind = HashToBucket(hash_key);
|
||||
|
||||
Position cur;
|
||||
R_TRY(this->ReadBucket(std::addressof(cur), ind));
|
||||
|
||||
s64 kv_size;
|
||||
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
||||
AMS_ASSERT(cur == InvalidPosition || cur < kv_size);
|
||||
|
||||
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
||||
|
||||
auto buf = ::ams::fs::impl::MakeUnique<u8[]>(MaxAuxiliarySize);
|
||||
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||
|
||||
while (true) {
|
||||
size_t cur_aux_size;
|
||||
R_TRY(this->ReadKeyValue(out_elem, buf.get(), std::addressof(cur_aux_size), cur));
|
||||
|
||||
if (key.IsEqual(out_elem->key, aux, aux_size, buf.get(), cur_aux_size)) {
|
||||
*out_pos = cur;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
*out_prev = cur;
|
||||
cur = out_elem->next;
|
||||
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
||||
}
|
||||
}
|
||||
|
||||
Result AllocateEntry(Position *out, StorageSizeType aux_size) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
s64 kv_size;
|
||||
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
||||
const size_t end_pos = m_total_entry_size + sizeof(Element) + static_cast<size_t>(aux_size);
|
||||
R_UNLESS(end_pos <= static_cast<size_t>(kv_size), fs::ResultDbmKeyFull());
|
||||
|
||||
*out = static_cast<Position>(m_total_entry_size);
|
||||
|
||||
m_total_entry_size = util::AlignUp<s64>(static_cast<s64>(end_pos), alignof(Position));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result LinkEntry(Position *out, Position pos, u32 hash_key) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
const BucketIndex ind = HashToBucket(hash_key);
|
||||
|
||||
Position next;
|
||||
R_TRY(this->ReadBucket(std::addressof(next), ind));
|
||||
|
||||
s64 kv_size;
|
||||
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
||||
AMS_ASSERT(next == InvalidPosition || next < kv_size);
|
||||
|
||||
R_TRY(this->WriteBucket(pos, ind));
|
||||
|
||||
*out = next;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ReadBucket(Position *out, BucketIndex ind) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(ind < m_bucket_count);
|
||||
|
||||
const s64 offset = ind * sizeof(Position);
|
||||
R_RETURN(m_bucket_storage.Read(offset, out, sizeof(*out)));
|
||||
}
|
||||
|
||||
Result WriteBucket(Position pos, BucketIndex ind) {
|
||||
AMS_ASSERT(ind < m_bucket_count);
|
||||
|
||||
const s64 offset = ind * sizeof(Position);
|
||||
R_RETURN(m_bucket_storage.Write(offset, std::addressof(pos), sizeof(pos)));
|
||||
}
|
||||
|
||||
Result ReadKeyValue(Element *out, Position pos) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
s64 kv_size;
|
||||
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
||||
AMS_ASSERT(pos < kv_size);
|
||||
|
||||
R_RETURN(m_kv_storage.Read(pos, out, sizeof(*out)));
|
||||
}
|
||||
|
||||
Result ReadKeyValue(Element *out, void *out_aux, size_t *out_aux_size, Position pos) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
AMS_ASSERT(out_aux != nullptr);
|
||||
AMS_ASSERT(out_aux_size != nullptr);
|
||||
|
||||
R_TRY(this->ReadKeyValue(out, pos));
|
||||
|
||||
*out_aux_size = out->size;
|
||||
if (out->size > 0) {
|
||||
R_TRY(m_kv_storage.Read(pos + sizeof(*out), out_aux, out->size));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result WriteKeyValue(const Element *elem, Position pos, const void *aux, size_t aux_size) {
|
||||
AMS_ASSERT(elem != nullptr);
|
||||
AMS_ASSERT(aux != nullptr);
|
||||
|
||||
s64 kv_size;
|
||||
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
||||
AMS_ASSERT(pos < kv_size);
|
||||
|
||||
R_TRY(m_kv_storage.Write(pos, elem, sizeof(*elem)));
|
||||
|
||||
if (aux != nullptr && aux_size > 0) {
|
||||
R_TRY(m_kv_storage.Write(pos + sizeof(*elem), aux, aux_size));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/common/fs_dbm_rom_types.hpp>
|
||||
|
||||
namespace ams::fs::RomPathTool {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
|
||||
constexpr inline u32 MaxPathLength = 0x300;
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsSeparator(RomPathChar c) {
|
||||
return c == RomStringTraits::DirectorySeparator;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsNullTerminator(RomPathChar c) {
|
||||
return c == RomStringTraits::NullTerminator;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsDot(RomPathChar c) {
|
||||
return c == RomStringTraits::Dot;
|
||||
}
|
||||
|
||||
class RomEntryName {
|
||||
private:
|
||||
const RomPathChar *m_path;
|
||||
size_t m_length;
|
||||
public:
|
||||
constexpr RomEntryName() : m_path(nullptr), m_length(0) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
constexpr void Initialize(const RomPathChar *p, size_t len) {
|
||||
m_path = p;
|
||||
m_length = len;
|
||||
}
|
||||
|
||||
constexpr bool IsCurrentDirectory() const {
|
||||
return m_length == 1 && IsDot(m_path[0]);
|
||||
}
|
||||
|
||||
constexpr bool IsParentDirectory() const {
|
||||
return m_length == 2 && IsDot(m_path[0]) && IsDot(m_path[1]);
|
||||
}
|
||||
|
||||
constexpr bool IsRootDirectory() const {
|
||||
return m_length == 0;
|
||||
}
|
||||
|
||||
constexpr const RomPathChar *begin() const {
|
||||
return m_path;
|
||||
}
|
||||
|
||||
constexpr const RomPathChar *end() const {
|
||||
return m_path + m_length;
|
||||
}
|
||||
|
||||
constexpr size_t length() const {
|
||||
return m_length;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
|
||||
AMS_ASSERT(p != nullptr);
|
||||
return length == 1 && IsDot(p[0]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p) {
|
||||
AMS_ASSERT(p != nullptr);
|
||||
return IsDot(p[0]) && IsNullTerminator(p[1]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsParentDirectory(const RomPathChar *p) {
|
||||
AMS_ASSERT(p != nullptr);
|
||||
return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsParentDirectory(const RomPathChar *p, size_t length) {
|
||||
AMS_ASSERT(p != nullptr);
|
||||
return length == 2 && IsDot(p[0]) && IsDot(p[1]);
|
||||
}
|
||||
|
||||
constexpr inline bool IsEqualPath(const RomPathChar *lhs, const RomPathChar *rhs, size_t length) {
|
||||
AMS_ASSERT(lhs != nullptr);
|
||||
AMS_ASSERT(rhs != nullptr);
|
||||
return std::strncmp(lhs, rhs, length) == 0;
|
||||
}
|
||||
|
||||
Result GetParentDirectoryName(RomEntryName *out, const RomEntryName &cur, const RomPathChar *p);
|
||||
|
||||
class PathParser {
|
||||
private:
|
||||
const RomPathChar *m_prev_path_start;
|
||||
const RomPathChar *m_prev_path_end;
|
||||
const RomPathChar *m_next_path;
|
||||
bool m_finished;
|
||||
public:
|
||||
constexpr PathParser() : m_prev_path_start(), m_prev_path_end(), m_next_path(), m_finished() { /* ... */ }
|
||||
|
||||
Result Initialize(const RomPathChar *path);
|
||||
void Finalize();
|
||||
|
||||
bool IsParseFinished() const;
|
||||
bool IsDirectoryPath() const;
|
||||
|
||||
Result GetAsDirectoryName(RomEntryName *out) const;
|
||||
Result GetAsFileName(RomEntryName *out) const;
|
||||
|
||||
Result GetNextDirectoryName(RomEntryName *out);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
using RomPathChar = char;
|
||||
using RomFileId = u32;
|
||||
using RomDirectoryId = u32;
|
||||
|
||||
struct RomFileSystemInformation {
|
||||
s64 size;
|
||||
s64 directory_bucket_offset;
|
||||
s64 directory_bucket_size;
|
||||
s64 directory_entry_offset;
|
||||
s64 directory_entry_size;
|
||||
s64 file_bucket_offset;
|
||||
s64 file_bucket_size;
|
||||
s64 file_entry_offset;
|
||||
s64 file_entry_size;
|
||||
s64 body_offset;
|
||||
};
|
||||
static_assert(util::is_pod<RomFileSystemInformation>::value);
|
||||
static_assert(sizeof(RomFileSystemInformation) == 0x50);
|
||||
|
||||
struct RomFileInfo {
|
||||
Int64 offset;
|
||||
Int64 size;
|
||||
};
|
||||
static_assert(util::is_pod<RomFileInfo>::value);
|
||||
|
||||
namespace RomStringTraits {
|
||||
|
||||
constexpr inline char DirectorySeparator = '/';
|
||||
constexpr inline char NullTerminator = '\x00';
|
||||
constexpr inline char Dot = '.';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_path.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
class DirectoryPathParser {
|
||||
NON_COPYABLE(DirectoryPathParser);
|
||||
NON_MOVEABLE(DirectoryPathParser);
|
||||
private:
|
||||
char *m_buffer;
|
||||
char m_replaced_char;
|
||||
s32 m_position;
|
||||
fs::Path m_current_path;
|
||||
public:
|
||||
DirectoryPathParser() : m_buffer(nullptr), m_replaced_char(StringTraits::NullTerminator), m_position(0), m_current_path() { /* ... */ }
|
||||
|
||||
const fs::Path &GetCurrentPath() const {
|
||||
return m_current_path;
|
||||
}
|
||||
|
||||
Result Initialize(fs::Path *path) {
|
||||
/* Declare a default buffer, in case the path has no write buffer. */
|
||||
static constinit char EmptyBuffer[1] = "";
|
||||
|
||||
/* Get a usable buffer. */
|
||||
char *buf = path->GetWriteBufferLength() > 0 ? path->GetWriteBuffer() : EmptyBuffer;
|
||||
|
||||
/* Get the windows skip length. */
|
||||
const auto windows_skip_len = fs::GetWindowsSkipLength(buf);
|
||||
|
||||
/* Set our buffer. */
|
||||
m_buffer = buf + windows_skip_len;
|
||||
|
||||
/* Set up our initial state. */
|
||||
if (windows_skip_len) {
|
||||
R_TRY(m_current_path.InitializeWithNormalization(buf, windows_skip_len + 1));
|
||||
} else {
|
||||
if (char * const first = this->ReadNextImpl(); first != nullptr) {
|
||||
R_TRY(m_current_path.InitializeWithNormalization(first));
|
||||
}
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ReadNext(bool *out_finished) {
|
||||
/* Default to not finished. */
|
||||
*out_finished = false;
|
||||
|
||||
/* Get the next child component. */
|
||||
if (auto * const child = this->ReadNextImpl(); child != nullptr) {
|
||||
/* Append the child component to our current path. */
|
||||
R_TRY(m_current_path.AppendChild(child));
|
||||
} else {
|
||||
/* We have no child component, so we're finished. */
|
||||
*out_finished = true;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
private:
|
||||
char *ReadNextImpl() {
|
||||
/* Check that we have characters to read. */
|
||||
if (m_position < 0 || m_buffer[0] == StringTraits::NullTerminator) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* If we have a replaced character, restore it. */
|
||||
if (m_replaced_char != StringTraits::NullTerminator) {
|
||||
m_buffer[m_position] = m_replaced_char;
|
||||
if (m_replaced_char == StringTraits::DirectorySeparator) {
|
||||
++m_position;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're at the start of a root-relative path, begin by returning the root. */
|
||||
if (m_position == 0 && m_buffer[0] == StringTraits::DirectorySeparator) {
|
||||
m_replaced_char = m_buffer[1];
|
||||
m_buffer[1] = StringTraits::NullTerminator;
|
||||
m_position = 1;
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
/* Otherwise, find the end of the next path component. */
|
||||
s32 i;
|
||||
for (i = m_position; m_buffer[i] != StringTraits::DirectorySeparator; ++i) {
|
||||
if (m_buffer[i] == StringTraits::NullTerminator) {
|
||||
char * const ret = (i != m_position) ? m_buffer + m_position : nullptr;
|
||||
m_position = -1;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check that we're not ending on a separator. */
|
||||
AMS_ASSERT(m_buffer[i + 1] != StringTraits::NullTerminator);
|
||||
|
||||
char * const ret = m_buffer + m_position;
|
||||
|
||||
m_replaced_char = StringTraits::DirectorySeparator;
|
||||
m_buffer[i] = 0;
|
||||
m_position = i;
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_istorage.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class FileStorage : public IStorage, public impl::Newable {
|
||||
NON_COPYABLE(FileStorage);
|
||||
NON_MOVEABLE(FileStorage);
|
||||
private:
|
||||
static constexpr s64 InvalidSize = -1;
|
||||
private:
|
||||
std::unique_ptr<fsa::IFile> m_unique_file;
|
||||
std::shared_ptr<fsa::IFile> m_shared_file;
|
||||
fsa::IFile *m_base_file;
|
||||
s64 m_size;
|
||||
public:
|
||||
FileStorage(fsa::IFile *f) : m_unique_file(f), m_size(InvalidSize) {
|
||||
m_base_file = m_unique_file.get();
|
||||
}
|
||||
|
||||
FileStorage(std::unique_ptr<fsa::IFile> f) : m_unique_file(std::move(f)), m_size(InvalidSize) {
|
||||
m_base_file = m_unique_file.get();
|
||||
}
|
||||
|
||||
FileStorage(std::shared_ptr<fsa::IFile> f) : m_shared_file(f), m_size(InvalidSize) {
|
||||
m_base_file = m_shared_file.get();
|
||||
}
|
||||
|
||||
virtual ~FileStorage() { /* ... */ }
|
||||
private:
|
||||
Result UpdateSize();
|
||||
protected:
|
||||
constexpr FileStorage() : m_unique_file(), m_shared_file(), m_base_file(nullptr), m_size(InvalidSize) { /* ... */ }
|
||||
|
||||
void SetFile(fs::fsa::IFile *file) {
|
||||
AMS_ASSERT(file != nullptr);
|
||||
AMS_ASSERT(m_base_file == nullptr);
|
||||
m_base_file = file;
|
||||
}
|
||||
|
||||
void SetFile(std::unique_ptr<fs::fsa::IFile> &&file) {
|
||||
AMS_ASSERT(file != nullptr);
|
||||
AMS_ASSERT(m_base_file == nullptr);
|
||||
AMS_ASSERT(m_unique_file == nullptr);
|
||||
|
||||
m_unique_file = std::move(file);
|
||||
m_base_file = m_unique_file.get();
|
||||
}
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override;
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
|
||||
virtual Result Flush() override;
|
||||
virtual Result GetSize(s64 *out_size) override;
|
||||
virtual Result SetSize(s64 size) override;
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
|
||||
};
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class FileStorageBasedFileSystem : public FileStorage {
|
||||
NON_COPYABLE(FileStorageBasedFileSystem);
|
||||
NON_MOVEABLE(FileStorageBasedFileSystem);
|
||||
private:
|
||||
std::shared_ptr<fs::fsa::IFileSystem> m_base_file_system;
|
||||
public:
|
||||
constexpr FileStorageBasedFileSystem() : FileStorage(), m_base_file_system(nullptr) { /* ... */ }
|
||||
|
||||
Result Initialize(std::shared_ptr<fs::fsa::IFileSystem> base_file_system, const fs::Path &path, fs::OpenMode mode);
|
||||
};
|
||||
|
||||
class FileHandleStorage : public IStorage, public impl::Newable {
|
||||
private:
|
||||
static constexpr s64 InvalidSize = -1;
|
||||
private:
|
||||
FileHandle m_handle;
|
||||
bool m_close_file;
|
||||
s64 m_size;
|
||||
os::SdkMutex m_mutex;
|
||||
public:
|
||||
constexpr explicit FileHandleStorage(FileHandle handle, bool close_file) : m_handle(handle), m_close_file(close_file), m_size(InvalidSize), m_mutex() { /* ... */ }
|
||||
constexpr explicit FileHandleStorage(FileHandle handle) : FileHandleStorage(handle, false) { /* ... */ }
|
||||
|
||||
virtual ~FileHandleStorage() override {
|
||||
if (m_close_file) {
|
||||
CloseFile(m_handle);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
Result UpdateSize();
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override;
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
|
||||
virtual Result Flush() override;
|
||||
virtual Result GetSize(s64 *out_size) override;
|
||||
virtual Result SetSize(s64 size) override;
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
enum AccessLogMode : u32 {
|
||||
AccessLogMode_None = 0,
|
||||
AccessLogMode_Log = 1,
|
||||
AccessLogMode_SdCard = 2,
|
||||
};
|
||||
|
||||
Result GetGlobalAccessLogMode(u32 *out);
|
||||
Result SetGlobalAccessLogMode(u32 mode);
|
||||
|
||||
void SetLocalAccessLog(bool enabled);
|
||||
void SetLocalSystemAccessLogForDebug(bool enabled);
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
void InitializeForSystem();
|
||||
void InitializeWithMultiSessionForSystem();
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
Result MountApplicationPackage(const char *name, const char *common_path);
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_istorage.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
enum class BisPartitionId {
|
||||
/* Boot0 */
|
||||
BootPartition1Root = 0,
|
||||
|
||||
/* Boot1 */
|
||||
BootPartition2Root = 10,
|
||||
|
||||
/* Non-Boot */
|
||||
UserDataRoot = 20,
|
||||
BootConfigAndPackage2Part1 = 21,
|
||||
BootConfigAndPackage2Part2 = 22,
|
||||
BootConfigAndPackage2Part3 = 23,
|
||||
BootConfigAndPackage2Part4 = 24,
|
||||
BootConfigAndPackage2Part5 = 25,
|
||||
BootConfigAndPackage2Part6 = 26,
|
||||
CalibrationBinary = 27,
|
||||
CalibrationFile = 28,
|
||||
SafeMode = 29,
|
||||
User = 30,
|
||||
System = 31,
|
||||
SystemProperEncryption = 32,
|
||||
SystemProperPartition = 33,
|
||||
SignedSystemPartitionOnSafeMode = 34,
|
||||
DeviceTreeBlob = 35,
|
||||
System0 = 36,
|
||||
};
|
||||
|
||||
const char *GetBisMountName(BisPartitionId id);
|
||||
|
||||
Result MountBis(BisPartitionId id, const char *root_path);
|
||||
Result MountBis(const char *name, BisPartitionId id);
|
||||
|
||||
void SetBisRootForHost(BisPartitionId id, const char *root_path);
|
||||
|
||||
Result OpenBisPartition(std::unique_ptr<fs::IStorage> *out, BisPartitionId id);
|
||||
|
||||
Result InvalidateBisCache();
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
#include <stratosphere/fs/fs_code_verification_data.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 16.2.0.0 */
|
||||
Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id);
|
||||
|
||||
Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific);
|
||||
Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id);
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/sf/sf_buffer_tags.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
struct CodeVerificationData : public ams::sf::LargeData {
|
||||
u8 signature[crypto::Rsa2048PssSha256Verifier::SignatureSize];
|
||||
u8 target_hash[crypto::Rsa2048PssSha256Verifier::HashSize];
|
||||
bool has_data;
|
||||
u8 reserved[3];
|
||||
};
|
||||
static_assert(sizeof(CodeVerificationData) == crypto::Rsa2048PssSha256Verifier::SignatureSize + crypto::Rsa2048PssSha256Verifier::HashSize + 4);
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/os.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
#include <stratosphere/sf.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct Int64 {
|
||||
u32 low;
|
||||
u32 high;
|
||||
|
||||
constexpr ALWAYS_INLINE void Set(s64 v) {
|
||||
this->low = static_cast<u32>((v & static_cast<u64>(0x00000000FFFFFFFFul)) >> 0);
|
||||
this->high = static_cast<u32>((v & static_cast<u64>(0xFFFFFFFF00000000ul)) >> 32);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE s64 Get() const {
|
||||
return (static_cast<s64>(this->high) << 32) | (static_cast<s64>(this->low));
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE Int64 &operator=(s64 v) {
|
||||
this->Set(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE operator s64() const {
|
||||
return this->Get();
|
||||
}
|
||||
};
|
||||
static_assert(util::is_pod<Int64>::value);
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum ContentType {
|
||||
ContentType_Meta = 0,
|
||||
ContentType_Control = 1,
|
||||
ContentType_Manual = 2,
|
||||
ContentType_Logo = 3,
|
||||
ContentType_Data = 4,
|
||||
};
|
||||
|
||||
Result MountContent(const char *name, const char *path, fs::ContentAttributes attr, ContentType content_type);
|
||||
Result MountContent(const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId id, ContentType content_type);
|
||||
Result MountContent(const char *name, const char *path, fs::ContentAttributes attr, ncm::DataId id, ContentType content_type);
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum ContentAttributes : u8 {
|
||||
ContentAttributes_None = 0x0,
|
||||
ContentAttributes_All = 0xF,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_content_storage_id.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
constexpr inline const char * const ContentStorageDirectoryName = "Contents";
|
||||
|
||||
const char *GetContentStorageMountName(ContentStorageId id);
|
||||
|
||||
Result MountContentStorage(ContentStorageId id);
|
||||
Result MountContentStorage(const char *name, ContentStorageId id);
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 16.2.0.0 */
|
||||
enum class ContentStorageId : u32 {
|
||||
System = 0,
|
||||
User = 1,
|
||||
SdCard = 2,
|
||||
System0 = 3,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
enum class AbortSpecifier {
|
||||
Default,
|
||||
Abort,
|
||||
Return,
|
||||
};
|
||||
|
||||
using ResultHandler = AbortSpecifier (*)(Result);
|
||||
|
||||
class FsContext {
|
||||
private:
|
||||
ResultHandler m_handler;
|
||||
public:
|
||||
constexpr explicit FsContext(ResultHandler h) : m_handler(h) { /* ... */ }
|
||||
|
||||
constexpr void SetHandler(ResultHandler h) { m_handler = h; }
|
||||
|
||||
constexpr AbortSpecifier HandleResult(Result result) const { return m_handler(result); }
|
||||
};
|
||||
|
||||
void SetDefaultFsContextResultHandler(const ResultHandler handler);
|
||||
|
||||
const FsContext *GetCurrentThreadFsContext();
|
||||
void SetCurrentThreadFsContext(const FsContext *context);
|
||||
|
||||
class ScopedFsContext {
|
||||
private:
|
||||
const FsContext * const m_prev_context;
|
||||
public:
|
||||
ALWAYS_INLINE ScopedFsContext(const FsContext &ctx) : m_prev_context(GetCurrentThreadFsContext()) {
|
||||
SetCurrentThreadFsContext(std::addressof(ctx));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ~ScopedFsContext() {
|
||||
SetCurrentThreadFsContext(m_prev_context);
|
||||
}
|
||||
};
|
||||
|
||||
class ScopedAutoAbortDisabler {
|
||||
private:
|
||||
const FsContext * const m_prev_context;
|
||||
public:
|
||||
ScopedAutoAbortDisabler();
|
||||
ALWAYS_INLINE ~ScopedAutoAbortDisabler() {
|
||||
SetCurrentThreadFsContext(m_prev_context);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_save_data_types.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result MountDeviceSaveData(const char *name);
|
||||
Result MountDeviceSaveData(const char *name, const ncm::ApplicationId application_id);
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
constexpr inline size_t EntryNameLengthMax = 0x300;
|
||||
|
||||
struct DirectoryEntry {
|
||||
char name[EntryNameLengthMax + 1];
|
||||
char pad[3];
|
||||
s8 type;
|
||||
u8 pad2[3];
|
||||
s64 file_size;
|
||||
};
|
||||
|
||||
struct DirectoryHandle {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries);
|
||||
Result GetDirectoryEntryCount(s64 *out, DirectoryHandle handle);
|
||||
void CloseDirectory(DirectoryHandle handle);
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fat/fat_file_system.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
struct StorageErrorInfo {
|
||||
u32 num_activation_failures;
|
||||
u32 num_activation_error_corrections;
|
||||
u32 num_read_write_failures;
|
||||
u32 num_read_write_error_corrections;
|
||||
};
|
||||
static_assert(sizeof(StorageErrorInfo) == 0x10);
|
||||
static_assert(util::is_pod<StorageErrorInfo>::value);
|
||||
|
||||
struct FileSystemProxyErrorInfo {
|
||||
u32 rom_fs_remount_for_data_corruption_count;
|
||||
u32 rom_fs_unrecoverable_data_corruption_by_remount_count;
|
||||
fat::FatError fat_fs_error;
|
||||
u32 rom_fs_recovered_by_invalidate_cache_count;
|
||||
u32 save_data_index_count;
|
||||
fat::FatReportInfo1 bis_system_fat_report_info_1;
|
||||
fat::FatReportInfo1 bis_user_fat_report_info_1;
|
||||
fat::FatReportInfo1 sd_card_fat_report_info_1;
|
||||
fat::FatReportInfo2 bis_system_fat_report_info_2;
|
||||
fat::FatReportInfo2 bis_user_fat_report_info_2;
|
||||
fat::FatReportInfo2 sd_card_fat_report_info_2;
|
||||
u32 rom_fs_deep_retry_start_count;
|
||||
u32 rom_fs_unrecoverable_by_game_card_access_failed_count;
|
||||
fat::FatSafeInfo bis_system_fat_safe_info;
|
||||
fat::FatSafeInfo bis_user_fat_safe_info;
|
||||
|
||||
u8 reserved[0x18];
|
||||
};
|
||||
static_assert(sizeof(FileSystemProxyErrorInfo) == 0x80);
|
||||
static_assert(util::is_pod<FileSystemProxyErrorInfo>::value);
|
||||
|
||||
Result GetAndClearMmcErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size);
|
||||
Result GetAndClearSdCardErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size);
|
||||
|
||||
Result GetAndClearFileSystemProxyErrorInfo(FileSystemProxyErrorInfo *out);
|
||||
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
struct ReadOption {
|
||||
u32 _value;
|
||||
|
||||
static const ReadOption None;
|
||||
};
|
||||
|
||||
enum ReadOptionFlag : u32 {
|
||||
ReadOptionFlag_None = (0 << 0),
|
||||
};
|
||||
|
||||
inline constexpr const ReadOption ReadOption::None = {ReadOptionFlag_None};
|
||||
|
||||
inline constexpr bool operator==(const ReadOption &lhs, const ReadOption &rhs) {
|
||||
return lhs._value == rhs._value;
|
||||
}
|
||||
|
||||
inline constexpr bool operator!=(const ReadOption &lhs, const ReadOption &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
static_assert(util::is_pod<ReadOption>::value && sizeof(ReadOption) == sizeof(u32));
|
||||
|
||||
enum WriteOptionFlag : u32 {
|
||||
WriteOptionFlag_None = (0 << 0),
|
||||
WriteOptionFlag_Flush = (1 << 0),
|
||||
};
|
||||
|
||||
struct WriteOption {
|
||||
u32 _value;
|
||||
|
||||
constexpr inline bool HasFlushFlag() const {
|
||||
return _value & WriteOptionFlag_Flush;
|
||||
}
|
||||
|
||||
static const WriteOption None;
|
||||
static const WriteOption Flush;
|
||||
};
|
||||
|
||||
inline constexpr const WriteOption WriteOption::None = {WriteOptionFlag_None};
|
||||
inline constexpr const WriteOption WriteOption::Flush = {WriteOptionFlag_Flush};
|
||||
|
||||
inline constexpr bool operator==(const WriteOption &lhs, const WriteOption &rhs) {
|
||||
return lhs._value == rhs._value;
|
||||
}
|
||||
|
||||
inline constexpr bool operator!=(const WriteOption &lhs, const WriteOption &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
static_assert(util::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32));
|
||||
|
||||
struct FileHandle {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option);
|
||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size);
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option);
|
||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size);
|
||||
Result GetFileSize(s64 *out, FileHandle handle);
|
||||
Result FlushFile(FileHandle handle);
|
||||
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option);
|
||||
Result SetFileSize(FileHandle handle, s64 size);
|
||||
int GetFileOpenMode(FileHandle handle);
|
||||
void CloseFile(FileHandle handle);
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
namespace fsa {
|
||||
|
||||
class IFileSystem;
|
||||
|
||||
}
|
||||
|
||||
enum OpenMode {
|
||||
OpenMode_Read = (1 << 0),
|
||||
OpenMode_Write = (1 << 1),
|
||||
OpenMode_AllowAppend = (1 << 2),
|
||||
|
||||
OpenMode_ReadWrite = (OpenMode_Read | OpenMode_Write),
|
||||
OpenMode_All = (OpenMode_ReadWrite | OpenMode_AllowAppend),
|
||||
};
|
||||
|
||||
enum OpenDirectoryMode {
|
||||
OpenDirectoryMode_Directory = (1 << 0),
|
||||
OpenDirectoryMode_File = (1 << 1),
|
||||
|
||||
OpenDirectoryMode_All = (OpenDirectoryMode_Directory | OpenDirectoryMode_File),
|
||||
|
||||
/* TODO: Separate enum, like N? */
|
||||
OpenDirectoryMode_NotRequireFileSize = (1 << 31),
|
||||
};
|
||||
|
||||
enum DirectoryEntryType {
|
||||
DirectoryEntryType_Directory = 0,
|
||||
DirectoryEntryType_File = 1,
|
||||
};
|
||||
|
||||
enum CreateOption {
|
||||
CreateOption_None = (0 << 0),
|
||||
CreateOption_BigFile = (1 << 0),
|
||||
};
|
||||
|
||||
struct FileHandle;
|
||||
struct DirectoryHandle;
|
||||
|
||||
Result CreateFile(const char *path, s64 size);
|
||||
Result CreateFile(const char* path, s64 size, int option);
|
||||
Result DeleteFile(const char *path);
|
||||
Result CreateDirectory(const char *path);
|
||||
Result DeleteDirectory(const char *path);
|
||||
Result DeleteDirectoryRecursively(const char *path);
|
||||
Result RenameFile(const char *old_path, const char *new_path);
|
||||
Result RenameDirectory(const char *old_path, const char *new_path);
|
||||
Result GetEntryType(DirectoryEntryType *out, const char *path);
|
||||
Result OpenFile(FileHandle *out_file, const char *path, int mode);
|
||||
Result OpenDirectory(DirectoryHandle *out_dir, const char *path, int mode);
|
||||
Result CleanDirectoryRecursively(const char *path);
|
||||
Result GetFreeSpaceSize(s64 *out, const char *path);
|
||||
Result GetTotalSpaceSize(s64 *out, const char *path);
|
||||
|
||||
Result SetConcatenationFileAttribute(const char *path);
|
||||
|
||||
Result OpenFile(FileHandle *out, std::unique_ptr<fsa::IFile> &&file, int mode);
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_filesystem.hpp>
|
||||
#include <stratosphere/time/time_posix_time.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct FileTimeStamp {
|
||||
time::PosixTime create;
|
||||
time::PosixTime modify;
|
||||
time::PosixTime access;
|
||||
bool is_local_time;
|
||||
char pad[7];
|
||||
};
|
||||
static_assert(util::is_pod<FileTimeStamp>::value && sizeof(FileTimeStamp) == 0x20);
|
||||
|
||||
struct FileTimeStampRaw {
|
||||
s64 create;
|
||||
s64 modify;
|
||||
s64 access;
|
||||
bool is_local_time;
|
||||
char pad[7];
|
||||
};
|
||||
static_assert(util::is_pod<FileTimeStampRaw>::value && sizeof(FileTimeStampRaw) == 0x20);
|
||||
|
||||
static_assert(__builtin_offsetof(FileTimeStampRaw, create) == __builtin_offsetof(FileTimeStampRaw, create));
|
||||
static_assert(__builtin_offsetof(FileTimeStampRaw, modify) == __builtin_offsetof(FileTimeStampRaw, modify));
|
||||
static_assert(__builtin_offsetof(FileTimeStampRaw, access) == __builtin_offsetof(FileTimeStampRaw, access));
|
||||
static_assert(__builtin_offsetof(FileTimeStampRaw, is_local_time) == __builtin_offsetof(FileTimeStampRaw, is_local_time));
|
||||
static_assert(__builtin_offsetof(FileTimeStampRaw, pad) == __builtin_offsetof(FileTimeStampRaw, pad));
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
static_assert(sizeof(FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
|
||||
#endif
|
||||
|
||||
namespace impl {
|
||||
|
||||
Result GetFileTimeStampRawForDebug(FileTimeStampRaw *out, const char *path);
|
||||
|
||||
}
|
||||
|
||||
Result GetFileTimeStamp(FileTimeStamp *out, const char *path);
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_filesystem.hpp>
|
||||
#include <stratosphere/fs/fs_filesystem_for_debug.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* Common utilities. */
|
||||
Result EnsureDirectory(const char *path);
|
||||
Result EnsureParentDirectory(const char *path);
|
||||
|
||||
Result HasFile(bool *out, const char *path);
|
||||
Result HasDirectory(bool *out, const char *path);
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
constexpr inline size_t GameCardCidSize = 0x10;
|
||||
constexpr inline size_t GameCardDeviceIdSize = 0x10;
|
||||
|
||||
enum class GameCardPartition {
|
||||
Update = 0,
|
||||
Normal = 1,
|
||||
Secure = 2,
|
||||
Logo = 3,
|
||||
};
|
||||
|
||||
enum class GameCardPartitionRaw {
|
||||
NormalReadable,
|
||||
SecureReadable,
|
||||
RootWriteable,
|
||||
};
|
||||
|
||||
enum GameCardAttribute : u8 {
|
||||
GameCardAttribute_AutoBootFlag = (1 << 0),
|
||||
GameCardAttribute_HistoryEraseFlag = (1 << 1),
|
||||
GameCardAttribute_RepairToolFlag = (1 << 2),
|
||||
GameCardAttribute_DifferentRegionCupToTerraDeviceFlag = (1 << 3),
|
||||
GameCardAttribute_DifferentRegionCupToGlobalDeviceFlag = (1 << 4),
|
||||
|
||||
GameCardAttribute_HasCa10CertificateFlag = (1 << 7),
|
||||
};
|
||||
|
||||
enum class GameCardCompatibilityType : u8 {
|
||||
Normal = 0,
|
||||
Terra = 1,
|
||||
};
|
||||
|
||||
struct GameCardErrorReportInfo {
|
||||
u16 game_card_crc_error_num;
|
||||
u16 reserved1;
|
||||
u16 asic_crc_error_num;
|
||||
u16 reserved2;
|
||||
u16 refresh_num;
|
||||
u16 reserved3;
|
||||
u16 retry_limit_out_num;
|
||||
u16 timeout_retry_num;
|
||||
u16 asic_reinitialize_failure_detail;
|
||||
u16 insertion_count;
|
||||
u16 removal_count;
|
||||
u16 asic_reinitialize_num;
|
||||
u32 initialize_count;
|
||||
u16 asic_reinitialize_failure_num;
|
||||
u16 awaken_failure_num;
|
||||
u16 reserved4;
|
||||
u16 refresh_succeeded_count;
|
||||
u32 last_read_error_page_address;
|
||||
u32 last_read_error_page_count;
|
||||
u32 awaken_count;
|
||||
u32 read_count_from_insert;
|
||||
u32 read_count_from_awaken;
|
||||
u8 reserved5[8];
|
||||
};
|
||||
static_assert(util::is_pod<GameCardErrorReportInfo>::value);
|
||||
static_assert(sizeof(GameCardErrorReportInfo) == 0x40);
|
||||
|
||||
using GameCardHandle = u32;
|
||||
|
||||
Result GetGameCardHandle(GameCardHandle *out);
|
||||
Result MountGameCardPartition(const char *name, GameCardHandle handle, GameCardPartition partition);
|
||||
|
||||
Result GetGameCardCid(void *dst, size_t size);
|
||||
Result GetGameCardDeviceId(void *dst, size_t size);
|
||||
|
||||
Result GetGameCardErrorReportInfo(GameCardErrorReportInfo *out);
|
||||
|
||||
bool IsGameCardInserted();
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
#include <stratosphere/fs/fs_code_verification_data.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum MountHostOptionFlag : u32 {
|
||||
MountHostOptionFlag_None = (0 << 0),
|
||||
MountHostOptionFlag_PseudoCaseSensitive = (1 << 0),
|
||||
};
|
||||
|
||||
struct MountHostOption {
|
||||
u32 _value;
|
||||
|
||||
constexpr inline bool HasPseudoCaseSensitiveFlag() const {
|
||||
return _value & MountHostOptionFlag_PseudoCaseSensitive;
|
||||
}
|
||||
|
||||
static const MountHostOption None;
|
||||
static const MountHostOption PseudoCaseSensitive;
|
||||
};
|
||||
|
||||
inline constexpr const MountHostOption MountHostOption::None = {MountHostOptionFlag_None};
|
||||
inline constexpr const MountHostOption MountHostOption::PseudoCaseSensitive = {MountHostOptionFlag_PseudoCaseSensitive};
|
||||
|
||||
inline constexpr bool operator==(const MountHostOption &lhs, const MountHostOption &rhs) {
|
||||
return lhs._value == rhs._value;
|
||||
}
|
||||
|
||||
inline constexpr bool operator!=(const MountHostOption &lhs, const MountHostOption &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
Result MountHost(const char *name, const char *root_path);
|
||||
Result MountHost(const char *name, const char *root_path, const MountHostOption &option);
|
||||
|
||||
Result MountHostRoot();
|
||||
Result MountHostRoot(const MountHostOption &option);
|
||||
|
||||
void UnmountHostRoot();
|
||||
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class IBufferManager {
|
||||
public:
|
||||
class BufferAttribute {
|
||||
private:
|
||||
s32 m_level;
|
||||
public:
|
||||
constexpr BufferAttribute() : m_level(0) { /* ... */ }
|
||||
constexpr explicit BufferAttribute(s32 l) : m_level(l) { /* ... */ }
|
||||
|
||||
constexpr s32 GetLevel() const { return m_level; }
|
||||
};
|
||||
|
||||
using CacheHandle = u64;
|
||||
|
||||
static constexpr s32 BufferLevelMin = 0;
|
||||
|
||||
using MemoryRange = std::pair<uintptr_t, size_t>;
|
||||
|
||||
static constexpr ALWAYS_INLINE MemoryRange MakeMemoryRange(uintptr_t address, size_t size) { return MemoryRange(address, size); }
|
||||
public:
|
||||
virtual ~IBufferManager() { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE const MemoryRange AllocateBuffer(size_t size, const BufferAttribute &attr) {
|
||||
return this->DoAllocateBuffer(size, attr);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE const MemoryRange AllocateBuffer(size_t size) {
|
||||
return this->DoAllocateBuffer(size, BufferAttribute());
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void DeallocateBuffer(uintptr_t address, size_t size) {
|
||||
return this->DoDeallocateBuffer(address, size);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void DeallocateBuffer(const MemoryRange &memory_range) {
|
||||
return this->DoDeallocateBuffer(memory_range.first, memory_range.second);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE CacheHandle RegisterCache(uintptr_t address, size_t size, const BufferAttribute &attr) {
|
||||
return this->DoRegisterCache(address, size, attr);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE CacheHandle RegisterCache(const MemoryRange &memory_range, const BufferAttribute &attr) {
|
||||
return this->DoRegisterCache(memory_range.first, memory_range.second, attr);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE const std::pair<uintptr_t, size_t> AcquireCache(CacheHandle handle) {
|
||||
return this->DoAcquireCache(handle);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetTotalSize() const {
|
||||
return this->DoGetTotalSize();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetFreeSize() const {
|
||||
return this->DoGetFreeSize();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetTotalAllocatableSize() const {
|
||||
return this->DoGetTotalAllocatableSize();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetFreeSizePeak() const {
|
||||
return this->DoGetFreeSizePeak();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetTotalAllocatableSizePeak() const {
|
||||
return this->DoGetTotalAllocatableSizePeak();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE size_t GetRetriedCount() const {
|
||||
return this->DoGetRetriedCount();
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void ClearPeak() {
|
||||
return this->DoClearPeak();
|
||||
}
|
||||
protected:
|
||||
virtual const MemoryRange DoAllocateBuffer(size_t size, const BufferAttribute &attr) = 0;
|
||||
|
||||
virtual void DoDeallocateBuffer(uintptr_t address, size_t size) = 0;
|
||||
|
||||
virtual CacheHandle DoRegisterCache(uintptr_t address, size_t size, const BufferAttribute &attr) = 0;
|
||||
|
||||
virtual const MemoryRange DoAcquireCache(CacheHandle handle) = 0;
|
||||
|
||||
virtual size_t DoGetTotalSize() const = 0;
|
||||
|
||||
virtual size_t DoGetFreeSize() const = 0;
|
||||
|
||||
virtual size_t DoGetTotalAllocatableSize() const = 0;
|
||||
|
||||
virtual size_t DoGetFreeSizePeak() const = 0;
|
||||
|
||||
virtual size_t DoGetTotalAllocatableSizePeak() const = 0;
|
||||
|
||||
virtual size_t DoGetRetriedCount() const = 0;
|
||||
|
||||
virtual void DoClearPeak() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class IEventNotifier {
|
||||
public:
|
||||
virtual ~IEventNotifier() { /* ... */ }
|
||||
|
||||
Result BindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
R_RETURN(this->DoBindEvent(out, clear_mode));
|
||||
}
|
||||
private:
|
||||
virtual Result DoBindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class ImageDirectoryId {
|
||||
Nand = 0,
|
||||
SdCard = 1,
|
||||
};
|
||||
|
||||
Result MountImageDirectory(const char *name, ImageDirectoryId id);
|
||||
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_file.hpp>
|
||||
#include <stratosphere/fs/fs_operate_range.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||
class IStorage {
|
||||
public:
|
||||
virtual ~IStorage() { /* ... */ }
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) = 0;
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) = 0;
|
||||
|
||||
virtual Result Flush() = 0;
|
||||
|
||||
virtual Result SetSize(s64 size) = 0;
|
||||
|
||||
virtual Result GetSize(s64 *out) = 0;
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) = 0;
|
||||
|
||||
virtual Result OperateRange(OperationId op_id, s64 offset, s64 size) {
|
||||
R_RETURN(this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0));
|
||||
}
|
||||
public:
|
||||
static inline Result CheckAccessRange(s64 offset, s64 size, s64 total_size) {
|
||||
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
||||
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
||||
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
|
||||
R_UNLESS(offset + size <= total_size, fs::ResultOutOfRange());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE Result CheckAccessRange(s64 offset, size_t size, s64 total_size) {
|
||||
R_RETURN(CheckAccessRange(offset, static_cast<s64>(size), total_size));
|
||||
}
|
||||
|
||||
static inline Result CheckOffsetAndSize(s64 offset, s64 size) {
|
||||
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
||||
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
||||
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE Result CheckOffsetAndSize(s64 offset, size_t size) {
|
||||
R_RETURN(CheckOffsetAndSize(offset, static_cast<s64>(size)));
|
||||
}
|
||||
|
||||
static inline Result CheckOffsetAndSizeWithResult(s64 offset, s64 size, Result fail_result) {
|
||||
R_TRY_CATCH(CheckOffsetAndSize(offset, size)) {
|
||||
R_CONVERT_ALL(fail_result);
|
||||
} R_END_TRY_CATCH;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE Result CheckOffsetAndSizeWithResult(s64 offset, size_t size, Result fail_result) {
|
||||
R_RETURN(CheckOffsetAndSizeWithResult(offset, static_cast<s64>(size), fail_result));
|
||||
}
|
||||
};
|
||||
|
||||
class ReadOnlyStorageAdapter : public IStorage {
|
||||
private:
|
||||
std::shared_ptr<IStorage> m_shared_storage;
|
||||
std::unique_ptr<IStorage> m_unique_storage;
|
||||
IStorage *m_storage;
|
||||
public:
|
||||
explicit ReadOnlyStorageAdapter(IStorage *s) : m_unique_storage(s) {
|
||||
m_storage = m_unique_storage.get();
|
||||
}
|
||||
explicit ReadOnlyStorageAdapter(std::shared_ptr<IStorage> s) : m_shared_storage(s) {
|
||||
m_storage = m_shared_storage.get();
|
||||
}
|
||||
explicit ReadOnlyStorageAdapter(std::unique_ptr<IStorage> s) : m_unique_storage(std::move(s)) {
|
||||
m_storage = m_unique_storage.get();
|
||||
}
|
||||
|
||||
virtual ~ReadOnlyStorageAdapter() { /* ... */ }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
R_RETURN(m_storage->Read(offset, buffer, size));
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_RETURN(m_storage->Flush());
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
R_RETURN(m_storage->GetSize(out));
|
||||
}
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||
R_RETURN(m_storage->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
/* TODO: Better result? Is it possible to get a more specific one? */
|
||||
AMS_UNUSED(offset, buffer, size);
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
/* TODO: Better result? Is it possible to get a more specific one? */
|
||||
AMS_UNUSED(size);
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept PointerToStorage = ::ams::util::RawOrSmartPointerTo<T, ::ams::fs::IStorage>;
|
||||
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
using AllocateFunction = void *(*)(size_t);
|
||||
using DeallocateFunction = void (*)(void *, size_t);
|
||||
|
||||
void SetAllocator(AllocateFunction allocator, DeallocateFunction deallocator);
|
||||
|
||||
namespace impl {
|
||||
|
||||
class Newable;
|
||||
|
||||
void *Allocate(size_t size);
|
||||
void Deallocate(void *ptr, size_t size);
|
||||
|
||||
void LockAllocatorMutex();
|
||||
void UnlockAllocatorMutex();
|
||||
|
||||
void *AllocateUnsafe(size_t size);
|
||||
void DeallocateUnsafe(void *ptr, size_t size);
|
||||
|
||||
class AllocatorImpl {
|
||||
public:
|
||||
static ALWAYS_INLINE void *Allocate(size_t size) { return ::ams::fs::impl::Allocate(size); }
|
||||
static ALWAYS_INLINE void *AllocateUnsafe(size_t size) { return ::ams::fs::impl::AllocateUnsafe(size); }
|
||||
|
||||
static ALWAYS_INLINE void Deallocate(void *ptr, size_t size) { return ::ams::fs::impl::Deallocate(ptr, size); }
|
||||
static ALWAYS_INLINE void DeallocateUnsafe(void *ptr, size_t size) { return ::ams::fs::impl::DeallocateUnsafe(ptr, size); }
|
||||
|
||||
static ALWAYS_INLINE void LockAllocatorMutex() { return ::ams::fs::impl::LockAllocatorMutex(); }
|
||||
static ALWAYS_INLINE void UnlockAllocatorMutex() { return ::ams::fs::impl::UnlockAllocatorMutex(); }
|
||||
};
|
||||
|
||||
template<typename T, typename Impl, bool AllocateWhileLocked>
|
||||
class AllocatorTemplate : public std::allocator<T> {
|
||||
public:
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
using other = AllocatorTemplate<U, Impl, AllocateWhileLocked>;
|
||||
};
|
||||
private:
|
||||
bool m_allocation_failed;
|
||||
private:
|
||||
static ALWAYS_INLINE T *AllocateImpl(::std::size_t n) {
|
||||
if constexpr (AllocateWhileLocked) {
|
||||
auto * const p = Impl::AllocateUnsafe(sizeof(T) * n);
|
||||
Impl::UnlockAllocatorMutex();
|
||||
return static_cast<T *>(p);
|
||||
} else {
|
||||
return static_cast<T *>(Impl::Allocate(sizeof(T) * n));
|
||||
}
|
||||
}
|
||||
public:
|
||||
AllocatorTemplate() : m_allocation_failed(false) { /* ... */ }
|
||||
|
||||
template<typename U>
|
||||
AllocatorTemplate(const AllocatorTemplate<U, Impl, AllocateWhileLocked> &rhs) : m_allocation_failed(rhs.IsAllocationFailed()) { /* ... */ }
|
||||
|
||||
bool IsAllocationFailed() const { return m_allocation_failed; }
|
||||
|
||||
[[nodiscard]] T *allocate(::std::size_t n) {
|
||||
auto * const p = AllocateImpl(n);
|
||||
if (AMS_UNLIKELY(p == nullptr) && n) {
|
||||
m_allocation_failed = true;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void deallocate(T *p, ::std::size_t n) {
|
||||
Impl::Deallocate(p, sizeof(T) * n);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Impl>
|
||||
using AllocatorTemplateForAllocateShared = AllocatorTemplate<T, Impl, true>;
|
||||
|
||||
template<typename T, template<typename, typename> class AllocatorTemplateT, typename Impl, typename... Args>
|
||||
std::shared_ptr<T> AllocateSharedImpl(Args &&... args) {
|
||||
/* Try to allocate. */
|
||||
{
|
||||
/* Acquire exclusive access to the allocator. */
|
||||
Impl::LockAllocatorMutex();
|
||||
|
||||
/* Check that we can allocate memory (using overestimate of 0x80 + sizeof(T)). */
|
||||
if (auto * const p = Impl::AllocateUnsafe(0x80 + sizeof(T)); AMS_LIKELY(p != nullptr)) {
|
||||
/* Free the memory we allocated. */
|
||||
Impl::DeallocateUnsafe(p, 0x80 + sizeof(T));
|
||||
|
||||
/* Get allocator type. */
|
||||
using AllocatorType = AllocatorTemplateT<T, Impl>;
|
||||
|
||||
/* Allocate the shared pointer. */
|
||||
return std::allocate_shared<T>(AllocatorType{}, std::forward<Args>(args)...);
|
||||
} else {
|
||||
/* We can't allocate. */
|
||||
Impl::UnlockAllocatorMutex();
|
||||
}
|
||||
}
|
||||
|
||||
/* We failed. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class Deleter {
|
||||
private:
|
||||
size_t m_size;
|
||||
public:
|
||||
Deleter() : m_size() { /* ... */ }
|
||||
explicit Deleter(size_t sz) : m_size(sz) { /* ... */ }
|
||||
|
||||
void operator()(void *ptr) const {
|
||||
::ams::fs::impl::Deallocate(ptr, m_size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto MakeUnique() {
|
||||
/* Check that we're not using MakeUnique unnecessarily. */
|
||||
static_assert(!std::derived_from<T, ::ams::fs::impl::Newable>);
|
||||
|
||||
return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T)));
|
||||
}
|
||||
|
||||
template<typename ArrayT>
|
||||
auto MakeUnique(size_t size) {
|
||||
using T = typename std::remove_extent<ArrayT>::type;
|
||||
|
||||
static_assert(util::is_pod<ArrayT>::value);
|
||||
static_assert(std::is_array<ArrayT>::value);
|
||||
|
||||
/* Check that we're not using MakeUnique unnecessarily. */
|
||||
static_assert(!std::derived_from<T, ::ams::fs::impl::Newable>);
|
||||
|
||||
using ReturnType = std::unique_ptr<ArrayT, Deleter>;
|
||||
|
||||
const size_t alloc_size = sizeof(T) * size;
|
||||
return ReturnType(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
std::shared_ptr<T> AllocateShared(Args &&... args) {
|
||||
return ::ams::fs::impl::AllocateSharedImpl<T, ::ams::fs::impl::AllocatorTemplateForAllocateShared, ::ams::fs::impl::AllocatorImpl>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
struct MemoryReportInfo {
|
||||
u64 pooled_buffer_peak_free_size;
|
||||
u64 pooled_buffer_retried_count;
|
||||
u64 pooled_buffer_reduce_allocation_count;
|
||||
u64 buffer_manager_peak_free_size;
|
||||
u64 buffer_manager_retried_count;
|
||||
u64 exp_heap_peak_free_size;
|
||||
u64 buffer_pool_peak_free_size;
|
||||
u64 patrol_read_allocate_buffer_success_count;
|
||||
u64 patrol_read_allocate_buffer_failure_count;
|
||||
u64 buffer_manager_peak_total_allocatable_size;
|
||||
u64 buffer_pool_max_allocate_size;
|
||||
u64 pooled_buffer_failed_ideal_allocation_count_on_async_access;
|
||||
|
||||
u8 reserved[0x20];
|
||||
};
|
||||
static_assert(sizeof(MemoryReportInfo) == 0x80);
|
||||
static_assert(util::is_pod<MemoryReportInfo>::value);
|
||||
|
||||
Result GetAndClearMemoryReportInfo(MemoryReportInfo *out);
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fs/fs_istorage.hpp>
|
||||
#include <stratosphere/fs/fs_query_range.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class MemoryStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
||||
private:
|
||||
u8 * const m_buf;
|
||||
const s64 m_size;
|
||||
public:
|
||||
MemoryStorage(void *b, s64 sz) : m_buf(static_cast<u8 *>(b)), m_size(sz) { /* .. */ }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
/* Succeed immediately on zero-sized read. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
|
||||
/* Copy from memory. */
|
||||
std::memcpy(buffer, m_buf + offset, size);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
/* Succeed immediately on zero-sized write. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
|
||||
/* Copy to memory. */
|
||||
std::memcpy(m_buf + offset, buffer, size);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
*out = m_size;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
AMS_UNUSED(size);
|
||||
R_THROW(fs::ResultUnsupportedSetSizeForMemoryStorage());
|
||||
}
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||
AMS_UNUSED(offset, size, src, src_size);
|
||||
|
||||
switch (op_id) {
|
||||
case OperationId::Invalidate:
|
||||
R_SUCCEED();
|
||||
case OperationId::QueryRange:
|
||||
R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(dst_size == sizeof(QueryRangeInfo), fs::ResultInvalidSize());
|
||||
reinterpret_cast<QueryRangeInfo *>(dst)->Clear();
|
||||
R_SUCCEED();
|
||||
default:
|
||||
R_THROW(fs::ResultUnsupportedOperateRangeForMemoryStorage());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
constexpr inline size_t MmcCidSize = 0x10;
|
||||
|
||||
constexpr inline size_t MmcExtendedCsdSize = 0x200;
|
||||
|
||||
constexpr inline int MmcExtendedCsdOffsetReEolInfo = 267;
|
||||
constexpr inline int MmcExtendedCsdOffsetDeviceLifeTimeEstTypA = 268;
|
||||
constexpr inline int MmcExtendedCsdOffsetDeviceLifeTimeEstTypB = 269;
|
||||
|
||||
enum MmcSpeedMode {
|
||||
MmcSpeedMode_Identification = 0,
|
||||
MmcSpeedMode_LegacySpeed = 1,
|
||||
MmcSpeedMode_HighSpeed = 2,
|
||||
MmcSpeedMode_Hs200 = 3,
|
||||
MmcSpeedMode_Hs400 = 4,
|
||||
MmcSpeedMode_Unknown = 5,
|
||||
};
|
||||
|
||||
enum class MmcPartition {
|
||||
UserData = 0,
|
||||
BootPartition1 = 1,
|
||||
BootPartition2 = 2,
|
||||
};
|
||||
|
||||
Result GetMmcCid(void *dst, size_t size);
|
||||
|
||||
inline void ClearMmcCidSerialNumber(u8 *cid) {
|
||||
/* Clear the serial number from the cid. */
|
||||
std::memset(cid + 1, 0, 4);
|
||||
}
|
||||
|
||||
Result GetMmcSpeedMode(MmcSpeedMode *out);
|
||||
|
||||
Result GetMmcPatrolCount(u32 *out);
|
||||
|
||||
Result GetMmcExtendedCsd(void *dst, size_t size);
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
constexpr inline size_t MountNameLengthMax = 15;
|
||||
|
||||
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *src);
|
||||
|
||||
void Unmount(const char *mount_name);
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class OperationId : s64 {
|
||||
FillZero = 0,
|
||||
DestroySignature = 1,
|
||||
Invalidate = 2,
|
||||
QueryRange = 3,
|
||||
QueryUnpreparedRange = 4,
|
||||
QueryLazyLoadCompletionRate = 5,
|
||||
SetLazyLoadPriority = 6,
|
||||
|
||||
ReadLazyLoadFileForciblyForDebug = 10001,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,675 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_memory_management.hpp>
|
||||
#include <stratosphere/fs/impl/fs_common_mount_name.hpp>
|
||||
#include <stratosphere/fs/fs_path_utility.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class DirectoryPathParser;
|
||||
|
||||
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||
/* NOTE: Intentional inaccuracy in custom WriteBuffer class, to save 0x10 bytes (0x28 -> 0x18) over Nintendo's implementation. */
|
||||
class Path {
|
||||
NON_COPYABLE(Path);
|
||||
NON_MOVEABLE(Path);
|
||||
private:
|
||||
static constexpr const char *EmptyPath = "";
|
||||
static constexpr size_t WriteBufferAlignmentLength = 8;
|
||||
private:
|
||||
friend class DirectoryPathParser;
|
||||
public:
|
||||
class WriteBuffer {
|
||||
NON_COPYABLE(WriteBuffer);
|
||||
private:
|
||||
char *m_buffer;
|
||||
size_t m_length_and_is_normalized;
|
||||
public:
|
||||
constexpr WriteBuffer() : m_buffer(nullptr), m_length_and_is_normalized(0) { /* ... */ }
|
||||
|
||||
constexpr ~WriteBuffer() {
|
||||
if (m_buffer != nullptr) {
|
||||
::ams::fs::impl::Deallocate(m_buffer, this->GetLength());
|
||||
this->ResetBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
constexpr WriteBuffer(WriteBuffer &&rhs) : m_buffer(rhs.m_buffer), m_length_and_is_normalized(rhs.m_length_and_is_normalized) {
|
||||
rhs.ResetBuffer();
|
||||
}
|
||||
|
||||
constexpr WriteBuffer &operator=(WriteBuffer &&rhs) {
|
||||
if (m_buffer != nullptr) {
|
||||
::ams::fs::impl::Deallocate(m_buffer, this->GetLength());
|
||||
}
|
||||
|
||||
m_buffer = rhs.m_buffer;
|
||||
m_length_and_is_normalized = rhs.m_length_and_is_normalized;
|
||||
|
||||
rhs.ResetBuffer();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::unique_ptr<char[], ::ams::fs::impl::Deleter> ReleaseBuffer() {
|
||||
auto released = std::unique_ptr<char[], ::ams::fs::impl::Deleter>(m_buffer, ::ams::fs::impl::Deleter(this->GetLength()));
|
||||
this->ResetBuffer();
|
||||
return released;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE void ResetBuffer() {
|
||||
m_buffer = nullptr;
|
||||
this->SetLength(0);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE char *Get() const {
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE size_t GetLength() const {
|
||||
return m_length_and_is_normalized >> 1;
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsNormalized() const {
|
||||
return static_cast<bool>(m_length_and_is_normalized & 1);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE void SetNormalized() {
|
||||
m_length_and_is_normalized |= static_cast<size_t>(1);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE void SetNotNormalized() {
|
||||
m_length_and_is_normalized &= ~static_cast<size_t>(1);
|
||||
}
|
||||
private:
|
||||
constexpr ALWAYS_INLINE WriteBuffer(char *buffer, size_t length) : m_buffer(buffer), m_length_and_is_normalized(0) {
|
||||
this->SetLength(length);
|
||||
}
|
||||
public:
|
||||
static WriteBuffer Make(size_t length) {
|
||||
if (void *alloc = ::ams::fs::impl::Allocate(length); alloc != nullptr) {
|
||||
return WriteBuffer(static_cast<char *>(alloc), length);
|
||||
} else {
|
||||
return WriteBuffer();
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
||||
constexpr ALWAYS_INLINE void SetLength(size_t size) {
|
||||
m_length_and_is_normalized = (m_length_and_is_normalized & 1) | (size << 1);
|
||||
}
|
||||
};
|
||||
private:
|
||||
const char *m_str;
|
||||
WriteBuffer m_write_buffer;
|
||||
public:
|
||||
constexpr Path() : m_str(EmptyPath), m_write_buffer() {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
constexpr Path(const char *s, util::ConstantInitializeTag) : m_str(s), m_write_buffer() {
|
||||
m_write_buffer.SetNormalized();
|
||||
}
|
||||
|
||||
constexpr ~Path() { /* ... */ }
|
||||
|
||||
std::unique_ptr<char[], ::ams::fs::impl::Deleter> ReleaseBuffer() {
|
||||
/* Check pre-conditions. */
|
||||
AMS_ASSERT(m_write_buffer.Get() != nullptr);
|
||||
|
||||
/* Reset. */
|
||||
m_str = EmptyPath;
|
||||
|
||||
/* Release our write buffer. */
|
||||
return m_write_buffer.ReleaseBuffer();
|
||||
}
|
||||
|
||||
constexpr Result SetShallowBuffer(const char *buffer) {
|
||||
/* Check pre-conditions. */
|
||||
AMS_ASSERT(m_write_buffer.GetLength() == 0);
|
||||
|
||||
/* Check the buffer is valid. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Set buffer. */
|
||||
this->SetReadOnlyBuffer(buffer);
|
||||
|
||||
/* Note that we're normalized. */
|
||||
this->SetNormalized();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
constexpr const char *GetString() const {
|
||||
/* Check pre-conditions. */
|
||||
AMS_ASSERT(this->IsNormalized());
|
||||
|
||||
return m_str;
|
||||
}
|
||||
|
||||
constexpr size_t GetLength() const {
|
||||
if (std::is_constant_evaluated()) {
|
||||
return util::Strlen(this->GetString());
|
||||
} else {
|
||||
return std::strlen(this->GetString());
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool IsEmpty() const {
|
||||
return *m_str == '\x00';
|
||||
}
|
||||
|
||||
constexpr bool IsMatchHead(const char *p, size_t len) const {
|
||||
return util::Strncmp(this->GetString(), p, len) == 0;
|
||||
}
|
||||
|
||||
Result Initialize(const Path &rhs) {
|
||||
/* Check the other path is normalized. */
|
||||
const bool normalized = rhs.IsNormalized();
|
||||
R_UNLESS(normalized, fs::ResultNotNormalized());
|
||||
|
||||
/* Allocate buffer for our path. */
|
||||
const auto len = rhs.GetLength();
|
||||
R_TRY(this->Preallocate(len + 1));
|
||||
|
||||
/* Copy the path. */
|
||||
const size_t copied = util::Strlcpy<char>(m_write_buffer.Get(), rhs.GetString(), len + 1);
|
||||
R_UNLESS(copied == len, fs::ResultUnexpectedInPathA());
|
||||
|
||||
/* Set normalized. */
|
||||
this->SetNormalized();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Initialize(const char *path, size_t len) {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Initialize. */
|
||||
R_TRY(this->InitializeImpl(path, len));
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Initialize(const char *path) {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
R_RETURN(this->Initialize(path, std::strlen(path)));
|
||||
}
|
||||
|
||||
Result InitializeWithFormat(const char *fmt, ...) __attribute__((format (printf, 2, 3))) {
|
||||
/* Check the format string is valid. */
|
||||
R_UNLESS(fmt != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Create the va_list for formatting. */
|
||||
std::va_list vl;
|
||||
va_start(vl, fmt);
|
||||
|
||||
/* Determine how big the string will be. */
|
||||
char dummy;
|
||||
const auto len = util::VSNPrintf(std::addressof(dummy), 0, fmt, vl);
|
||||
|
||||
/* Allocate buffer for our path. */
|
||||
R_TRY(this->Preallocate(len + 1));
|
||||
|
||||
/* Format our path into our new buffer. */
|
||||
const auto real_len = util::VSNPrintf(m_write_buffer.Get(), m_write_buffer.GetLength(), fmt, vl);
|
||||
AMS_ASSERT(real_len == len);
|
||||
AMS_UNUSED(real_len);
|
||||
|
||||
/* Finish the va_list. */
|
||||
va_end(vl);
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result InitializeWithReplaceBackslash(const char *path) {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Initialize. */
|
||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||
|
||||
/* Replace slashes as desired. */
|
||||
if (const auto write_buffer_length = m_write_buffer.GetLength(); write_buffer_length > 1) {
|
||||
fs::Replace(m_write_buffer.Get(), write_buffer_length - 1, '\\', '/');
|
||||
}
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result InitializeWithReplaceForwardSlashes(const char *path) {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Initialize. */
|
||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||
|
||||
/* Replace slashes as desired. */
|
||||
if (m_write_buffer.GetLength() > 1) {
|
||||
if (auto *p = m_write_buffer.Get(); p[0] == '/' && p[1] == '/') {
|
||||
p[0] = '\\';
|
||||
p[1] = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result InitializeWithReplaceUnc(const char *path) {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Initialize. */
|
||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
|
||||
/* Replace unc as desired. */
|
||||
if (m_str[0]) {
|
||||
auto *p = m_write_buffer.Get();
|
||||
|
||||
/* Replace :/// -> \\ as needed. */
|
||||
if (auto *sep = std::strstr(p, ":///"); sep != nullptr) {
|
||||
sep[0] = '\\';
|
||||
sep[1] = '\\';
|
||||
}
|
||||
|
||||
/* Edit path prefix. */
|
||||
if (!util::Strncmp(p, AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME AMS_FS_IMPL_MOUNT_NAME_DELIMITER "/", AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME_LEN + AMS_FS_IMPL_MOUNT_NAME_DELIMITER_LEN + 1)) {
|
||||
static_assert((AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME AMS_FS_IMPL_MOUNT_NAME_DELIMITER)[AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME_LEN + AMS_FS_IMPL_MOUNT_NAME_DELIMITER_LEN - 1] == '/');
|
||||
|
||||
p[AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME_LEN + AMS_FS_IMPL_MOUNT_NAME_DELIMITER_LEN - 1] = '\\';
|
||||
p[AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME_LEN + AMS_FS_IMPL_MOUNT_NAME_DELIMITER_LEN - 0] = '\\';
|
||||
}
|
||||
|
||||
if (p[0] == '/' && p[1] == '/') {
|
||||
p[0] = '\\';
|
||||
p[1] = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result InitializeWithNormalization(const char *path, size_t size) {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Initialize. */
|
||||
R_TRY(this->InitializeImpl(path, size));
|
||||
|
||||
/* Set not normalized. */
|
||||
this->SetNotNormalized();
|
||||
|
||||
/* Perform normalization. */
|
||||
fs::PathFlags path_flags;
|
||||
if (fs::IsPathRelative(m_str)) {
|
||||
path_flags.AllowRelativePath();
|
||||
} else if (fs::IsWindowsPath(m_str, true)) {
|
||||
path_flags.AllowWindowsPath();
|
||||
} else {
|
||||
/* NOTE: In this case, Nintendo checks is normalized, then sets is normalized, then returns success. */
|
||||
/* This seems like a bug. */
|
||||
size_t dummy;
|
||||
bool normalized;
|
||||
R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy), m_str));
|
||||
|
||||
this->SetNormalized();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Normalize. */
|
||||
R_TRY(this->Normalize(path_flags));
|
||||
|
||||
this->SetNormalized();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result InitializeWithNormalization(const char *path) {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
R_RETURN(this->InitializeWithNormalization(path, std::strlen(path)));
|
||||
}
|
||||
|
||||
Result InitializeAsEmpty() {
|
||||
/* Clear our buffer. */
|
||||
this->ClearBuffer();
|
||||
|
||||
/* Set normalized. */
|
||||
this->SetNormalized();
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result AppendChild(const char *child) {
|
||||
/* Check the path is valid. */
|
||||
R_UNLESS(child != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* Basic checks. If we hvea a path and the child is empty, we have nothing to do. */
|
||||
const char *c = child;
|
||||
if (m_str[0]) {
|
||||
/* Skip an early separator. */
|
||||
if (*c == '/') {
|
||||
++c;
|
||||
}
|
||||
|
||||
R_SUCCEED_IF(*c == '\x00');
|
||||
}
|
||||
|
||||
/* If we don't have a string, we can just initialize. */
|
||||
auto cur_len = std::strlen(m_str);
|
||||
if (cur_len == 0) {
|
||||
R_RETURN(this->Initialize(child));
|
||||
}
|
||||
|
||||
/* Remove a trailing separator. */
|
||||
if (m_str[cur_len - 1] == '/' || m_str[cur_len - 1] == '\\') {
|
||||
--cur_len;
|
||||
}
|
||||
|
||||
/* Get the child path's length. */
|
||||
auto child_len = std::strlen(c);
|
||||
|
||||
/* Reset our write buffer. */
|
||||
WriteBuffer old_write_buffer;
|
||||
if (m_write_buffer.Get() != nullptr) {
|
||||
old_write_buffer = std::move(m_write_buffer);
|
||||
this->ClearBuffer();
|
||||
}
|
||||
|
||||
/* Pre-allocate the new buffer. */
|
||||
R_TRY(this->Preallocate(cur_len + 1 + child_len + 1));
|
||||
|
||||
/* Get our write buffer. */
|
||||
auto *dst = m_write_buffer.Get();
|
||||
if (old_write_buffer.Get() != nullptr && cur_len > 0) {
|
||||
util::Strlcpy<char>(dst, old_write_buffer.Get(), cur_len + 1);
|
||||
}
|
||||
|
||||
/* Add separator. */
|
||||
dst[cur_len] = '/';
|
||||
|
||||
/* Copy the child path. */
|
||||
const size_t copied = util::Strlcpy<char>(dst + cur_len + 1, c, child_len + 1);
|
||||
R_UNLESS(copied == child_len, fs::ResultUnexpectedInPathA());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result AppendChild(const Path &rhs) {
|
||||
R_RETURN(this->AppendChild(rhs.GetString()));
|
||||
}
|
||||
|
||||
Result Combine(const Path &parent, const Path &child) {
|
||||
/* Get the lengths. */
|
||||
const auto p_len = parent.GetLength();
|
||||
const auto c_len = child.GetLength();
|
||||
|
||||
/* Allocate our buffer. */
|
||||
R_TRY(this->Preallocate(p_len + c_len + 1));
|
||||
|
||||
/* Initialize as parent. */
|
||||
R_TRY(this->Initialize(parent));
|
||||
|
||||
/* If we're empty, we can just initialize as child. */
|
||||
if (this->IsEmpty()) {
|
||||
R_TRY(this->Initialize(child));
|
||||
} else {
|
||||
/* Otherwise, we should append the child. */
|
||||
R_TRY(this->AppendChild(child));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RemoveChild() {
|
||||
/* If we don't have a write-buffer, ensure that we have one. */
|
||||
if (m_write_buffer.Get() == nullptr) {
|
||||
if (const auto len = std::strlen(m_str); len > 0) {
|
||||
R_TRY(this->Preallocate(len));
|
||||
util::Strlcpy<char>(m_write_buffer.Get(), m_str, len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that it's possible for us to remove a child. */
|
||||
auto *p = m_write_buffer.Get();
|
||||
s32 len = std::strlen(p);
|
||||
R_UNLESS(len != 1 || (p[0] != '/' && p[0] != '.'), fs::ResultNotImplemented());
|
||||
|
||||
/* Handle a trailing separator. */
|
||||
if (len > 0 && (p[len - 1] == '\\' || p[len - 1] == '/')) {
|
||||
--len;
|
||||
}
|
||||
|
||||
/* Remove the child path segment. */
|
||||
while ((--len) >= 0 && p[len]) {
|
||||
if (p[len] == '/' || p[len] == '\\') {
|
||||
if (len > 0) {
|
||||
p[len] = 0;
|
||||
} else {
|
||||
p[1] = 0;
|
||||
len = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that length remains > 0. */
|
||||
R_UNLESS(len > 0, fs::ResultNotImplemented());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Normalize(const PathFlags &flags) {
|
||||
/* If we're already normalized, nothing to do. */
|
||||
R_SUCCEED_IF(this->IsNormalized());
|
||||
|
||||
/* Check if we're normalized. */
|
||||
bool normalized;
|
||||
size_t dummy;
|
||||
R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy), m_str, flags));
|
||||
|
||||
/* If we're not normalized, normalize. */
|
||||
if (!normalized) {
|
||||
/* Determine necessary buffer length. */
|
||||
auto len = m_write_buffer.GetLength();
|
||||
if (flags.IsRelativePathAllowed() && fs::IsPathRelative(m_str)) {
|
||||
len += 2;
|
||||
}
|
||||
if (flags.IsWindowsPathAllowed() && fs::IsWindowsPath(m_str, true)) {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
/* Allocate a new buffer. */
|
||||
const size_t size = util::AlignUp(len, WriteBufferAlignmentLength);
|
||||
auto buf = WriteBuffer::Make(size);
|
||||
R_UNLESS(buf.Get() != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||
|
||||
/* Normalize into it. */
|
||||
R_TRY(PathFormatter::Normalize(buf.Get(), size, m_write_buffer.Get(), m_write_buffer.GetLength(), flags));
|
||||
|
||||
/* Set the normalized buffer as our buffer. */
|
||||
this->SetModifiableBuffer(std::move(buf));
|
||||
}
|
||||
|
||||
/* Set normalized. */
|
||||
this->SetNormalized();
|
||||
R_SUCCEED();
|
||||
}
|
||||
private:
|
||||
void ClearBuffer() {
|
||||
m_write_buffer.ResetBuffer();
|
||||
m_str = EmptyPath;
|
||||
}
|
||||
|
||||
void SetModifiableBuffer(WriteBuffer &&buffer) {
|
||||
/* Check pre-conditions. */
|
||||
AMS_ASSERT(buffer.Get() != nullptr);
|
||||
AMS_ASSERT(buffer.GetLength() > 0);
|
||||
AMS_ASSERT(util::IsAligned(buffer.GetLength(), WriteBufferAlignmentLength));
|
||||
|
||||
/* Get whether we're normalized. */
|
||||
if (m_write_buffer.IsNormalized()) {
|
||||
buffer.SetNormalized();
|
||||
} else {
|
||||
buffer.SetNotNormalized();
|
||||
}
|
||||
|
||||
/* Set write buffer. */
|
||||
m_write_buffer = std::move(buffer);
|
||||
m_str = m_write_buffer.Get();
|
||||
}
|
||||
|
||||
constexpr void SetReadOnlyBuffer(const char *buffer) {
|
||||
m_str = buffer;
|
||||
m_write_buffer.ResetBuffer();
|
||||
}
|
||||
|
||||
Result Preallocate(size_t length) {
|
||||
/* Allocate additional space, if needed. */
|
||||
if (length > m_write_buffer.GetLength()) {
|
||||
/* Allocate buffer. */
|
||||
const size_t size = util::AlignUp(length, WriteBufferAlignmentLength);
|
||||
auto buf = WriteBuffer::Make(size);
|
||||
R_UNLESS(buf.Get() != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||
|
||||
/* Set write buffer. */
|
||||
this->SetModifiableBuffer(std::move(buf));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result InitializeImpl(const char *path, size_t size) {
|
||||
if (size > 0 && path[0]) {
|
||||
/* Pre allocate a buffer for the path. */
|
||||
R_TRY(this->Preallocate(size + 1));
|
||||
|
||||
/* Copy the path. */
|
||||
const size_t copied = util::Strlcpy<char>(m_write_buffer.Get(), path, size + 1);
|
||||
R_UNLESS(copied >= size, fs::ResultUnexpectedInPathA());
|
||||
} else {
|
||||
/* We can just clear the buffer. */
|
||||
this->ClearBuffer();
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
constexpr char *GetWriteBuffer() {
|
||||
AMS_ASSERT(m_write_buffer.Get() != nullptr);
|
||||
return m_write_buffer.Get();
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE size_t GetWriteBufferLength() const {
|
||||
return m_write_buffer.GetLength();
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE bool IsNormalized() const { return m_write_buffer.IsNormalized(); }
|
||||
|
||||
constexpr ALWAYS_INLINE void SetNormalized() { m_write_buffer.SetNormalized(); }
|
||||
|
||||
constexpr ALWAYS_INLINE void SetNotNormalized() { m_write_buffer.SetNotNormalized(); }
|
||||
public:
|
||||
ALWAYS_INLINE bool operator==(const fs::Path &rhs) const { return std::strcmp(this->GetString(), rhs.GetString()) == 0; }
|
||||
ALWAYS_INLINE bool operator!=(const fs::Path &rhs) const { return !(*this == rhs); }
|
||||
ALWAYS_INLINE bool operator==(const char *p) const { return std::strcmp(this->GetString(), p) == 0; }
|
||||
ALWAYS_INLINE bool operator!=(const char *p) const { return !(*this == p); }
|
||||
};
|
||||
|
||||
consteval fs::Path MakeConstantPath(const char *s) { return fs::Path(s, util::ConstantInitializeTag{}); }
|
||||
|
||||
inline Result SetUpFixedPath(fs::Path *out, const char *s) {
|
||||
/* Verify the path is normalized. */
|
||||
bool normalized;
|
||||
size_t dummy;
|
||||
R_TRY(PathNormalizer::IsNormalized(std::addressof(normalized), std::addressof(dummy), s));
|
||||
|
||||
R_UNLESS(normalized, fs::ResultInvalidPathFormat());
|
||||
|
||||
/* Set the fixed path. */
|
||||
R_RETURN(out->SetShallowBuffer(s));
|
||||
}
|
||||
|
||||
inline Result SetUpFixedPathSingleEntry(fs::Path *out, char *buf, size_t buf_size, const char *e) {
|
||||
/* Print the path into the buffer. */
|
||||
const size_t len = util::TSNPrintf(buf, buf_size, "/%s", e);
|
||||
R_UNLESS(len < buf_size, fs::ResultInvalidArgument());
|
||||
|
||||
/* Set up the path. */
|
||||
R_RETURN(SetUpFixedPath(out, buf));
|
||||
}
|
||||
|
||||
inline Result SetUpFixedPathDoubleEntry(fs::Path *out, char *buf, size_t buf_size, const char *e, const char *e2) {
|
||||
/* Print the path into the buffer. */
|
||||
const size_t len = util::TSNPrintf(buf, buf_size, "/%s/%s", e, e2);
|
||||
R_UNLESS(len < buf_size, fs::ResultInvalidArgument());
|
||||
|
||||
/* Set up the path. */
|
||||
R_RETURN(SetUpFixedPath(out, buf));
|
||||
}
|
||||
|
||||
inline Result SetUpFixedPathSaveId(fs::Path *out, char *buf, size_t buf_size, u64 id) {
|
||||
/* Print the path into the buffer. */
|
||||
const size_t len = util::TSNPrintf(buf, buf_size, "/%016" PRIx64 "", id);
|
||||
R_UNLESS(len < buf_size, fs::ResultInvalidArgument());
|
||||
|
||||
/* Set up the path. */
|
||||
R_RETURN(SetUpFixedPath(out, buf));
|
||||
}
|
||||
|
||||
inline Result SetUpFixedPathSaveMetaName(fs::Path *out, char *buf, size_t buf_size, u32 type) {
|
||||
/* Print the path into the buffer. */
|
||||
const size_t len = util::TSNPrintf(buf, buf_size, "/%08" PRIx32 ".meta", type);
|
||||
R_UNLESS(len < buf_size, fs::ResultInvalidArgument());
|
||||
|
||||
/* Set up the path. */
|
||||
R_RETURN(SetUpFixedPath(out, buf));
|
||||
}
|
||||
|
||||
inline Result SetUpFixedPathSaveMetaDir(fs::Path *out, char *buf, size_t buf_size, u64 id) {
|
||||
/* Print the path into the buffer. */
|
||||
const size_t len = util::TSNPrintf(buf, buf_size, "/saveMeta/%016" PRIx64 "", id);
|
||||
R_UNLESS(len < buf_size, fs::ResultInvalidArgument());
|
||||
|
||||
/* Set up the path. */
|
||||
R_RETURN(SetUpFixedPath(out, buf));
|
||||
}
|
||||
|
||||
constexpr inline bool IsWindowsDriveRootPath(const fs::Path &path) {
|
||||
const char * const str = path.GetString();
|
||||
return fs::IsWindowsDrive(str) && (str[2] == StringTraits::DirectorySeparator || str[2] == StringTraits::AlternateDirectorySeparator) && str[3] == StringTraits::NullTerminator;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum Priority {
|
||||
Priority_Realtime = 0,
|
||||
Priority_Normal = 1,
|
||||
Priority_Low = 2,
|
||||
};
|
||||
|
||||
enum PriorityRaw {
|
||||
PriorityRaw_Realtime = 0,
|
||||
PriorityRaw_Normal = 1,
|
||||
PriorityRaw_Low = 2,
|
||||
PriorityRaw_Background = 3,
|
||||
};
|
||||
|
||||
Priority GetPriorityOnCurrentThread();
|
||||
Priority GetPriority(os::ThreadType *thread);
|
||||
PriorityRaw GetPriorityRawOnCurrentThread();
|
||||
PriorityRaw GetPriorityRaw(os::ThreadType *thread);
|
||||
|
||||
void SetPriorityOnCurrentThread(Priority prio);
|
||||
void SetPriority(os::ThreadType *thread, Priority prio);
|
||||
void SetPriorityRawOnCurrentThread(PriorityRaw prio);
|
||||
void SetPriorityRaw(os::ThreadType *thread, PriorityRaw prio);
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/fs/fs_content_attributes.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 17.5.0.0 */
|
||||
Result GetProgramId(ncm::ProgramId *out, const char *path, fs::ContentAttributes attr);
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct ProgramIndexMapInfo {
|
||||
ncm::ProgramId program_id;
|
||||
ncm::ProgramId base_program_id;
|
||||
u8 program_index;
|
||||
u8 pad[0xF];
|
||||
};
|
||||
static_assert(util::is_pod<ProgramIndexMapInfo>::value);
|
||||
static_assert(sizeof(ProgramIndexMapInfo) == 0x20);
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_file.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
struct QueryRangeInfo {
|
||||
s32 aes_ctr_key_type;
|
||||
s32 speed_emulation_type;
|
||||
u8 reserved[0x38];
|
||||
|
||||
void Clear() {
|
||||
this->aes_ctr_key_type = 0;
|
||||
this->speed_emulation_type = 0;
|
||||
std::memset(this->reserved, 0, sizeof(this->reserved));
|
||||
}
|
||||
|
||||
void Merge(const QueryRangeInfo &rhs) {
|
||||
this->aes_ctr_key_type |= rhs.aes_ctr_key_type;
|
||||
this->speed_emulation_type |= rhs.speed_emulation_type;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(util::is_pod<QueryRangeInfo>::value);
|
||||
static_assert(sizeof(QueryRangeInfo) == 0x40);
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
static_assert(sizeof(QueryRangeInfo) == sizeof(::FsRangeInfo));
|
||||
#endif
|
||||
|
||||
using FileQueryRangeInfo = QueryRangeInfo;
|
||||
using StorageQueryRangeInfo = QueryRangeInfo;
|
||||
|
||||
Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size);
|
||||
|
||||
enum class AesCtrKeyTypeFlag : s32 {
|
||||
InternalKeyForSoftwareAes = (1 << 0),
|
||||
InternalKeyForHardwareAes = (1 << 1),
|
||||
ExternalKeyForHardwareAes = (1 << 2),
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
namespace {
|
||||
|
||||
class ReadOnlyFile : public fsa::IFile, public impl::Newable {
|
||||
NON_COPYABLE(ReadOnlyFile);
|
||||
NON_MOVEABLE(ReadOnlyFile);
|
||||
private:
|
||||
std::unique_ptr<fsa::IFile> m_base_file;
|
||||
public:
|
||||
explicit ReadOnlyFile(std::unique_ptr<fsa::IFile> &&f) : m_base_file(std::move(f)) { AMS_ASSERT(m_base_file != nullptr); }
|
||||
virtual ~ReadOnlyFile() { /* ... */ }
|
||||
private:
|
||||
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
|
||||
R_RETURN(m_base_file->Read(out, offset, buffer, size, option));
|
||||
}
|
||||
|
||||
virtual Result DoGetSize(s64 *out) override final {
|
||||
R_RETURN(m_base_file->GetSize(out));
|
||||
}
|
||||
|
||||
virtual Result DoFlush() override final {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
||||
bool need_append;
|
||||
R_TRY(this->DryWrite(std::addressof(need_append), offset, size, option, fs::OpenMode_Read));
|
||||
|
||||
AMS_ASSERT(!need_append);
|
||||
|
||||
AMS_UNUSED(buffer);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFile());
|
||||
}
|
||||
|
||||
virtual Result DoSetSize(s64 size) override final {
|
||||
R_TRY(this->DrySetSize(size, fs::OpenMode_Read));
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFile());
|
||||
}
|
||||
|
||||
virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
|
||||
switch (op_id) {
|
||||
case OperationId::Invalidate:
|
||||
case OperationId::QueryRange:
|
||||
R_RETURN(m_base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
default:
|
||||
R_THROW(fs::ResultUnsupportedOperateRangeForReadOnlyFile());
|
||||
}
|
||||
}
|
||||
public:
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override {
|
||||
return m_base_file->GetDomainObjectId();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class ReadOnlyFileSystemTemplate : public fsa::IFileSystem, public impl::Newable {
|
||||
NON_COPYABLE(ReadOnlyFileSystemTemplate);
|
||||
NON_MOVEABLE(ReadOnlyFileSystemTemplate);
|
||||
private:
|
||||
T m_base_fs;
|
||||
public:
|
||||
explicit ReadOnlyFileSystemTemplate(T &&fs) : m_base_fs(std::move(fs)) { /* ... */ }
|
||||
virtual ~ReadOnlyFileSystemTemplate() { /* ... */ }
|
||||
private:
|
||||
virtual Result DoOpenFile(std::unique_ptr<fsa::IFile> *out_file, const fs::Path &path, OpenMode mode) override final {
|
||||
/* Only allow opening files with mode = read. */
|
||||
R_UNLESS((mode & fs::OpenMode_All) == fs::OpenMode_Read, fs::ResultInvalidOpenMode());
|
||||
|
||||
std::unique_ptr<fsa::IFile> base_file;
|
||||
R_TRY(m_base_fs->OpenFile(std::addressof(base_file), path, mode));
|
||||
|
||||
auto read_only_file = std::make_unique<ReadOnlyFile>(std::move(base_file));
|
||||
R_UNLESS(read_only_file != nullptr, fs::ResultAllocationMemoryFailedInReadOnlyFileSystemA());
|
||||
|
||||
*out_file = std::move(read_only_file);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result DoOpenDirectory(std::unique_ptr<fsa::IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) override final {
|
||||
R_RETURN(m_base_fs->OpenDirectory(out_dir, path, mode));
|
||||
}
|
||||
|
||||
virtual Result DoGetEntryType(DirectoryEntryType *out, const fs::Path &path) override final {
|
||||
R_RETURN(m_base_fs->GetEntryType(out, path));
|
||||
}
|
||||
|
||||
virtual Result DoCommit() override final {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final {
|
||||
AMS_UNUSED(path, size, flags);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoDeleteFile(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoCreateDirectory(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final {
|
||||
AMS_UNUSED(old_path, new_path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final {
|
||||
AMS_UNUSED(old_path, new_path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
|
||||
AMS_UNUSED(path);
|
||||
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||
R_RETURN(m_base_fs->GetFreeSpaceSize(out, path));
|
||||
}
|
||||
|
||||
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||
AMS_UNUSED(out, path);
|
||||
R_THROW(fs::ResultUnsupportedGetTotalSpaceSizeForReadOnlyFileSystem());
|
||||
}
|
||||
|
||||
virtual Result DoCommitProvisionally(s64 counter) override final {
|
||||
AMS_UNUSED(counter);
|
||||
R_THROW(fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem());
|
||||
}
|
||||
};
|
||||
|
||||
using ReadOnlyFileSystem = ReadOnlyFileSystemTemplate<std::unique_ptr<::ams::fs::fsa::IFileSystem>>;
|
||||
using ReadOnlyFileSystemShared = ReadOnlyFileSystemTemplate<std::shared_ptr<::ams::fs::fsa::IFileSystem>>;
|
||||
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
||||
#include <stratosphere/fs/fs_query_range.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
class RemoteFile : public fsa::IFile, public impl::Newable {
|
||||
NON_COPYABLE(RemoteFile);
|
||||
NON_MOVEABLE(RemoteFile);
|
||||
private:
|
||||
::FsFile m_base_file;
|
||||
public:
|
||||
RemoteFile(const ::FsFile &f) : m_base_file(f) { /* ... */ }
|
||||
|
||||
virtual ~RemoteFile() { fsFileClose(std::addressof(m_base_file)); }
|
||||
public:
|
||||
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
|
||||
R_RETURN(fsFileRead(std::addressof(m_base_file), offset, buffer, size, option._value, out));
|
||||
}
|
||||
|
||||
virtual Result DoGetSize(s64 *out) override final {
|
||||
R_RETURN(fsFileGetSize(std::addressof(m_base_file), out));
|
||||
}
|
||||
|
||||
virtual Result DoFlush() override final {
|
||||
R_RETURN(fsFileFlush(std::addressof(m_base_file)));
|
||||
}
|
||||
|
||||
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
||||
R_RETURN(fsFileWrite(std::addressof(m_base_file), offset, buffer, size, option._value));
|
||||
}
|
||||
|
||||
virtual Result DoSetSize(s64 size) override final {
|
||||
R_RETURN(fsFileSetSize(std::addressof(m_base_file), size));
|
||||
}
|
||||
|
||||
virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
|
||||
AMS_UNUSED(src, src_size);
|
||||
|
||||
R_UNLESS(op_id == OperationId::QueryRange, fs::ResultUnsupportedOperateRangeForFileServiceObjectAdapter());
|
||||
R_UNLESS(dst_size == sizeof(FileQueryRangeInfo), fs::ResultInvalidSize());
|
||||
|
||||
R_RETURN(fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(dst)));
|
||||
}
|
||||
public:
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final {
|
||||
return sf::cmif::DomainObjectId{serviceGetObjectId(const_cast<::Service *>(std::addressof(m_base_file.s)))};
|
||||
}
|
||||
};
|
||||
|
||||
class RemoteDirectory : public fsa::IDirectory, public impl::Newable {
|
||||
NON_COPYABLE(RemoteDirectory);
|
||||
NON_MOVEABLE(RemoteDirectory);
|
||||
private:
|
||||
::FsDir m_base_dir;
|
||||
public:
|
||||
RemoteDirectory(const ::FsDir &d) : m_base_dir(d) { /* ... */ }
|
||||
|
||||
virtual ~RemoteDirectory() { fsDirClose(std::addressof(m_base_dir)); }
|
||||
public:
|
||||
virtual Result DoRead(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) override final {
|
||||
static_assert(sizeof(*out_entries) == sizeof(::FsDirectoryEntry));
|
||||
R_RETURN(fsDirRead(std::addressof(m_base_dir), out_count, max_entries, reinterpret_cast<::FsDirectoryEntry *>(out_entries)));
|
||||
}
|
||||
|
||||
virtual Result DoGetEntryCount(s64 *out) override final {
|
||||
R_RETURN(fsDirGetEntryCount(std::addressof(m_base_dir), out));
|
||||
}
|
||||
public:
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final {
|
||||
return sf::cmif::DomainObjectId{serviceGetObjectId(const_cast<::Service *>(std::addressof(m_base_dir.s)))};
|
||||
}
|
||||
};
|
||||
|
||||
class RemoteFileSystem : public fsa::IFileSystem, public impl::Newable {
|
||||
NON_COPYABLE(RemoteFileSystem);
|
||||
NON_MOVEABLE(RemoteFileSystem);
|
||||
private:
|
||||
::FsFileSystem m_base_fs;
|
||||
public:
|
||||
RemoteFileSystem(const ::FsFileSystem &fs) : m_base_fs(fs) { /* ... */ }
|
||||
|
||||
virtual ~RemoteFileSystem() { fsFsClose(std::addressof(m_base_fs)); }
|
||||
private:
|
||||
Result GetPathForServiceObject(fssrv::sf::Path *out_path, const fs::Path &path) {
|
||||
/* Copy, ensuring length is in bounds. */
|
||||
const size_t len = util::Strlcpy<char>(out_path->str, path.GetString(), sizeof(out_path->str));
|
||||
R_UNLESS(len < sizeof(out_path->str), fs::ResultTooLongPath());
|
||||
|
||||
/* Replace directory separators. */
|
||||
/* TODO: Is this still necessary? We originally had it to not break things on low firmware. */
|
||||
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX)
|
||||
fs::Replace(out_path->str, sizeof(out_path->str) - 1, '\\', '/');
|
||||
#endif
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
public:
|
||||
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsCreateFile(std::addressof(m_base_fs), sf_path.str, size, flags));
|
||||
}
|
||||
|
||||
virtual Result DoDeleteFile(const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsDeleteFile(std::addressof(m_base_fs), sf_path.str));
|
||||
}
|
||||
|
||||
virtual Result DoCreateDirectory(const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsCreateDirectory(std::addressof(m_base_fs), sf_path.str));
|
||||
}
|
||||
|
||||
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsDeleteDirectory(std::addressof(m_base_fs), sf_path.str));
|
||||
}
|
||||
|
||||
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), sf_path.str));
|
||||
}
|
||||
|
||||
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final {
|
||||
fssrv::sf::Path old_sf_path;
|
||||
fssrv::sf::Path new_sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(old_sf_path), old_path));
|
||||
R_TRY(GetPathForServiceObject(std::addressof(new_sf_path), new_path));
|
||||
R_RETURN(fsFsRenameFile(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str));
|
||||
}
|
||||
|
||||
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final {
|
||||
fssrv::sf::Path old_sf_path;
|
||||
fssrv::sf::Path new_sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(old_sf_path), old_path));
|
||||
R_TRY(GetPathForServiceObject(std::addressof(new_sf_path), new_path));
|
||||
R_RETURN(fsFsRenameDirectory(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str));
|
||||
}
|
||||
|
||||
virtual Result DoGetEntryType(DirectoryEntryType *out, const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
|
||||
static_assert(sizeof(::FsDirEntryType) == sizeof(DirectoryEntryType));
|
||||
R_RETURN(fsFsGetEntryType(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsDirEntryType *>(out)));
|
||||
}
|
||||
|
||||
virtual Result DoOpenFile(std::unique_ptr<fsa::IFile> *out_file, const fs::Path &path, OpenMode mode) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
|
||||
FsFile f;
|
||||
R_TRY(fsFsOpenFile(std::addressof(m_base_fs), sf_path.str, mode, std::addressof(f)));
|
||||
|
||||
auto file = std::make_unique<RemoteFile>(f);
|
||||
R_UNLESS(file != nullptr, fs::ResultAllocationMemoryFailedNew());
|
||||
|
||||
*out_file = std::move(file);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result DoOpenDirectory(std::unique_ptr<fsa::IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
|
||||
FsDir d;
|
||||
R_TRY(fsFsOpenDirectory(std::addressof(m_base_fs), sf_path.str, mode, std::addressof(d)));
|
||||
|
||||
auto dir = std::make_unique<RemoteDirectory>(d);
|
||||
R_UNLESS(dir != nullptr, fs::ResultAllocationMemoryFailedNew());
|
||||
|
||||
*out_dir = std::move(dir);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result DoCommit() override final {
|
||||
R_RETURN(fsFsCommit(std::addressof(m_base_fs)));
|
||||
}
|
||||
|
||||
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsGetFreeSpace(std::addressof(m_base_fs), sf_path.str, out));
|
||||
}
|
||||
|
||||
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsGetTotalSpace(std::addressof(m_base_fs), sf_path.str, out));
|
||||
}
|
||||
|
||||
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), sf_path.str));
|
||||
}
|
||||
|
||||
virtual Result DoGetFileTimeStampRaw(FileTimeStampRaw *out, const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
static_assert(sizeof(FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
|
||||
R_RETURN(fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsTimeStampRaw *>(out)));
|
||||
}
|
||||
|
||||
virtual Result DoQueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryId query, const fs::Path &path) override final {
|
||||
fssrv::sf::Path sf_path;
|
||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||
R_RETURN(fsFsQueryEntry(std::addressof(m_base_fs), dst, dst_size, src, src_size, sf_path.str, static_cast<FsFileSystemQueryId>(query)));
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_istorage.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
class RemoteStorage : public IStorage, public impl::Newable {
|
||||
NON_COPYABLE(RemoteStorage);
|
||||
NON_MOVEABLE(RemoteStorage);
|
||||
private:
|
||||
::FsStorage m_base_storage;
|
||||
public:
|
||||
RemoteStorage(::FsStorage &s) : m_base_storage(s) { /* ... */}
|
||||
|
||||
virtual ~RemoteStorage() { fsStorageClose(std::addressof(m_base_storage)); }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
R_RETURN(fsStorageRead(std::addressof(m_base_storage), offset, buffer, size));
|
||||
};
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
R_RETURN(fsStorageWrite(std::addressof(m_base_storage), offset, buffer, size));
|
||||
};
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_RETURN(fsStorageFlush(std::addressof(m_base_storage)));
|
||||
};
|
||||
|
||||
virtual Result GetSize(s64 *out_size) override {
|
||||
R_RETURN(fsStorageGetSize(std::addressof(m_base_storage), out_size));
|
||||
};
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
R_RETURN(fsStorageSetSize(std::addressof(m_base_storage), size));
|
||||
};
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||
/* TODO: How to deal with this? */
|
||||
AMS_UNUSED(dst, dst_size, op_id, offset, size, src, src_size);
|
||||
R_THROW(fs::ResultUnsupportedOperation());
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
void SetEnabledAutoAbort(bool enabled);
|
||||
void SetResultHandledByApplication(bool application);
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/fs/fs_content_attributes.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
union RightsId {
|
||||
u8 data[0x10];
|
||||
u64 data64[2];
|
||||
};
|
||||
static_assert(sizeof(RightsId) == 0x10);
|
||||
static_assert(util::is_pod<RightsId>::value);
|
||||
|
||||
inline bool operator==(const RightsId &lhs, const RightsId &rhs) {
|
||||
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const RightsId &lhs, const RightsId &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(const RightsId &lhs, const RightsId &rhs) {
|
||||
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(RightsId)) < 0;
|
||||
}
|
||||
|
||||
constexpr inline RightsId InvalidRightsId = {};
|
||||
|
||||
/* Rights ID API */
|
||||
Result GetRightsId(RightsId *out, const char *path, fs::ContentAttributes attr);
|
||||
Result GetRightsId(RightsId *out, u8 *out_key_generation, const char *path, fs::ContentAttributes attr);
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
||||
#include <stratosphere/fs/common/fs_dbm_hierarchical_rom_file_table.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class RomFsFileSystem : public fsa::IFileSystem, public impl::Newable {
|
||||
NON_COPYABLE(RomFsFileSystem);
|
||||
public:
|
||||
using RomFileTable = HierarchicalRomFileTable;
|
||||
private:
|
||||
RomFileTable m_rom_file_table;
|
||||
IStorage *m_base_storage;
|
||||
std::unique_ptr<IStorage> m_unique_storage;
|
||||
std::unique_ptr<IStorage> m_dir_bucket_storage;
|
||||
std::unique_ptr<IStorage> m_dir_entry_storage;
|
||||
std::unique_ptr<IStorage> m_file_bucket_storage;
|
||||
std::unique_ptr<IStorage> m_file_entry_storage;
|
||||
s64 m_entry_size;
|
||||
private:
|
||||
Result GetFileInfo(RomFileTable::FileInfo *out, const char *path);
|
||||
public:
|
||||
static Result GetRequiredWorkingMemorySize(size_t *out, IStorage *storage);
|
||||
public:
|
||||
RomFsFileSystem();
|
||||
virtual ~RomFsFileSystem() override;
|
||||
|
||||
Result Initialize(IStorage *base, void *work, size_t work_size, bool use_cache);
|
||||
Result Initialize(std::unique_ptr<IStorage>&& base, void *work, size_t work_size, bool use_cache);
|
||||
|
||||
IStorage *GetBaseStorage();
|
||||
RomFileTable *GetRomFileTable();
|
||||
Result GetFileBaseOffset(s64 *out, const char *path);
|
||||
public:
|
||||
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override;
|
||||
virtual Result DoDeleteFile(const fs::Path &path) override;
|
||||
virtual Result DoCreateDirectory(const fs::Path &path) override;
|
||||
virtual Result DoDeleteDirectory(const fs::Path &path) override;
|
||||
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override;
|
||||
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override;
|
||||
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override;
|
||||
virtual Result DoGetEntryType(fs::DirectoryEntryType *out, const fs::Path &path) override;
|
||||
virtual Result DoOpenFile(std::unique_ptr<fs::fsa::IFile> *out_file, const fs::Path &path, fs::OpenMode mode) override;
|
||||
virtual Result DoOpenDirectory(std::unique_ptr<fs::fsa::IDirectory> *out_dir, const fs::Path &path, fs::OpenDirectoryMode mode) override;
|
||||
virtual Result DoCommit() override;
|
||||
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override;
|
||||
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override;
|
||||
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override;
|
||||
|
||||
/* These aren't accessible as commands. */
|
||||
virtual Result DoCommitProvisionally(s64 counter) override;
|
||||
virtual Result DoRollback() override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_save_data_types.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result DeleteSaveData(SaveDataId id);
|
||||
Result DeleteSaveData(SaveDataSpaceId space_id, SaveDataId id);
|
||||
|
||||
Result GetSaveDataFlags(u32 *out, SaveDataId id);
|
||||
Result GetSaveDataFlags(u32 *out, SaveDataSpaceId space_id, SaveDataId id);
|
||||
Result SetSaveDataFlags(SaveDataId id, SaveDataSpaceId space_id, u32 flags);
|
||||
|
||||
Result GetSaveDataAvailableSize(s64 *out, SaveDataId id);
|
||||
Result GetSaveDataJournalSize(s64 *out, SaveDataId id);
|
||||
|
||||
Result ExtendSaveData(SaveDataSpaceId space_id, SaveDataId id, s64 available_size, s64 journal_size);
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_save_data_types.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result CommitSaveData(const char *path);
|
||||
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
using SaveDataId = u64;
|
||||
using SystemSaveDataId = u64;
|
||||
using SystemBcatSaveDataId = SystemSaveDataId;
|
||||
|
||||
enum class SaveDataSpaceId : u8 {
|
||||
System = 0,
|
||||
User = 1,
|
||||
SdSystem = 2,
|
||||
Temporary = 3,
|
||||
SdUser = 4,
|
||||
|
||||
ProperSystem = 100,
|
||||
SafeMode = 101,
|
||||
};
|
||||
|
||||
enum class SaveDataType : u8 {
|
||||
System = 0,
|
||||
Account = 1,
|
||||
Bcat = 2,
|
||||
Device = 3,
|
||||
Temporary = 4,
|
||||
Cache = 5,
|
||||
SystemBcat = 6,
|
||||
};
|
||||
|
||||
enum class SaveDataRank : u8 {
|
||||
Primary = 0,
|
||||
Secondary = 1,
|
||||
};
|
||||
|
||||
struct UserId {
|
||||
u64 data[2];
|
||||
};
|
||||
static_assert(util::is_pod<UserId>::value);
|
||||
|
||||
constexpr inline bool operator<(const UserId &lhs, const UserId &rhs) {
|
||||
if (lhs.data[0] < rhs.data[0]) {
|
||||
return true;
|
||||
} else if (lhs.data[0] == rhs.data[0] && lhs.data[1] < rhs.data[1]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const UserId &lhs, const UserId &rhs) {
|
||||
return lhs.data[0] == rhs.data[0] && lhs.data[1] == rhs.data[1];
|
||||
}
|
||||
|
||||
constexpr inline bool operator!=(const UserId &lhs, const UserId &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
constexpr inline SystemSaveDataId InvalidSystemSaveDataId = 0;
|
||||
constexpr inline UserId InvalidUserId = {};
|
||||
|
||||
enum SaveDataFlags : u32 {
|
||||
SaveDataFlags_None = (0 << 0),
|
||||
SaveDataFlags_KeepAfterResettingSystemSaveData = (1 << 0),
|
||||
SaveDataFlags_KeepAfterRefurbishment = (1 << 1),
|
||||
SaveDataFlags_KeepAfterResettingSystemSaveDataWithoutUserSaveData = (1 << 2),
|
||||
SaveDataFlags_NeedsSecureDelete = (1 << 3),
|
||||
};
|
||||
|
||||
enum class SaveDataMetaType : u8 {
|
||||
None = 0,
|
||||
Thumbnail = 1,
|
||||
ExtensionContext = 2,
|
||||
};
|
||||
|
||||
struct SaveDataMetaInfo {
|
||||
u32 size;
|
||||
SaveDataMetaType type;
|
||||
u8 reserved[0xB];
|
||||
};
|
||||
static_assert(util::is_pod<SaveDataMetaInfo>::value);
|
||||
static_assert(sizeof(SaveDataMetaInfo) == 0x10);
|
||||
|
||||
struct SaveDataCreationInfo {
|
||||
s64 size;
|
||||
s64 journal_size;
|
||||
s64 block_size;
|
||||
u64 owner_id;
|
||||
u32 flags;
|
||||
SaveDataSpaceId space_id;
|
||||
bool pseudo;
|
||||
u8 reserved[0x1A];
|
||||
};
|
||||
static_assert(util::is_pod<SaveDataCreationInfo>::value);
|
||||
static_assert(sizeof(SaveDataCreationInfo) == 0x40);
|
||||
|
||||
struct SaveDataAttribute {
|
||||
ncm::ProgramId program_id;
|
||||
UserId user_id;
|
||||
SystemSaveDataId system_save_data_id;
|
||||
SaveDataType type;
|
||||
SaveDataRank rank;
|
||||
u16 index;
|
||||
u8 reserved[0x1C];
|
||||
|
||||
static constexpr SaveDataAttribute Make(ncm::ProgramId program_id, SaveDataType type, UserId user_id, SystemSaveDataId system_save_data_id, u16 index, SaveDataRank rank) {
|
||||
return {
|
||||
.program_id = program_id,
|
||||
.user_id = user_id,
|
||||
.system_save_data_id = system_save_data_id,
|
||||
.type = type,
|
||||
.rank = rank,
|
||||
.index = index,
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr SaveDataAttribute Make(ncm::ProgramId program_id, SaveDataType type, UserId user_id, SystemSaveDataId system_save_data_id, u16 index) {
|
||||
return Make(program_id, type, user_id, system_save_data_id, index, SaveDataRank::Primary);
|
||||
}
|
||||
|
||||
static constexpr SaveDataAttribute Make(ncm::ProgramId program_id, SaveDataType type, UserId user_id, SystemSaveDataId system_save_data_id) {
|
||||
return Make(program_id, type, user_id, system_save_data_id, 0, SaveDataRank::Primary);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(SaveDataAttribute) == 0x40);
|
||||
static_assert(std::is_trivially_destructible<SaveDataAttribute>::value);
|
||||
|
||||
constexpr inline bool operator<(const SaveDataAttribute &lhs, const SaveDataAttribute &rhs) {
|
||||
return std::tie(lhs.program_id, lhs.user_id, lhs.system_save_data_id, lhs.index, lhs.rank) <
|
||||
std::tie(rhs.program_id, rhs.user_id, rhs.system_save_data_id, rhs.index, rhs.rank);
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const SaveDataAttribute &lhs, const SaveDataAttribute &rhs) {
|
||||
return std::tie(lhs.program_id, lhs.user_id, lhs.system_save_data_id, lhs.type, lhs.rank, lhs.index) ==
|
||||
std::tie(rhs.program_id, rhs.user_id, rhs.system_save_data_id, rhs.type, rhs.rank, rhs.index);
|
||||
}
|
||||
|
||||
constexpr inline bool operator!=(const SaveDataAttribute &lhs, const SaveDataAttribute &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
constexpr inline size_t DefaultSaveDataBlockSize = 16_KB;
|
||||
|
||||
struct SaveDataExtraData {
|
||||
SaveDataAttribute attr;
|
||||
u64 owner_id;
|
||||
s64 timestamp;
|
||||
u32 flags;
|
||||
u8 pad[4];
|
||||
s64 available_size;
|
||||
s64 journal_size;
|
||||
s64 commit_id;
|
||||
u8 unused[0x190];
|
||||
};
|
||||
static_assert(sizeof(SaveDataExtraData) == 0x200);
|
||||
static_assert(util::is_pod<SaveDataExtraData>::value);
|
||||
|
||||
struct HashSalt {
|
||||
static constexpr size_t Size = 32;
|
||||
|
||||
u8 value[Size];
|
||||
};
|
||||
static_assert(util::is_pod<HashSalt>::value);
|
||||
static_assert(sizeof(HashSalt) == HashSalt::Size);
|
||||
|
||||
using SaveDataHashSalt = util::optional<HashSalt>;
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class IEventNotifier;
|
||||
|
||||
constexpr inline size_t SdCardCidSize = 0x10;
|
||||
|
||||
enum SdCardSpeedMode {
|
||||
SdCardSpeedMode_Identification = 0,
|
||||
SdCardSpeedMode_DefaultSpeed = 1,
|
||||
SdCardSpeedMode_HighSpeed = 2,
|
||||
SdCardSpeedMode_Sdr12 = 3,
|
||||
SdCardSpeedMode_Sdr25 = 4,
|
||||
SdCardSpeedMode_Sdr50 = 5,
|
||||
SdCardSpeedMode_Sdr104 = 6,
|
||||
SdCardSpeedMode_Ddr50 = 7,
|
||||
SdCardSpeedMode_Unknown = 8,
|
||||
};
|
||||
|
||||
struct EncryptionSeed {
|
||||
char value[0x10];
|
||||
};
|
||||
static_assert(util::is_pod<EncryptionSeed>::value);
|
||||
static_assert(sizeof(EncryptionSeed) == 0x10);
|
||||
|
||||
Result GetSdCardCid(void *dst, size_t size);
|
||||
|
||||
inline void ClearSdCardCidSerialNumber(u8 *cid) {
|
||||
/* Clear the serial number from the cid. */
|
||||
std::memset(cid + 2, 0, 4);
|
||||
}
|
||||
|
||||
Result GetSdCardUserAreaSize(s64 *out);
|
||||
Result GetSdCardProtectedAreaSize(s64 *out);
|
||||
|
||||
Result GetSdCardSpeedMode(SdCardSpeedMode *out);
|
||||
|
||||
Result MountSdCard(const char *name);
|
||||
|
||||
Result MountSdCardErrorReportDirectoryForAtmosphere(const char *name);
|
||||
|
||||
Result OpenSdCardDetectionEventNotifier(std::unique_ptr<IEventNotifier> *out);
|
||||
|
||||
bool IsSdCardInserted();
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
bool IsSignedSystemPartitionOnSdCardValid(const char *system_root_path);
|
||||
bool IsSignedSystemPartitionOnSdCardValidDeprecated();
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum class SpeedEmulationMode {
|
||||
None = 0,
|
||||
Faster = 1,
|
||||
Slower = 2,
|
||||
Random = 3,
|
||||
};
|
||||
|
||||
/* TODO */
|
||||
/* Result SetSpeedEmulationMode(SpeedEmulationMode mode); */
|
||||
/* Result GetSpeedEmulationMode(SpeedEmulationMode *out); */
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum StorageType : s32 {
|
||||
StorageType_SaveData = 0,
|
||||
StorageType_RomFs = 1,
|
||||
StorageType_Authoring = 2,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/impl/fs_newable.hpp>
|
||||
#include <stratosphere/fs/fs_istorage.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class SubStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
||||
private:
|
||||
std::shared_ptr<IStorage> m_shared_base_storage;
|
||||
fs::IStorage *m_base_storage;
|
||||
s64 m_offset;
|
||||
s64 m_size;
|
||||
bool m_resizable;
|
||||
private:
|
||||
constexpr bool IsValid() const {
|
||||
return m_base_storage != nullptr;
|
||||
}
|
||||
public:
|
||||
SubStorage() : m_shared_base_storage(), m_base_storage(nullptr), m_offset(0), m_size(0), m_resizable(false) { /* ... */ }
|
||||
|
||||
SubStorage(const SubStorage &rhs) : m_shared_base_storage(rhs.m_shared_base_storage), m_base_storage(rhs.m_base_storage), m_offset(rhs.m_offset), m_size(rhs.m_size), m_resizable(rhs.m_resizable) { /* ... */}
|
||||
SubStorage &operator=(const SubStorage &rhs) {
|
||||
if (this != std::addressof(rhs)) {
|
||||
m_shared_base_storage = rhs.m_shared_base_storage;
|
||||
m_base_storage = rhs.m_base_storage;
|
||||
m_offset = rhs.m_offset;
|
||||
m_size = rhs.m_size;
|
||||
m_resizable = rhs.m_resizable;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SubStorage(IStorage *storage, s64 o, s64 sz) : m_shared_base_storage(), m_base_storage(storage), m_offset(o), m_size(sz), m_resizable(false) {
|
||||
AMS_ABORT_UNLESS(this->IsValid());
|
||||
AMS_ABORT_UNLESS(m_offset >= 0);
|
||||
AMS_ABORT_UNLESS(m_size >= 0);
|
||||
}
|
||||
|
||||
SubStorage(std::shared_ptr<IStorage> storage, s64 o, s64 sz) : m_shared_base_storage(storage), m_base_storage(storage.get()), m_offset(o), m_size(sz), m_resizable(false) {
|
||||
AMS_ABORT_UNLESS(this->IsValid());
|
||||
AMS_ABORT_UNLESS(m_offset >= 0);
|
||||
AMS_ABORT_UNLESS(m_size >= 0);
|
||||
}
|
||||
|
||||
SubStorage(SubStorage *sub, s64 o, s64 sz) : m_shared_base_storage(sub->m_shared_base_storage), m_base_storage(sub->m_base_storage), m_offset(o + sub->m_offset), m_size(sz), m_resizable(false) {
|
||||
AMS_ABORT_UNLESS(this->IsValid());
|
||||
AMS_ABORT_UNLESS(m_offset >= 0);
|
||||
AMS_ABORT_UNLESS(m_size >= 0);
|
||||
AMS_ABORT_UNLESS(sub->m_size >= o + sz);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE ::ams::fs::IStorage *operator->() {
|
||||
return this;
|
||||
}
|
||||
public:
|
||||
void SetResizable(bool rsz) {
|
||||
m_resizable = rsz;
|
||||
}
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
/* Ensure we're initialized. */
|
||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||
|
||||
/* Succeed immediately on zero-sized operation. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
|
||||
/* Validate arguments and read. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_RETURN(m_base_storage->Read(m_offset + offset, buffer, size));
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
|
||||
/* Ensure we're initialized. */
|
||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||
|
||||
/* Succeed immediately on zero-sized operation. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Validate arguments and write. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||
R_RETURN(m_base_storage->Write(m_offset + offset, buffer, size));
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||
R_RETURN(m_base_storage->Flush());
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
/* Ensure we're initialized and validate arguments. */
|
||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||
R_UNLESS(m_resizable, fs::ResultUnsupportedSetSizeForNotResizableSubStorage());
|
||||
|
||||
R_TRY(IStorage::CheckOffsetAndSize(m_offset, size));
|
||||
|
||||
/* Ensure that we're allowed to set size. */
|
||||
s64 cur_size;
|
||||
R_TRY(m_base_storage->GetSize(std::addressof(cur_size)));
|
||||
R_UNLESS(cur_size == m_offset + m_size, fs::ResultUnsupportedSetSizeForResizableSubStorage());
|
||||
|
||||
/* Set the size. */
|
||||
R_TRY(m_base_storage->SetSize(m_offset + size));
|
||||
|
||||
m_size = size;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override {
|
||||
/* Ensure we're initialized. */
|
||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||
|
||||
*out = m_size;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||
/* Ensure we're initialized. */
|
||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||
|
||||
/* If we're not invalidating, sanity check arguments. */
|
||||
if (op_id != fs::OperationId::Invalidate) {
|
||||
/* Succeed immediately on zero-sized operation other than invalidate. */
|
||||
R_SUCCEED_IF(size == 0);
|
||||
|
||||
/* Check access extents. */
|
||||
R_TRY(IStorage::CheckOffsetAndSize(offset, size));
|
||||
}
|
||||
|
||||
/* Perform the operation. */
|
||||
R_RETURN(m_base_storage->OperateRange(dst, dst_size, op_id, m_offset + offset, size, src, src_size));
|
||||
}
|
||||
|
||||
using IStorage::OperateRange;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result QueryMountSystemDataCacheSize(size_t *out, ncm::SystemDataId data_id);
|
||||
|
||||
Result MountSystemData(const char *name, ncm::SystemDataId data_id);
|
||||
Result MountSystemData(const char *name, ncm::SystemDataId data_id, void *cache_buffer, size_t cache_size);
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_save_data_types.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
void DisableAutoSaveDataCreation();
|
||||
|
||||
Result CreateSystemSaveData(SystemSaveDataId save_id, s64 size, s64 journal_size, u32 flags);
|
||||
Result CreateSystemSaveData(SystemSaveDataId save_id, u64 owner_id, s64 size, s64 journal_size, u32 flags);
|
||||
Result CreateSystemSaveData(SaveDataSpaceId space_id, SystemSaveDataId save_id, u64 owner_id, s64 size, s64 journal_size, u32 flags);
|
||||
|
||||
Result CreateSystemSaveData(SystemSaveDataId save_id, UserId user_id, s64 size, s64 journal_size, u32 flags);
|
||||
Result CreateSystemSaveData(SystemSaveDataId save_id, UserId user_id, u64 owner_id, s64 size, s64 journal_size, u32 flags);
|
||||
Result CreateSystemSaveData(SaveDataSpaceId space_id, SystemSaveDataId save_id, UserId user_id, u64 owner_id, s64 size, s64 journal_size, u32 flags);
|
||||
|
||||
Result MountSystemSaveData(const char *name, SystemSaveDataId id);
|
||||
Result MountSystemSaveData(const char *name, SaveDataSpaceId space_id, SystemSaveDataId id);
|
||||
|
||||
Result MountSystemSaveData(const char *name, SystemSaveDataId id, UserId user_id);
|
||||
Result MountSystemSaveData(const char *name, SaveDataSpaceId space_id, SystemSaveDataId id, UserId user_id);
|
||||
|
||||
Result DeleteSystemSaveData(SaveDataSpaceId space_id, SystemSaveDataId id, UserId user_id);
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_directory.hpp>
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class IDirectory {
|
||||
public:
|
||||
virtual ~IDirectory() { /* ... */ }
|
||||
|
||||
Result Read(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) {
|
||||
R_UNLESS(out_count != nullptr, fs::ResultNullptrArgument());
|
||||
if (max_entries == 0) {
|
||||
*out_count = 0;
|
||||
R_SUCCEED();
|
||||
}
|
||||
R_UNLESS(out_entries != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(max_entries > 0, fs::ResultInvalidArgument());
|
||||
R_RETURN(this->DoRead(out_count, out_entries, max_entries));
|
||||
}
|
||||
|
||||
Result GetEntryCount(s64 *out) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
R_RETURN(this->DoGetEntryCount(out));
|
||||
}
|
||||
public:
|
||||
/* TODO: This is a hack to allow the mitm API to work. Find a better way? */
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const = 0;
|
||||
protected:
|
||||
/* ...? */
|
||||
private:
|
||||
virtual Result DoRead(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) = 0;
|
||||
virtual Result DoGetEntryCount(s64 *out) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_file.hpp>
|
||||
#include <stratosphere/fs/fs_filesystem.hpp>
|
||||
#include <stratosphere/fs/fs_operate_range.hpp>
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
class IFile {
|
||||
public:
|
||||
virtual ~IFile() { /* ... */ }
|
||||
|
||||
Result Read(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
||||
/* Check that we have an output pointer. */
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
|
||||
/* If we have nothing to read, just succeed. */
|
||||
if (size == 0) {
|
||||
*out = 0;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Check that the read is valid. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(offset >= 0, fs::ResultOutOfRange());
|
||||
R_UNLESS(util::IsIntValueRepresentable<s64>(size), fs::ResultOutOfRange());
|
||||
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
|
||||
|
||||
/* Do the read. */
|
||||
R_RETURN(this->DoRead(out, offset, buffer, size, option));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result Read(size_t *out, s64 offset, void *buffer, size_t size) { R_RETURN(this->Read(out, offset, buffer, size, ReadOption::None)); }
|
||||
|
||||
Result GetSize(s64 *out) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
R_RETURN(this->DoGetSize(out));
|
||||
}
|
||||
|
||||
Result Flush() {
|
||||
R_RETURN(this->DoFlush());
|
||||
}
|
||||
|
||||
Result Write(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
|
||||
/* Handle the zero-size case. */
|
||||
if (size == 0) {
|
||||
if (option.HasFlushFlag()) {
|
||||
R_TRY(this->Flush());
|
||||
}
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Check the write is valid. */
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(offset >= 0, fs::ResultOutOfRange());
|
||||
R_UNLESS(util::IsIntValueRepresentable<s64>(size), fs::ResultOutOfRange());
|
||||
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
|
||||
|
||||
R_RETURN(this->DoWrite(offset, buffer, size, option));
|
||||
}
|
||||
|
||||
Result SetSize(s64 size) {
|
||||
R_UNLESS(size >= 0, fs::ResultOutOfRange());
|
||||
R_RETURN(this->DoSetSize(size));
|
||||
}
|
||||
|
||||
Result OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) {
|
||||
R_RETURN(this->DoOperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
}
|
||||
|
||||
Result OperateRange(fs::OperationId op_id, s64 offset, s64 size) {
|
||||
R_RETURN(this->DoOperateRange(nullptr, 0, op_id, offset, size, nullptr, 0));
|
||||
}
|
||||
public:
|
||||
/* TODO: This is a hack to allow the mitm API to work. Find a better way? */
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const = 0;
|
||||
protected:
|
||||
Result DryRead(size_t *out, s64 offset, size_t size, const fs::ReadOption &option, OpenMode open_mode) {
|
||||
AMS_UNUSED(option);
|
||||
|
||||
/* Check that we can read. */
|
||||
R_UNLESS((open_mode & OpenMode_Read) != 0, fs::ResultReadNotPermitted());
|
||||
|
||||
/* Get the file size, and validate our offset. */
|
||||
s64 file_size = 0;
|
||||
R_TRY(this->DoGetSize(std::addressof(file_size)));
|
||||
R_UNLESS(offset <= file_size, fs::ResultOutOfRange());
|
||||
|
||||
*out = static_cast<size_t>(std::min(file_size - offset, static_cast<s64>(size)));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result DrySetSize(s64 size, fs::OpenMode open_mode) {
|
||||
AMS_UNUSED(size);
|
||||
|
||||
/* Check that we can write. */
|
||||
R_UNLESS((open_mode & OpenMode_Write) != 0, fs::ResultWriteNotPermitted());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result DryWrite(bool *out_append, s64 offset, size_t size, const fs::WriteOption &option, fs::OpenMode open_mode) {
|
||||
AMS_UNUSED(option);
|
||||
|
||||
/* Check that we can write. */
|
||||
R_UNLESS((open_mode & OpenMode_Write) != 0, fs::ResultWriteNotPermitted());
|
||||
|
||||
/* Get the file size. */
|
||||
s64 file_size = 0;
|
||||
R_TRY(this->DoGetSize(&file_size));
|
||||
|
||||
/* Determine if we need to append. */
|
||||
*out_append = false;
|
||||
if (file_size < offset + static_cast<s64>(size)) {
|
||||
R_UNLESS((open_mode & OpenMode_AllowAppend) != 0, fs::ResultFileExtensionWithoutOpenModeAllowAppend());
|
||||
*out_append = true;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
private:
|
||||
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) = 0;
|
||||
virtual Result DoGetSize(s64 *out) = 0;
|
||||
virtual Result DoFlush() = 0;
|
||||
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) = 0;
|
||||
virtual Result DoSetSize(s64 size) = 0;
|
||||
virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_filesystem.hpp>
|
||||
#include <stratosphere/fs/fs_filesystem_for_debug.hpp>
|
||||
#include <stratosphere/fs/fs_path.hpp>
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class IFile;
|
||||
class IDirectory;
|
||||
|
||||
enum class QueryId {
|
||||
SetConcatenationFileAttribute = 0,
|
||||
UpdateMac = 1,
|
||||
IsSignedSystemPartitionOnSdCardValid = 2,
|
||||
QueryUnpreparedFileInformation = 3,
|
||||
};
|
||||
|
||||
class IFileSystem {
|
||||
public:
|
||||
virtual ~IFileSystem() { /* ... */ }
|
||||
|
||||
Result CreateFile(const fs::Path &path, s64 size, int option) {
|
||||
R_UNLESS(size >= 0, fs::ResultOutOfRange());
|
||||
R_RETURN(this->DoCreateFile(path, size, option));
|
||||
}
|
||||
|
||||
Result CreateFile(const fs::Path &path, s64 size) {
|
||||
R_RETURN(this->CreateFile(path, size, fs::CreateOption_None));
|
||||
}
|
||||
|
||||
Result DeleteFile(const fs::Path &path) {
|
||||
R_RETURN(this->DoDeleteFile(path));
|
||||
}
|
||||
|
||||
Result CreateDirectory(const fs::Path &path) {
|
||||
R_RETURN(this->DoCreateDirectory(path));
|
||||
}
|
||||
|
||||
Result DeleteDirectory(const fs::Path &path) {
|
||||
R_RETURN(this->DoDeleteDirectory(path));
|
||||
}
|
||||
|
||||
Result DeleteDirectoryRecursively(const fs::Path &path) {
|
||||
R_RETURN(this->DoDeleteDirectoryRecursively(path));
|
||||
}
|
||||
|
||||
Result RenameFile(const fs::Path &old_path, const fs::Path &new_path) {
|
||||
R_RETURN(this->DoRenameFile(old_path, new_path));
|
||||
}
|
||||
|
||||
Result RenameDirectory(const fs::Path &old_path, const fs::Path &new_path) {
|
||||
R_RETURN(this->DoRenameDirectory(old_path, new_path));
|
||||
}
|
||||
|
||||
Result GetEntryType(DirectoryEntryType *out, const fs::Path &path) {
|
||||
R_RETURN(this->DoGetEntryType(out, path));
|
||||
}
|
||||
|
||||
Result OpenFile(std::unique_ptr<IFile> *out_file, const fs::Path &path, OpenMode mode) {
|
||||
R_UNLESS(out_file != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS((mode & OpenMode_ReadWrite) != 0, fs::ResultInvalidOpenMode());
|
||||
R_UNLESS((mode & ~OpenMode_All) == 0, fs::ResultInvalidOpenMode());
|
||||
R_RETURN(this->DoOpenFile(out_file, path, mode));
|
||||
}
|
||||
|
||||
Result OpenDirectory(std::unique_ptr<IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) {
|
||||
R_UNLESS(out_dir != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS((mode & OpenDirectoryMode_All) != 0, fs::ResultInvalidOpenMode());
|
||||
R_UNLESS((mode & ~(OpenDirectoryMode_All | OpenDirectoryMode_NotRequireFileSize)) == 0, fs::ResultInvalidOpenMode());
|
||||
R_RETURN(this->DoOpenDirectory(out_dir, path, mode));
|
||||
}
|
||||
|
||||
Result Commit() {
|
||||
R_RETURN(this->DoCommit());
|
||||
}
|
||||
|
||||
Result GetFreeSpaceSize(s64 *out, const fs::Path &path) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
R_RETURN(this->DoGetFreeSpaceSize(out, path));
|
||||
}
|
||||
|
||||
Result GetTotalSpaceSize(s64 *out, const fs::Path &path) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
R_RETURN(this->DoGetTotalSpaceSize(out, path));
|
||||
}
|
||||
|
||||
Result CleanDirectoryRecursively(const fs::Path &path) {
|
||||
R_RETURN(this->DoCleanDirectoryRecursively(path));
|
||||
}
|
||||
|
||||
Result GetFileTimeStampRaw(FileTimeStampRaw *out, const fs::Path &path) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
R_RETURN(this->DoGetFileTimeStampRaw(out, path));
|
||||
}
|
||||
|
||||
Result QueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, QueryId query, const fs::Path &path) {
|
||||
R_RETURN(this->DoQueryEntry(dst, dst_size, src, src_size, query, path));
|
||||
}
|
||||
|
||||
/* These aren't accessible as commands. */
|
||||
|
||||
Result CommitProvisionally(s64 counter) {
|
||||
R_RETURN(this->DoCommitProvisionally(counter));
|
||||
}
|
||||
|
||||
Result Rollback() {
|
||||
R_RETURN(this->DoRollback());
|
||||
}
|
||||
|
||||
Result Flush() {
|
||||
R_RETURN(this->DoFlush());
|
||||
}
|
||||
|
||||
protected:
|
||||
/* ...? */
|
||||
private:
|
||||
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) = 0;
|
||||
virtual Result DoDeleteFile(const fs::Path &path) = 0;
|
||||
virtual Result DoCreateDirectory(const fs::Path &path) = 0;
|
||||
virtual Result DoDeleteDirectory(const fs::Path &path) = 0;
|
||||
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) = 0;
|
||||
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) = 0;
|
||||
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) = 0;
|
||||
virtual Result DoGetEntryType(fs::DirectoryEntryType *out, const fs::Path &path) = 0;
|
||||
virtual Result DoOpenFile(std::unique_ptr<fs::fsa::IFile> *out_file, const fs::Path &path, fs::OpenMode mode) = 0;
|
||||
virtual Result DoOpenDirectory(std::unique_ptr<fs::fsa::IDirectory> *out_dir, const fs::Path &path, fs::OpenDirectoryMode mode) = 0;
|
||||
virtual Result DoCommit() = 0;
|
||||
|
||||
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) {
|
||||
AMS_UNUSED(out, path);
|
||||
R_THROW(fs::ResultNotImplemented());
|
||||
}
|
||||
|
||||
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) {
|
||||
AMS_UNUSED(out, path);
|
||||
R_THROW(fs::ResultNotImplemented());
|
||||
}
|
||||
|
||||
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) = 0;
|
||||
|
||||
virtual Result DoGetFileTimeStampRaw(fs::FileTimeStampRaw *out, const fs::Path &path) {
|
||||
AMS_UNUSED(out, path);
|
||||
R_THROW(fs::ResultNotImplemented());
|
||||
}
|
||||
|
||||
virtual Result DoQueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fs::fsa::QueryId query, const fs::Path &path) {
|
||||
AMS_UNUSED(dst, dst_size, src, src_size, query, path);
|
||||
R_THROW(fs::ResultNotImplemented());
|
||||
}
|
||||
|
||||
/* These aren't accessible as commands. */
|
||||
virtual Result DoCommitProvisionally(s64 counter) {
|
||||
AMS_UNUSED(counter);
|
||||
R_THROW(fs::ResultNotImplemented());
|
||||
}
|
||||
|
||||
virtual Result DoRollback() {
|
||||
R_THROW(fs::ResultNotImplemented());
|
||||
}
|
||||
|
||||
virtual Result DoFlush() {
|
||||
R_THROW(fs::ResultNotImplemented());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept PointerToFileSystem = ::ams::util::RawOrSmartPointerTo<T, ::ams::fs::fsa::IFileSystem>;
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class ICommonMountNameGenerator {
|
||||
public:
|
||||
virtual ~ICommonMountNameGenerator() { /* ... */ }
|
||||
virtual Result GenerateCommonMountName(char *name, size_t name_size) = 0;
|
||||
};
|
||||
|
||||
class IFileSystem;
|
||||
|
||||
Result Register(const char *name, std::unique_ptr<IFileSystem> &&fs);
|
||||
Result Register(const char *name, std::unique_ptr<IFileSystem> &&fs, std::unique_ptr<ICommonMountNameGenerator> &&generator);
|
||||
Result Register(const char *name, std::unique_ptr<IFileSystem> &&fs, std::unique_ptr<ICommonMountNameGenerator> &&generator, bool use_data_cache, bool use_path_cache, bool multi_commit_supported);
|
||||
|
||||
void Unregister(const char *name);
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/fs/fs_access_log.hpp>
|
||||
#include <stratosphere/fs/fs_directory.hpp>
|
||||
#include <stratosphere/fs/fs_file.hpp>
|
||||
#include <stratosphere/fs/fs_priority.hpp>
|
||||
#include <stratosphere/os/os_tick.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum AccessLogTarget : u32 {
|
||||
AccessLogTarget_None = (0 << 0),
|
||||
AccessLogTarget_Application = (1 << 0),
|
||||
AccessLogTarget_System = (1 << 1),
|
||||
};
|
||||
|
||||
struct IdentifyAccessLogHandle {
|
||||
void *handle;
|
||||
public:
|
||||
static constexpr IdentifyAccessLogHandle MakeHandle(void *h) {
|
||||
return IdentifyAccessLogHandle{h};
|
||||
}
|
||||
};
|
||||
|
||||
bool IsEnabledAccessLog(u32 target);
|
||||
bool IsEnabledAccessLog();
|
||||
|
||||
bool IsEnabledHandleAccessLog(fs::FileHandle handle);
|
||||
bool IsEnabledHandleAccessLog(fs::DirectoryHandle handle);
|
||||
bool IsEnabledHandleAccessLog(fs::impl::IdentifyAccessLogHandle handle);
|
||||
bool IsEnabledHandleAccessLog(const void *handle);
|
||||
|
||||
bool IsEnabledFileSystemAccessorAccessLog(const char *mount_name);
|
||||
void EnableFileSystemAccessorAccessLog(const char *mount_name);
|
||||
|
||||
using AccessLogPrinterCallback = int (*)(char *buffer, size_t buffer_size);
|
||||
void RegisterStartAccessLogPrinterCallback(AccessLogPrinterCallback callback);
|
||||
|
||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::impl::IdentifyAccessLogHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
||||
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
||||
void OutputAccessLog(Result result, fs::Priority priority, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 7, 8)));
|
||||
void OutputAccessLog(Result result, fs::PriorityRaw priority_raw, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 7, 8)));
|
||||
|
||||
void OutputAccessLogToOnlySdCard(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
||||
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
|
||||
|
||||
class IdString {
|
||||
private:
|
||||
char m_buffer[0x20];
|
||||
private:
|
||||
const char *ToValueString(int id);
|
||||
public:
|
||||
template<typename T>
|
||||
const char *ToString(T id);
|
||||
};
|
||||
|
||||
template<typename T> requires (requires { T{}; })
|
||||
inline T DereferenceOutValue(T *out_value, Result result) {
|
||||
if (R_SUCCEEDED(result) && out_value != nullptr) {
|
||||
return *out_value;
|
||||
} else {
|
||||
return T{};
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(sizeof(size_t) == sizeof(u64));
|
||||
|
||||
}
|
||||
|
||||
/* Access log result name. */
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME __tmp_ams_fs_access_log_result
|
||||
/* Access log utils. */
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__VALUE__) ::ams::fs::impl::DereferenceOutValue(__VALUE__, AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME)
|
||||
|
||||
/* Access log components. */
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE ", size: %" PRId64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_SIZE ", read_size: %" PRIuZ ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_QUERY_SIZE ", read_size: %" PRIuZ ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_OFFSET_AND_SIZE ", offset: %" PRId64 ", size: %" PRIuZ ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID ", thread_id: %" PRIu64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT ", name: \"%s\""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_COUNT ", entry_count: %" PRId64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_BUFFER_COUNT ", entry_buffer_count: %" PRId64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_OPEN_MODE ", open_mode: 0x%" PRIX32 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH ", path: \"%s\""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_SIZE ", path: \"%s\", size: %" PRId64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH_AND_OPEN_MODE ", path: \"%s\", open_mode: 0x%" PRIX32 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_RENAME ", path: \"%s\", new_path: \"%s\""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_DIRECTORY_ENTRY_TYPE ", entry_type: %s"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_CONTENT_TYPE ", content_type: %s"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_HOST_OPTION ", mount_host_option: %s"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_ROOT_PATH ", root_path: %s"
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_APPLICATION_ID ", applicationid: 0x%" PRIx64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_BIS_PARTITION_ID ", bispartitionid: %s"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_CONTENT_STORAGE_ID ", contentstorageid: %s"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SYSTEM_DATA_ID ", systemdataid: 0x%" PRIx64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_DATA_ID ", dataid: 0x%" PRIx64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GAME_CARD_HANDLE ", gamecard_handle: 0x%" PRIX32 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GAME_CARD_PARTITION ", gamecard_partition: %s"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_IMAGE_DIRECTORY_ID ", imagedirectoryid: %s"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_PROGRAM_ID ", programid: 0x%" PRIx64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_ID ", savedataid: 0x%" PRIx64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SPACE_ID ", savedataspaceid: %s"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_OWNER_ID ", save_data_owner_id: 0x%" PRIx64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_USER_ID ", userid: 0x%016" PRIx64 "%016" PRIx64 ""
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_FLAGS ", save_data_flags: 0x%08" PRIX32 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_JOURNAL_SIZE ", save_data_journal_size: %" PRId64 ""
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SIZE ", save_data_size: %" PRId64 ""
|
||||
|
||||
/* Access log formats. */
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE ""
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_FILE(__OUT_READ_SIZE__, __OFFSET__, __SIZE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_OFFSET_AND_SIZE AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_SIZE, __OFFSET__, __SIZE__, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_READ_SIZE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION AMS_FS_IMPL_ACCESS_LOG_FORMAT_OFFSET_AND_SIZE
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_FLUSH_OPTION AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION ", write_option: Flush"
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE(__OPTION__) ((__OPTION__).HasFlushFlag() ? AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_FLUSH_OPTION : AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_FILE_SIZE(__OUT_SIZE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_SIZE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_READ_DIRECTORY(__OUT_ENTRY_COUNT__, __ENTRY_BUFFER_COUNT__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_BUFFER_COUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_COUNT, __ENTRY_BUFFER_COUNT__, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_ENTRY_COUNT__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_DIRECTORY_ENTRY_COUNT(__OUT_ENTRY_COUNT__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_ENTRY_COUNT, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_ENTRY_COUNT__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_ENTRY_TYPE(__OUT_ENTRY_TYPE__, __PATH__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH AMS_FS_IMPL_ACCESS_LOG_FORMAT_DIRECTORY_ENTRY_TYPE, __PATH__, ::ams::fs::impl::IdString().ToString(AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_ENTRY_TYPE__))
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_GET_SPACE_SIZE(__OUT_SIZE__, __NAME__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE, __NAME__, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__OUT_SIZE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_APPLICATION_PACKAGE(__NAME__, __PATH__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, (__NAME__), (__PATH__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_BIS(__NAME__, __ID__, __PATH__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_BIS_PARTITION_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH, (__NAME__), ::ams::fs::impl::IdString().ToString(__ID__), (__PATH__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_CODE(__NAME__, __PATH__, __ID__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH AMS_FS_IMPL_ACCESS_LOG_FORMAT_PROGRAM_ID, (__NAME__), (__PATH__), (__ID__).value
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_CONTENT_PATH(__NAME__, __PATH__, __TYPE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH AMS_FS_IMPL_ACCESS_LOG_FORMAT_CONTENT_TYPE, (__NAME__), (__PATH__), ::ams::fs::impl::IdString().ToString(__TYPE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_CONTENT_PROGRAM_ID(__NAME__, __ID__, __TYPE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_PROGRAM_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_CONTENT_TYPE, (__NAME__), (__ID__), ::ams::fs::impl::IdString().ToString(__TYPE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_CONTENT_PATH_AND_PROGRAM_ID(__NAME__, __PATH__, __ID__, __TYPE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH AMS_FS_IMPL_ACCESS_LOG_FORMAT_PROGRAM_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_CONTENT_TYPE, (__NAME__), (__PATH__), (__ID__).value, ::ams::fs::impl::IdString().ToString(__TYPE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_CONTENT_PATH_AND_DATA_ID(__NAME__, __PATH__, __ID__, __TYPE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_PATH AMS_FS_IMPL_ACCESS_LOG_FORMAT_DATA_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_CONTENT_TYPE, (__NAME__), (__PATH__), (__ID__).value, ::ams::fs::impl::IdString().ToString(__TYPE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_CONTENT_STORAGE(__NAME__, __ID__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_CONTENT_STORAGE_ID, (__NAME__), ::ams::fs::impl::IdString().ToString(__ID__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_DEVICE_SAVE_DATA_APPLICATION_ID(__NAME__, __ID__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_APPLICATION_ID, (__NAME__), (__ID__).value
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_GAME_CARD_PARTITION(__NAME__, __GCHANDLE__, __PARTITION__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_GAME_CARD_HANDLE AMS_FS_IMPL_ACCESS_LOG_FORMAT_GAME_CARD_PARTITION, (__NAME__), __GCHANDLE__, ::ams::fs::impl::IdString().ToString(__PARTITION__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_HOST_ROOT() \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT, (AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_HOST_ROOT_WITH_OPTION(__OPTION__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_HOST_OPTION, (AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME), ::ams::fs::impl::IdString().ToString(__OPTION__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_HOST(__NAME__, __ROOT_PATH__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_ROOT_PATH, (__NAME__), (__ROOT_PATH__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_HOST_WITH_OPTION(__NAME__, __ROOT_PATH__, __OPTION__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_ROOT_PATH AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_HOST_OPTION, (__NAME__), (__ROOT_PATH__), ::ams::fs::impl::IdString().ToString(__OPTION__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_IMAGE_DIRECTORY(__NAME__, __ID__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_IMAGE_DIRECTORY_ID, (__NAME__), ::ams::fs::impl::IdString().ToString(__ID__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_SYSTEM_DATA(__NAME__, __ID__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_SYSTEM_DATA_ID, (__NAME__), (__ID__).value
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT_SYSTEM_SAVE_DATA(__NAME__, __SPACE__, __SAVE__, __USER__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_MOUNT AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SPACE_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_USER_ID, \
|
||||
(__NAME__), ::ams::fs::impl::IdString().ToString(__SPACE__), (__SAVE__), (__USER__).data[0], (__USER__).data[1]
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_CREATE_SYSTEM_SAVE_DATA(__SPACE__, __SAVE__, __USER__, __OWNER__, __SIZE__, __JOURNAL_SIZE__, __FLAGS__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SPACE_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_USER_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_OWNER_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SIZE AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_JOURNAL_SIZE AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_FLAGS, \
|
||||
::ams::fs::impl::IdString().ToString(__SPACE__), (__SAVE__), (__USER__).data[0], (__USER__).data[1], (__OWNER__), (__SIZE__), (__JOURNAL_SIZE__), (__FLAGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_DELETE_SAVE_DATA(__SPACE__, __SAVE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SPACE_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_ID, \
|
||||
::ams::fs::impl::IdString().ToString(__SPACE__), (__SAVE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_DELETE_SYSTEM_SAVE_DATA(__SPACE__, __SAVE__, __USER__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SPACE_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_USER_ID, \
|
||||
::ams::fs::impl::IdString().ToString(__SPACE__), (__SAVE__), (__USER__).data[0], (__USER__).data[1]
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_EXTEND_SAVE_DATA(__SPACE__, __SAVE__, __SIZE__, __JOURNAL_SIZE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SPACE_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_SIZE AMS_FS_IMPL_ACCESS_LOG_FORMAT_SAVE_DATA_JOURNAL_SIZE, \
|
||||
::ams::fs::impl::IdString().ToString(__SPACE__), (__SAVE__), (__SIZE__), (__JOURNAL_SIZE__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_QUERY_MOUNT_SYSTEM_DATA_CACHE_SIZE(__ID__, __SIZE__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FORMAT_SYSTEM_DATA_ID AMS_FS_IMPL_ACCESS_LOG_FORMAT_QUERY_SIZE, (__ID__).value, AMS_FS_IMPL_ACCESS_LOG_DEREFERENCE_OUT_VALUE(__SIZE__)
|
||||
|
||||
/* Access log invocation lambdas. */
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_IMPL(__EXPR__, __HANDLE__, __ENABLED__, __NAME__, ...) \
|
||||
[&](const char *__fs_func_name_) -> Result { \
|
||||
if (!(__ENABLED__)) { \
|
||||
R_RETURN(__EXPR__); \
|
||||
} else { \
|
||||
const ::ams::os::Tick __fs_start_tick = ::ams::os::GetSystemTick(); \
|
||||
const auto AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME = (__EXPR__); \
|
||||
const ::ams::os::Tick __fs_end_tick = ::ams::os::GetSystemTick(); \
|
||||
::ams::fs::impl::OutputAccessLog(AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME, __fs_start_tick, __fs_end_tick, __fs_func_name_, __HANDLE__, __VA_ARGS__); \
|
||||
R_RETURN( AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME ); \
|
||||
} \
|
||||
}(__NAME__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_WITH_PRIORITY_IMPL(__EXPR__, __PRIORITY__, __HANDLE__, __ENABLED__, __NAME__, ...) \
|
||||
[&](const char *__fs_func_name_) -> Result { \
|
||||
if (!(__ENABLED__)) { \
|
||||
R_RETURN(__EXPR__); \
|
||||
} else { \
|
||||
const ::ams::os::Tick __fs_start_tick = ::ams::os::GetSystemTick(); \
|
||||
const auto AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME = (__EXPR__); \
|
||||
const ::ams::os::Tick __fs_end_tick = ::ams::os::GetSystemTick(); \
|
||||
::ams::fs::impl::OutputAccessLog(AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME, __PRIORITY__, __fs_start_tick, __fs_end_tick, __fs_func_name_, __HANDLE__, __VA_ARGS__); \
|
||||
R_RETURN( AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME ); \
|
||||
} \
|
||||
}(__NAME__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_EXPLICIT_IMPL(__RESULT__, __START__, __END__, __HANDLE__, __ENABLED__, __NAME__, ...) \
|
||||
[&](const char *__fs_func_name_) -> Result { \
|
||||
if (!(__ENABLED__)) { \
|
||||
R_RETURN(__RESULT__); \
|
||||
} else { \
|
||||
const auto AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME = (__RESULT__); \
|
||||
::ams::fs::impl::OutputAccessLog(AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME, __START__, __END__, __fs_func_name_, __HANDLE__, __VA_ARGS__); \
|
||||
R_RETURN( AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME ); \
|
||||
} \
|
||||
}(__NAME__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED_IMPL(__EXPR__, __ENABLED__, __NAME__, ...) \
|
||||
[&](const char *__fs_func_name_) -> Result { \
|
||||
if (!(__ENABLED__)) { \
|
||||
R_RETURN(__EXPR__); \
|
||||
} else { \
|
||||
const ::ams::os::Tick __fs_start_tick = ::ams::os::GetSystemTick(); \
|
||||
const auto AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME = (__EXPR__); \
|
||||
const ::ams::os::Tick __fs_end_tick = ::ams::os::GetSystemTick(); \
|
||||
::ams::fs::impl::OutputAccessLogUnlessResultSuccess(AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME, __fs_start_tick, __fs_end_tick, __fs_func_name_, nullptr, __VA_ARGS__); \
|
||||
R_RETURN( AMS_FS_IMPL_ACCESS_LOG_RESULT_NAME ); \
|
||||
} \
|
||||
}(__NAME__)
|
||||
|
||||
/* Access log api. */
|
||||
#define AMS_FS_IMPL_ACCESS_LOG(__EXPR__, __HANDLE__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_SYSTEM(__EXPR__, __HANDLE__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog(::ams::fs::impl::AccessLogTarget_System) && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_WITH_NAME(__EXPR__, __HANDLE__, __NAME__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), __NAME__, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_EXPLICIT(__RESULT__, __START__, __END__, __HANDLE__, __NAME__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_EXPLICIT_IMPL((__RESULT__), __START__, __END__, __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), __NAME__, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(__EXPR__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED_IMPL((__EXPR__), ::ams::fs::impl::IsEnabledAccessLog(), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
||||
|
||||
/* FS Accessor logging. */
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FS_ACCESSOR_ENABLE_IMPL(__NAME__, __ENABLED__) \
|
||||
do { \
|
||||
if (static_cast<bool>(__ENABLED__)) { \
|
||||
::ams::fs::impl::EnableFileSystemAccessorAccessLog((__NAME__)); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FS_ACCESSOR_ENABLE(__NAME__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FS_ACCESSOR_ENABLE_IMPL((__NAME__), ::ams::fs::impl::IsEnabledAccessLog(::ams::fs::impl::AccessLogTarget_Application))
|
||||
|
||||
// DEBUG
|
||||
#define AMS_FS_FORCE_ENABLE_SYSTEM_MOUNT_ACCESS_LOG
|
||||
|
||||
/* System access log api. */
|
||||
#if defined(AMS_BUILD_FOR_DEBUGGING) || defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_FS_FORCE_ENABLE_SYSTEM_MOUNT_ACCESS_LOG)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_SYSTEM_MOUNT(__EXPR__, __NAME__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), nullptr, ::ams::fs::impl::IsEnabledAccessLog(::ams::fs::impl::AccessLogTarget_System), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_SYSTEM_FS_ACCESSOR_ENABLE(__NAME__) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_FS_ACCESSOR_ENABLE_IMPL((__NAME__), ::ams::fs::impl::IsEnabledAccessLog(::ams::fs::impl::AccessLogTarget_System))
|
||||
|
||||
#else
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_SYSTEM_MOUNT(__EXPR__, __NAME__, ...) (__EXPR__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_SYSTEM_FS_ACCESSOR_ENABLE(__NAME__) static_cast<void>(0)
|
||||
|
||||
#endif
|
||||
|
||||
/* Specific utilities. */
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM(__EXPR__, __HANDLE__, __FILESYSTEM__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && (__FILESYSTEM__)->IsEnabledAccessLog(), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_FILESYSTEM_WITH_NAME(__EXPR__, __HANDLE__, __FILESYSTEM__, __NAME__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && (__FILESYSTEM__)->IsEnabledAccessLog(), __NAME__, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_MOUNT(__EXPR__, __NAME__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), nullptr, ::ams::fs::impl::IsEnabledAccessLog(::ams::fs::impl::AccessLogTarget_Application), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_MOUNT_UNLESS_R_SUCCEEDED(__EXPR__, __NAME__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED_IMPL((__EXPR__), ::ams::fs::impl::IsEnabledAccessLog(::ams::fs::impl::AccessLogTarget_Application), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
||||
|
||||
#define AMS_FS_IMPL_ACCESS_LOG_UNMOUNT(__EXPR__, __MOUNT_NAME__, ...) \
|
||||
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), nullptr, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledFileSystemAccessorAccessLog(__MOUNT_NAME__), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
|
||||
/* Delimiting of mount names. */
|
||||
constexpr inline const char ReservedMountNamePrefixCharacter = '@';
|
||||
|
||||
#define AMS_FS_IMPL_MOUNT_NAME_DELIMITER ":/"
|
||||
#define AMS_FS_IMPL_MOUNT_NAME_DELIMITER_LEN 2
|
||||
constexpr inline const char * const MountNameDelimiter = AMS_FS_IMPL_MOUNT_NAME_DELIMITER;
|
||||
|
||||
/* Filesystem names. */
|
||||
#define AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME "@Host"
|
||||
#define AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME_LEN 5
|
||||
|
||||
constexpr inline const char * const HostRootFileSystemMountName = AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME;
|
||||
|
||||
constexpr inline const char * const SdCardFileSystemMountName = "@Sdcard";
|
||||
constexpr inline const char * const GameCardFileSystemMountName = "@Gc";
|
||||
|
||||
constexpr inline size_t GameCardFileSystemMountNameSuffixLength = 1;
|
||||
|
||||
constexpr inline const char * const GameCardFileSystemMountNameUpdateSuffix = "U";
|
||||
constexpr inline const char * const GameCardFileSystemMountNameNormalSuffix = "N";
|
||||
constexpr inline const char * const GameCardFileSystemMountNameSecureSuffix = "S";
|
||||
|
||||
/* Built-in storage names. */
|
||||
constexpr inline const char * const BisCalibrationFilePartitionMountName = "@CalibFile";
|
||||
constexpr inline const char * const BisSafeModePartitionMountName = "@Safe";
|
||||
constexpr inline const char * const BisUserPartitionMountName = "@User";
|
||||
constexpr inline const char * const BisSystemPartitionMountName = "@System";
|
||||
|
||||
/* Content storage names. */
|
||||
constexpr inline const char * const ContentStorageSystemMountName = "@SystemContent";
|
||||
constexpr inline const char * const ContentStorageUserMountName = "@UserContent";
|
||||
constexpr inline const char * const ContentStorageSdCardMountName = "@SdCardContent";
|
||||
|
||||
|
||||
/* Registered update partition. */
|
||||
constexpr inline const char * const RegisteredUpdatePartitionMountName = "@RegUpdate";
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
Result QueryMountDataCacheSize(size_t *out, ncm::DataId data_id, ncm::StorageId storage_id);
|
||||
|
||||
Result MountData(const char *name, ncm::DataId data_id, ncm::StorageId storage_id);
|
||||
Result MountData(const char *name, ncm::DataId data_id, ncm::StorageId storage_id, void *cache_buffer, size_t cache_size);
|
||||
Result MountData(const char *name, ncm::DataId data_id, ncm::StorageId storage_id, void *cache_buffer, size_t cache_size, bool use_data_cache, bool use_path_cache);
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum FileSystemProxyType {
|
||||
FileSystemProxyType_Code = 0,
|
||||
FileSystemProxyType_Rom = 1,
|
||||
FileSystemProxyType_Logo = 2,
|
||||
FileSystemProxyType_Control = 3,
|
||||
FileSystemProxyType_Manual = 4,
|
||||
FileSystemProxyType_Meta = 5,
|
||||
FileSystemProxyType_Data = 6,
|
||||
FileSystemProxyType_Package = 7,
|
||||
FileSystemProxyType_UpdatePartition = 8,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/sf/sf_fs_inline_context.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
constexpr inline u8 TlsIoPriorityMask = 0x7;
|
||||
constexpr inline u8 TlsIoRecursiveCallMask = 0x8;
|
||||
|
||||
struct TlsIoValueForInheritance {
|
||||
u8 _tls_value;
|
||||
};
|
||||
|
||||
inline void SetCurrentRequestRecursive() {
|
||||
os::ThreadType * const cur_thread = os::GetCurrentThread();
|
||||
sf::SetFsInlineContext(cur_thread, TlsIoRecursiveCallMask | sf::GetFsInlineContext(cur_thread));
|
||||
}
|
||||
|
||||
inline bool IsCurrentRequestRecursive() {
|
||||
return (sf::GetFsInlineContext(os::GetCurrentThread()) & TlsIoRecursiveCallMask) != 0;
|
||||
}
|
||||
|
||||
inline TlsIoValueForInheritance GetTlsIoValueForInheritance() {
|
||||
return TlsIoValueForInheritance { sf::GetFsInlineContext(os::GetCurrentThread()) };
|
||||
}
|
||||
|
||||
inline void SetTlsIoValueForInheritance(TlsIoValueForInheritance tls_io) {
|
||||
sf::SetFsInlineContext(os::GetCurrentThread(), tls_io._tls_value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fssystem/fssystem_i_hash_256_generator.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
fssystem::IHash256GeneratorFactorySelector *GetNcaHashGeneratorFactorySelector();
|
||||
fssystem::IHash256GeneratorFactorySelector *GetSaveDataHashGeneratorFactorySelector();
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_memory_management.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
class Newable {
|
||||
public:
|
||||
static ALWAYS_INLINE void *operator new(size_t size) noexcept {
|
||||
return ::ams::fs::impl::Allocate(size);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void *operator new(size_t size, Newable *placement) noexcept {
|
||||
AMS_UNUSED(size);
|
||||
return placement;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void *operator new[](size_t size) noexcept {
|
||||
return ::ams::fs::impl::Allocate(size);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void operator delete(void *ptr, size_t size) noexcept {
|
||||
return ::ams::fs::impl::Deallocate(ptr, size);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void operator delete[](void *ptr, size_t size) noexcept {
|
||||
return ::ams::fs::impl::Deallocate(ptr, size);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_priority.hpp>
|
||||
#include <stratosphere/fs/impl/fs_fs_inline_context_utils.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
enum TlsIoPriority : u8 {
|
||||
TlsIoPriority_Normal = 0,
|
||||
TlsIoPriority_Realtime = 1,
|
||||
TlsIoPriority_Low = 2,
|
||||
TlsIoPriority_Background = 3,
|
||||
};
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
/* Ensure that TlsIo priority matches libnx priority. */
|
||||
static_assert(TlsIoPriority_Normal == static_cast<TlsIoPriority>(::FsPriority_Normal));
|
||||
static_assert(TlsIoPriority_Realtime == static_cast<TlsIoPriority>(::FsPriority_Realtime));
|
||||
static_assert(TlsIoPriority_Low == static_cast<TlsIoPriority>(::FsPriority_Low));
|
||||
static_assert(TlsIoPriority_Background == static_cast<TlsIoPriority>(::FsPriority_Background));
|
||||
#endif
|
||||
|
||||
constexpr inline Result ConvertFsPriorityToTlsIoPriority(u8 *out, PriorityRaw priority) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
switch (priority) {
|
||||
case PriorityRaw_Normal: *out = TlsIoPriority_Normal; break;
|
||||
case PriorityRaw_Realtime: *out = TlsIoPriority_Realtime; break;
|
||||
case PriorityRaw_Low: *out = TlsIoPriority_Low; break;
|
||||
case PriorityRaw_Background: *out = TlsIoPriority_Background; break;
|
||||
default: R_THROW(fs::ResultInvalidArgument());
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
constexpr inline Result ConvertTlsIoPriorityToFsPriority(PriorityRaw *out, u8 tls_io) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
switch (static_cast<TlsIoPriority>(tls_io)) {
|
||||
case TlsIoPriority_Normal: *out = PriorityRaw_Normal; break;
|
||||
case TlsIoPriority_Realtime: *out = PriorityRaw_Realtime; break;
|
||||
case TlsIoPriority_Low: *out = PriorityRaw_Low; break;
|
||||
case TlsIoPriority_Background: *out = PriorityRaw_Background; break;
|
||||
default: R_THROW(fs::ResultInvalidArgument());
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
inline u8 GetTlsIoPriority(os::ThreadType *thread) {
|
||||
return sf::GetFsInlineContext(thread) & TlsIoPriorityMask;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
/* ACCURATE_TO_VERSION: Unknown */
|
||||
bool IsAbortNeeded(Result result);
|
||||
void LogErrorMessage(Result result, const char *function);
|
||||
|
||||
}
|
||||
|
||||
#define AMS_FS_R_CHECK_ABORT_IMPL(__RESULT__, __FORCE__) \
|
||||
({ \
|
||||
if (::ams::fs::impl::IsAbortNeeded(__RESULT__) || (__FORCE__)) { \
|
||||
::ams::fs::impl::LogErrorMessage(__RESULT__, AMS_CURRENT_FUNCTION_NAME); \
|
||||
R_ABORT_UNLESS(__RESULT__); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define AMS_FS_R_TRY(__RESULT__) \
|
||||
({ \
|
||||
const ::ams::Result __tmp_fs_result = (__RESULT__); \
|
||||
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, false); \
|
||||
R_TRY(__tmp_fs_result); \
|
||||
})
|
||||
|
||||
#define AMS_FS_R_ABORT_UNLESS(__RESULT__) \
|
||||
({ \
|
||||
const ::ams::Result __tmp_fs_result = (__RESULT__); \
|
||||
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, true); \
|
||||
})
|
||||
|
||||
#define AMS_FS_ABORT_UNLESS_WITH_RESULT(__EXPR__, __RESULT__) \
|
||||
({ \
|
||||
if (!(__EXPR__)) { \
|
||||
AMS_FS_R_ABORT_UNLESS((__RESULT__)); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define AMS_FS_R_THROW(__RESULT__) \
|
||||
({ \
|
||||
const ::ams::Result __tmp_fs_result = (__RESULT__); \
|
||||
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, false); \
|
||||
R_THROW(__tmp_fs_result); \
|
||||
})
|
||||
|
||||
#define AMS_FS_R_UNLESS(__EXPR__, __RESULT__) \
|
||||
({ \
|
||||
if (!(__EXPR__)) { \
|
||||
AMS_FS_R_THROW((__RESULT__)); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define AMS_FS_R_TRY_CATCH(__EXPR__) R_TRY_CATCH(__EXPR__)
|
||||
|
||||
#define AMS_FS_R_CATCH(...) R_CATCH(__VA_ARGS__)
|
||||
|
||||
#define AMS_FS_R_END_TRY_CATCH \
|
||||
else if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
AMS_FS_R_THROW(R_CURRENT_RESULT); \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
|
||||
#define AMS_FS_R_END_TRY_CATCH_WITH_ABORT_UNLESS \
|
||||
else { \
|
||||
AMS_FS_R_ABORT_UNLESS(R_CURRENT_RESULT); \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/sm/sm_types.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
constexpr inline const sm::ServiceName FileSystemProxyServiceName = sm::ServiceName::Encode("fsp-srv");
|
||||
constexpr inline const sm::ServiceName ProgramRegistryServiceName = sm::ServiceName::Encode("fsp-pr");
|
||||
constexpr inline const sm::ServiceName FileSystemProxyForLoaderServiceName = sm::ServiceName::Encode("fsp-ldr");
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere/fs/fs_common.hpp>
|
||||
#include <stratosphere/fs/fs_istorage.hpp>
|
||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||
|
||||
namespace ams::fs::impl {
|
||||
|
||||
template<typename StorageInterface>
|
||||
class StorageServiceObjectAdapter : public ::ams::fs::impl::Newable, public ::ams::fs::IStorage {
|
||||
NON_COPYABLE(StorageServiceObjectAdapter);
|
||||
NON_MOVEABLE(StorageServiceObjectAdapter);
|
||||
private:
|
||||
sf::SharedPointer<StorageInterface> m_x;
|
||||
public:
|
||||
explicit StorageServiceObjectAdapter(sf::SharedPointer<StorageInterface> &&o) : m_x(o) { /* ... */}
|
||||
virtual ~StorageServiceObjectAdapter() { /* ... */ }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override final {
|
||||
R_RETURN(m_x->Read(offset, sf::OutNonSecureBuffer(buffer, size), static_cast<s64>(size)));
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) override final {
|
||||
R_RETURN(m_x->GetSize(out));
|
||||
}
|
||||
|
||||
virtual Result Flush() override final {
|
||||
R_RETURN(m_x->Flush());
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override final {
|
||||
R_RETURN(m_x->Write(offset, sf::InNonSecureBuffer(buffer, size), static_cast<s64>(size)));
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override final {
|
||||
R_RETURN(m_x->SetSize(size));
|
||||
}
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
|
||||
AMS_UNUSED(src, src_size);
|
||||
switch (op_id) {
|
||||
case OperationId::Invalidate:
|
||||
{
|
||||
fs::QueryRangeInfo dummy_range_info;
|
||||
R_RETURN(m_x->OperateRange(std::addressof(dummy_range_info), static_cast<s32>(op_id), offset, size));
|
||||
}
|
||||
case OperationId::QueryRange:
|
||||
{
|
||||
R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(dst_size == sizeof(fs::QueryRangeInfo), fs::ResultInvalidSize());
|
||||
|
||||
R_RETURN(m_x->OperateRange(reinterpret_cast<fs::QueryRangeInfo *>(dst), static_cast<s32>(op_id), offset, size));
|
||||
}
|
||||
default:
|
||||
{
|
||||
R_THROW(fs::ResultUnsupportedOperateRangeForStorageServiceObjectAdapter());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user