mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-06-27 13:32:43 +02:00
fs.mitm: Implement bis protection
This commit is contained in:
parent
19f21514d9
commit
6d85d6f835
@ -48,3 +48,6 @@
|
||||
#include "stratosphere/sm.hpp"
|
||||
#include "stratosphere/spl.hpp"
|
||||
#include "stratosphere/updater.hpp"
|
||||
|
||||
/* Include FS last. */
|
||||
#include "stratosphere/fs.hpp"
|
||||
|
25
include/stratosphere/fs.hpp
Normal file
25
include/stratosphere/fs.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "fs/fs_common.hpp"
|
||||
#include "fs/fsa/fs_ifile.hpp"
|
||||
#include "fs/fsa/fs_idirectory.hpp"
|
||||
#include "fs/fsa/fs_ifilesystem.hpp"
|
||||
#include "fs/fs_remote_filesystem.hpp"
|
||||
#include "fs/fs_istorage.hpp"
|
||||
#include "fs/fs_remote_storage.hpp"
|
||||
#include "fs/fs_query_range.hpp"
|
20
include/stratosphere/fs/fs_common.hpp
Normal file
20
include/stratosphere/fs/fs_common.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <atmosphere/common.hpp>
|
||||
#include "../os.hpp"
|
||||
#include "../ncm.hpp"
|
||||
#include "../sf.hpp"
|
23
include/stratosphere/fs/fs_directory.hpp
Normal file
23
include/stratosphere/fs/fs_directory.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
using DirectoryEntry = ::FsDirectoryEntry;
|
||||
|
||||
}
|
63
include/stratosphere/fs/fs_file.hpp
Normal file
63
include/stratosphere/fs/fs_file.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
struct ReadOption {
|
||||
u32 value;
|
||||
|
||||
static const ReadOption None;
|
||||
};
|
||||
|
||||
inline constexpr const ReadOption ReadOption::None = {FsReadOption_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(std::is_pod<ReadOption>::value && sizeof(ReadOption) == sizeof(u32));
|
||||
|
||||
struct WriteOption {
|
||||
u32 value;
|
||||
|
||||
constexpr inline bool HasFlushFlag() const {
|
||||
return this->value & FsWriteOption_Flush;
|
||||
}
|
||||
|
||||
static const WriteOption None;
|
||||
static const WriteOption Flush;
|
||||
};
|
||||
|
||||
inline constexpr const WriteOption WriteOption::None = {FsWriteOption_None};
|
||||
inline constexpr const WriteOption WriteOption::Flush = {FsWriteOption_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(std::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32));
|
||||
|
||||
}
|
51
include/stratosphere/fs/fs_filesystem.hpp
Normal file
51
include/stratosphere/fs/fs_filesystem.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
enum OpenMode {
|
||||
OpenMode_Read = ::FsOpenMode_Read,
|
||||
OpenMode_Write = ::FsOpenMode_Write,
|
||||
OpenMode_Append = ::FsOpenMode_Append,
|
||||
|
||||
OpenMode_ReadWrite = (OpenMode_Read | OpenMode_Write),
|
||||
OpenMode_All = (OpenMode_ReadWrite | OpenMode_Append),
|
||||
};
|
||||
|
||||
enum OpenDirectoryMode {
|
||||
OpenDirectoryMode_Directory = ::FsDirOpenMode_ReadDirs,
|
||||
OpenDirectoryMode_File = ::FsDirOpenMode_ReadFiles,
|
||||
|
||||
OpenDirectoryMode_All = (OpenDirectoryMode_Directory | OpenDirectoryMode_File),
|
||||
|
||||
/* TODO: Separate enum, like N? */
|
||||
OpenDirectoryMode_NotRequireFileSize = ::FsDirOpenMode_NoFileSize,
|
||||
};
|
||||
|
||||
enum DirectoryEntryType {
|
||||
DirectoryEntryType_Directory = ::FsDirEntryType_Dir,
|
||||
DirectoryEntryType_File = ::FsDirEntryType_File,
|
||||
};
|
||||
|
||||
enum CreateOption {
|
||||
CreateOption_BigFile = ::FsCreateOption_BigFile,
|
||||
};
|
||||
|
||||
using FileTimeStampRaw = ::FsTimeStampRaw;
|
||||
|
||||
}
|
106
include/stratosphere/fs/fs_istorage.hpp
Normal file
106
include/stratosphere/fs/fs_istorage.hpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "fs_file.hpp"
|
||||
#include "fs_operate_range.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
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) {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result Flush() = 0;
|
||||
|
||||
virtual Result SetSize(s64 size) {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
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) {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result OperateRange(OperationId op_id, s64 offset, s64 size) {
|
||||
return this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0);
|
||||
}
|
||||
public:
|
||||
static inline bool IsRangeValid(s64 offset, s64 size, s64 total_size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
size <= total_size &&
|
||||
offset <= (total_size - size);
|
||||
}
|
||||
|
||||
static inline bool IsRangeValid(s64 offset, size_t size, s64 total_size) {
|
||||
return IsRangeValid(offset, static_cast<s64>(size), total_size);
|
||||
}
|
||||
|
||||
static inline bool IsOffsetAndSizeValid(s64 offset, s64 size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
offset <= (offset + size);
|
||||
}
|
||||
|
||||
static inline bool IsOffsetAndSizeValid(s64 offset, size_t size) {
|
||||
return IsOffsetAndSizeValid(offset, static_cast<s64>(size));
|
||||
}
|
||||
};
|
||||
|
||||
class ReadOnlyStorageAdapter : public IStorage {
|
||||
private:
|
||||
std::shared_ptr<IStorage> shared_storage;
|
||||
std::unique_ptr<IStorage> unique_storage;
|
||||
IStorage *storage;
|
||||
public:
|
||||
ReadOnlyStorageAdapter(IStorage *s) : unique_storage(s) {
|
||||
this->storage = this->unique_storage.get();
|
||||
}
|
||||
ReadOnlyStorageAdapter(std::shared_ptr<IStorage> s) : shared_storage(s) {
|
||||
this->storage = this->shared_storage.get();
|
||||
}
|
||||
ReadOnlyStorageAdapter(std::unique_ptr<IStorage> s) : unique_storage(std::move(s)) {
|
||||
this->storage = this->unique_storage.get();
|
||||
}
|
||||
|
||||
virtual ~ReadOnlyStorageAdapter() { /* ... */ }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) {
|
||||
return this->storage->Read(offset, buffer, size);
|
||||
}
|
||||
|
||||
virtual Result Flush() {
|
||||
return this->storage->Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) {
|
||||
return this->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 {
|
||||
return this->storage->OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
28
include/stratosphere/fs/fs_operate_range.hpp
Normal file
28
include/stratosphere/fs/fs_operate_range.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
enum class OperationId : u64 {
|
||||
Clear = ::FsOperationId_Clear,
|
||||
ClearSignature = ::FsOperationId_ClearSignature,
|
||||
InvalidateCache = ::FsOperationId_InvalidateCache,
|
||||
QueryRange = ::FsOperationId_QueryRange,
|
||||
};
|
||||
|
||||
}
|
45
include/stratosphere/fs/fs_query_range.hpp
Normal file
45
include/stratosphere/fs/fs_query_range.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
struct QueryRangeInfo {
|
||||
u32 aes_ctr_key_type;
|
||||
u32 speed_emulation_type;
|
||||
u32 reserved[0x38 / sizeof(u32)];
|
||||
|
||||
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(std::is_pod<QueryRangeInfo>::value);
|
||||
static_assert(sizeof(QueryRangeInfo) == 0x40);
|
||||
static_assert(sizeof(QueryRangeInfo) == sizeof(::FsRangeInfo));
|
||||
|
||||
using FileQueryRangeInfo = QueryRangeInfo;
|
||||
using StorageQueryRangeInfo = QueryRangeInfo;
|
||||
|
||||
}
|
171
include/stratosphere/fs/fs_remote_filesystem.hpp
Normal file
171
include/stratosphere/fs/fs_remote_filesystem.hpp
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "fsa/fs_ifile.hpp"
|
||||
#include "fsa/fs_idirectory.hpp"
|
||||
#include "fsa/fs_ifilesystem.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class RemoteFile : public fsa::IFile {
|
||||
private:
|
||||
std::unique_ptr<::FsFile> base_file;
|
||||
public:
|
||||
RemoteFile(::FsFile *f) : base_file(f) { /* ... */ }
|
||||
RemoteFile(std::unique_ptr<::FsFile> f) : base_file(std::move(f)) { /* ... */ }
|
||||
RemoteFile(::FsFile f) {
|
||||
this->base_file = std::make_unique<::FsFile>(f);
|
||||
}
|
||||
|
||||
virtual ~RemoteFile() { fsFileClose(this->base_file.get()); }
|
||||
public:
|
||||
virtual Result ReadImpl(size_t *out, s64 offset, void *buffer, size_t size, const ReadOption &option) override final {
|
||||
return fsFileRead(this->base_file.get(), offset, buffer, size, option.value, out);
|
||||
}
|
||||
|
||||
virtual Result GetSizeImpl(s64 *out) override final {
|
||||
return fsFileGetSize(this->base_file.get(), reinterpret_cast<u64 *>(out));
|
||||
}
|
||||
|
||||
virtual Result FlushImpl() override final {
|
||||
return fsFileFlush(this->base_file.get());
|
||||
}
|
||||
|
||||
virtual Result WriteImpl(s64 offset, const void *buffer, size_t size, const WriteOption &option) override final {
|
||||
return fsFileWrite(this->base_file.get(), offset, buffer, size, option.value);
|
||||
}
|
||||
|
||||
virtual Result SetSizeImpl(s64 size) override final {
|
||||
return fsFileSetSize(this->base_file.get(), size);
|
||||
}
|
||||
|
||||
virtual Result OperateRangeImpl(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
|
||||
/* TODO: How should this be handled? */
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
};
|
||||
|
||||
class RemoteDirectory : public fsa::IDirectory {
|
||||
private:
|
||||
std::unique_ptr<::FsDir> base_dir;
|
||||
public:
|
||||
RemoteDirectory(::FsDir *d) : base_dir(d) { /* ... */ }
|
||||
RemoteDirectory(std::unique_ptr<::FsDir> d) : base_dir(std::move(d)) { /* ... */ }
|
||||
RemoteDirectory(::FsDir d) {
|
||||
this->base_dir = std::make_unique<::FsDir>(d);
|
||||
}
|
||||
|
||||
virtual ~RemoteDirectory() { fsDirClose(this->base_dir.get()); }
|
||||
public:
|
||||
virtual Result ReadImpl(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) override final {
|
||||
return fsDirRead(this->base_dir.get(), 0, reinterpret_cast<u64 *>(out_count), max_entries, out_entries);
|
||||
}
|
||||
|
||||
virtual Result GetEntryCountImpl(s64 *out) override final {
|
||||
return fsDirGetEntryCount(this->base_dir.get(), reinterpret_cast<u64 *>(out));
|
||||
}
|
||||
};
|
||||
|
||||
class RemoteFileSystem : public fsa::IFileSystem {
|
||||
private:
|
||||
std::unique_ptr<::FsFileSystem> base_fs;
|
||||
public:
|
||||
RemoteFileSystem(::FsFileSystem *fs) : base_fs(fs) { /* ... */ }
|
||||
RemoteFileSystem(std::unique_ptr<::FsFileSystem> fs) : base_fs(std::move(fs)) { /* ... */ }
|
||||
RemoteFileSystem(::FsFileSystem fs) {
|
||||
this->base_fs = std::make_unique<::FsFileSystem>(fs);
|
||||
}
|
||||
|
||||
virtual ~RemoteFileSystem() { fsFsClose(this->base_fs.get()); }
|
||||
public:
|
||||
virtual Result CreateFileImpl(const char *path, s64 size, int flags) override final {
|
||||
return fsFsCreateFile(this->base_fs.get(), path, size, flags);
|
||||
}
|
||||
|
||||
virtual Result DeleteFileImpl(const char *path) override final {
|
||||
return fsFsDeleteFile(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result CreateDirectoryImpl(const char *path) override final {
|
||||
return fsFsCreateDirectory(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result DeleteDirectoryImpl(const char *path) override final {
|
||||
return fsFsDeleteDirectory(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result DeleteDirectoryRecursivelyImpl(const char *path) override final {
|
||||
return fsFsDeleteDirectoryRecursively(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result RenameFileImpl(const char *old_path, const char *new_path) override final {
|
||||
return fsFsRenameFile(this->base_fs.get(), old_path, new_path);
|
||||
}
|
||||
|
||||
virtual Result RenameDirectoryImpl(const char *old_path, const char *new_path) override final {
|
||||
return fsFsRenameDirectory(this->base_fs.get(), old_path, new_path);
|
||||
}
|
||||
|
||||
virtual Result GetEntryTypeImpl(DirectoryEntryType *out, const char *path) override final {
|
||||
static_assert(sizeof(::FsDirEntryType) == sizeof(DirectoryEntryType));
|
||||
return fsFsGetEntryType(this->base_fs.get(), path, reinterpret_cast<::FsDirEntryType *>(out));
|
||||
}
|
||||
|
||||
virtual Result OpenFileImpl(std::unique_ptr<fsa::IFile> *out_file, const char *path, OpenMode mode) override final {
|
||||
FsFile f;
|
||||
R_TRY(fsFsOpenFile(this->base_fs.get(), path, mode, &f));
|
||||
|
||||
*out_file = std::make_unique<RemoteFile>(f);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result OpenDirectoryImpl(std::unique_ptr<fsa::IDirectory> *out_dir, const char *path, OpenDirectoryMode mode) override final {
|
||||
FsDir d;
|
||||
R_TRY(fsFsOpenDirectory(this->base_fs.get(), path, mode, &d));
|
||||
|
||||
*out_dir = std::make_unique<RemoteDirectory>(d);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result CommitImpl() override final {
|
||||
return fsFsCommit(this->base_fs.get());
|
||||
}
|
||||
|
||||
|
||||
virtual Result GetFreeSpaceSizeImpl(s64 *out, const char *path) {
|
||||
return fsFsGetFreeSpace(this->base_fs.get(), path, reinterpret_cast<u64 *>(out));
|
||||
}
|
||||
|
||||
virtual Result GetTotalSpaceSizeImpl(s64 *out, const char *path) {
|
||||
return fsFsGetTotalSpace(this->base_fs.get(), path, reinterpret_cast<u64 *>(out));
|
||||
}
|
||||
|
||||
virtual Result CleanDirectoryRecursivelyImpl(const char *path) {
|
||||
return fsFsCleanDirectoryRecursively(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result GetFileTimeStampRawImpl(FileTimeStampRaw *out, const char *path) {
|
||||
static_assert(sizeof(FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
|
||||
return fsFsGetFileTimeStampRaw(this->base_fs.get(), path, reinterpret_cast<::FsTimeStampRaw *>(out));
|
||||
}
|
||||
|
||||
virtual Result QueryEntryImpl(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryType query, const char *path) {
|
||||
return fsFsQueryEntry(this->base_fs.get(), dst, dst_size, src, src_size, path, static_cast<FsFileSystemQueryType>(query));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
60
include/stratosphere/fs/fs_remote_storage.hpp
Normal file
60
include/stratosphere/fs/fs_remote_storage.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "fs_istorage.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class RemoteStorage : public IStorage {
|
||||
private:
|
||||
std::unique_ptr<::FsStorage> base_storage;
|
||||
public:
|
||||
RemoteStorage(::FsStorage *s) : base_storage(s) { /* ... */ }
|
||||
RemoteStorage(std::unique_ptr<::FsStorage> s) : base_storage(std::move(s)) { /* ... */ }
|
||||
RemoteStorage(::FsStorage s) {
|
||||
this->base_storage = std::make_unique<::FsStorage>(s);
|
||||
}
|
||||
|
||||
virtual ~RemoteStorage() { fsStorageClose(this->base_storage.get()); }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
return fsStorageRead(this->base_storage.get(), offset, buffer, size);
|
||||
};
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
return fsStorageWrite(this->base_storage.get(), offset, buffer, size);
|
||||
};
|
||||
|
||||
virtual Result Flush() override {
|
||||
return fsStorageFlush(this->base_storage.get());
|
||||
};
|
||||
|
||||
virtual Result GetSize(s64 *out_size) override {
|
||||
return fsStorageGetSize(this->base_storage.get(), reinterpret_cast<u64 *>(out_size));
|
||||
};
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
return fsStorageSetSize(this->base_storage.get(), 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? */
|
||||
return fs::ResultUnsupportedOperation();
|
||||
};
|
||||
};
|
||||
|
||||
}
|
49
include/stratosphere/fs/fsa/fs_idirectory.hpp
Normal file
49
include/stratosphere/fs/fsa/fs_idirectory.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../fs_common.hpp"
|
||||
#include "../fs_directory.hpp"
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
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;
|
||||
return ResultSuccess();
|
||||
}
|
||||
R_UNLESS(out_entries != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(max_entries > 0, fs::ResultInvalidArgument());
|
||||
return this->ReadImpl(out_count, out_entries, max_entries);
|
||||
}
|
||||
|
||||
Result GetEntryCount(s64 *out) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetEntryCountImpl(out);
|
||||
}
|
||||
protected:
|
||||
/* ...? */
|
||||
private:
|
||||
virtual Result ReadImpl(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) = 0;
|
||||
virtual Result GetEntryCountImpl(s64 *out) = 0;
|
||||
};
|
||||
|
||||
}
|
92
include/stratosphere/fs/fsa/fs_ifile.hpp
Normal file
92
include/stratosphere/fs/fsa/fs_ifile.hpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "../fs_common.hpp"
|
||||
#include "../fs_file.hpp"
|
||||
#include "../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 ReadOption &option) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
if (size == 0) {
|
||||
*out = 0;
|
||||
return ResultSuccess();
|
||||
}
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(offset >= 0, fs::ResultOutOfRange());
|
||||
const s64 signed_size = static_cast<s64>(size);
|
||||
R_UNLESS(signed_size >= 0, fs::ResultOutOfRange());
|
||||
R_UNLESS((std::numeric_limits<s64>::max() - offset) >= signed_size, fs::ResultOutOfRange());
|
||||
return this->ReadImpl(out, offset, buffer, size, option);
|
||||
}
|
||||
|
||||
Result Read(size_t *out, s64 offset, void *buffer, size_t size) {
|
||||
return this->Read(out, offset, buffer, size, ReadOption::None);
|
||||
}
|
||||
|
||||
Result GetSize(s64 *out) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetSizeImpl(out);
|
||||
}
|
||||
|
||||
Result Flush() {
|
||||
return this->FlushImpl();
|
||||
}
|
||||
|
||||
Result Write(s64 offset, const void *buffer, size_t size, const WriteOption &option) {
|
||||
if (size == 0) {
|
||||
if (option.HasFlushFlag()) {
|
||||
R_TRY(this->Flush());
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(offset >= 0, fs::ResultOutOfRange());
|
||||
const s64 signed_size = static_cast<s64>(size);
|
||||
R_UNLESS(signed_size >= 0, fs::ResultOutOfRange());
|
||||
R_UNLESS((std::numeric_limits<s64>::max() - offset) >= signed_size, fs::ResultOutOfRange());
|
||||
return this->WriteImpl(offset, buffer, size, option);
|
||||
}
|
||||
|
||||
Result SetSize(s64 size) {
|
||||
R_UNLESS(size >= 0, fs::ResultOutOfRange());
|
||||
return this->SetSizeImpl(size);
|
||||
}
|
||||
|
||||
Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) {
|
||||
return this->OperateRangeImpl(dst, dst_size, op_id, offset, size, src, src_size);
|
||||
}
|
||||
|
||||
Result OperateRange(OperationId op_id, s64 offset, s64 size) {
|
||||
return this->OperateRangeImpl(nullptr, 0, op_id, offset, size, nullptr, 0);
|
||||
}
|
||||
protected:
|
||||
/* ...? */
|
||||
private:
|
||||
virtual Result ReadImpl(size_t *out, s64 offset, void *buffer, size_t size, const ReadOption &option) = 0;
|
||||
virtual Result GetSizeImpl(s64 *out) = 0;
|
||||
virtual Result FlushImpl() = 0;
|
||||
virtual Result WriteImpl(s64 offset, const void *buffer, size_t size, const WriteOption &option) = 0;
|
||||
virtual Result SetSizeImpl(s64 size) = 0;
|
||||
virtual Result OperateRangeImpl(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) = 0;
|
||||
};
|
||||
|
||||
}
|
191
include/stratosphere/fs/fsa/fs_ifilesystem.hpp
Normal file
191
include/stratosphere/fs/fsa/fs_ifilesystem.hpp
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../fs_common.hpp"
|
||||
#include "../fs_filesystem.hpp"
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
class IFile;
|
||||
class IDirectory;
|
||||
|
||||
enum class QueryType {
|
||||
SetArchiveBit = FsFileSystemQueryType_SetArchiveBit
|
||||
};
|
||||
|
||||
class IFileSystem {
|
||||
public:
|
||||
virtual ~IFileSystem() { /* ... */ }
|
||||
|
||||
Result CreateFile(const char *path, s64 size, int option) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(size >= 0, fs::ResultOutOfRange());
|
||||
return this->CreateFileImpl(path, size, option);
|
||||
}
|
||||
|
||||
Result CreateFile(const char *path, s64 size) {
|
||||
return this->CreateFile(path, size, 0);
|
||||
}
|
||||
|
||||
Result DeleteFile(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->DeleteFileImpl(path);
|
||||
}
|
||||
|
||||
Result CreateDirectory(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->CreateDirectoryImpl(path);
|
||||
}
|
||||
|
||||
Result DeleteDirectory(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->DeleteDirectoryImpl(path);
|
||||
}
|
||||
|
||||
Result DeleteDirectoryRecursively(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->DeleteDirectoryRecursivelyImpl(path);
|
||||
}
|
||||
|
||||
Result RenameFile(const char *old_path, const char *new_path) {
|
||||
R_UNLESS(old_path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(new_path != nullptr, fs::ResultInvalidPath());
|
||||
return this->RenameFileImpl(old_path, new_path);
|
||||
}
|
||||
|
||||
Result RenameDirectory(const char *old_path, const char *new_path) {
|
||||
R_UNLESS(old_path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(new_path != nullptr, fs::ResultInvalidPath());
|
||||
return this->RenameDirectoryImpl(old_path, new_path);
|
||||
}
|
||||
|
||||
Result GetEntryType(DirectoryEntryType *out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetEntryTypeImpl(out, path);
|
||||
}
|
||||
|
||||
Result OpenFile(std::unique_ptr<IFile> *out_file, const char *path, OpenMode mode) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out_file != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS((mode & OpenMode_ReadWrite) != 0, fs::ResultInvalidArgument());
|
||||
R_UNLESS((mode & ~OpenMode_All) == 0, fs::ResultInvalidArgument());
|
||||
return this->OpenFileImpl(out_file, path, mode);
|
||||
}
|
||||
|
||||
Result OpenDirectory(std::unique_ptr<IDirectory> *out_dir, const char *path, OpenDirectoryMode mode) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out_dir != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS((mode & OpenDirectoryMode_All) != 0, fs::ResultInvalidArgument());
|
||||
R_UNLESS((mode & ~OpenDirectoryMode_All) == 0, fs::ResultInvalidArgument());
|
||||
return this->OpenDirectoryImpl(out_dir, path, mode);
|
||||
}
|
||||
|
||||
Result Commit() {
|
||||
return this->CommitImpl();
|
||||
}
|
||||
|
||||
Result GetFreeSpaceSize(s64 *out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetFreeSpaceSizeImpl(out, path);
|
||||
}
|
||||
|
||||
Result GetTotalSpaceSize(s64 *out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetTotalSpaceSizeImpl(out, path);
|
||||
}
|
||||
|
||||
Result CleanDirectoryRecursively(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->CleanDirectoryRecursivelyImpl(path);
|
||||
}
|
||||
|
||||
Result GetFileTimeStampRaw(FileTimeStampRaw *out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetFileTimeStampRawImpl(out, path);
|
||||
}
|
||||
|
||||
Result QueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, QueryType query, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->QueryEntryImpl(dst, dst_size, src, src_size, query, path);
|
||||
}
|
||||
|
||||
/* These aren't accessible as commands. */
|
||||
|
||||
Result CommitProvisionally(s64 counter) {
|
||||
return this->CommitProvisionallyImpl(counter);
|
||||
}
|
||||
|
||||
Result Rollback() {
|
||||
return this->RollbackImpl();
|
||||
}
|
||||
|
||||
Result Flush() {
|
||||
return this->FlushImpl();
|
||||
}
|
||||
|
||||
protected:
|
||||
/* ...? */
|
||||
private:
|
||||
virtual Result CreateFileImpl(const char *path, s64 size, int flags) = 0;
|
||||
virtual Result DeleteFileImpl(const char *path) = 0;
|
||||
virtual Result CreateDirectoryImpl(const char *path) = 0;
|
||||
virtual Result DeleteDirectoryImpl(const char *path) = 0;
|
||||
virtual Result DeleteDirectoryRecursivelyImpl(const char *path) = 0;
|
||||
virtual Result RenameFileImpl(const char *old_path, const char *new_path) = 0;
|
||||
virtual Result RenameDirectoryImpl(const char *old_path, const char *new_path) = 0;
|
||||
virtual Result GetEntryTypeImpl(DirectoryEntryType *out, const char *path) = 0;
|
||||
virtual Result OpenFileImpl(std::unique_ptr<IFile> *out_file, const char *path, OpenMode mode) = 0;
|
||||
virtual Result OpenDirectoryImpl(std::unique_ptr<IDirectory> *out_dir, const char *path, OpenDirectoryMode mode) = 0;
|
||||
virtual Result CommitImpl() = 0;
|
||||
|
||||
virtual Result GetFreeSpaceSizeImpl(s64 *out, const char *path) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result GetTotalSpaceSizeImpl(s64 *out, const char *path) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result CleanDirectoryRecursivelyImpl(const char *path) = 0;
|
||||
|
||||
virtual Result GetFileTimeStampRawImpl(FileTimeStampRaw *out, const char *path) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result QueryEntryImpl(char *dst, size_t dst_size, const char *src, size_t src_size, QueryType query, const char *path) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
/* These aren't accessible as commands. */
|
||||
virtual Result CommitProvisionallyImpl(s64 counter) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result RollbackImpl() {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result FlushImpl() {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -51,6 +51,8 @@ namespace ams::sf::cmif {
|
||||
explicit Domain(ServerDomainManager *m) : manager(m) { /* ... */ }
|
||||
~Domain();
|
||||
|
||||
void DestroySelf();
|
||||
|
||||
virtual ServerDomainBase *GetServerDomain() override final {
|
||||
return static_cast<ServerDomainBase *>(this);
|
||||
}
|
||||
@ -116,10 +118,9 @@ namespace ams::sf::cmif {
|
||||
}
|
||||
return new (storage) Domain(this);
|
||||
}
|
||||
|
||||
inline void FreeDomainServiceObject(DomainServiceObject *object) {
|
||||
static_cast<Domain *>(object)->~Domain();
|
||||
this->FreeDomain(object);
|
||||
public:
|
||||
static void DestroyDomainServiceObject(DomainServiceObject *obj) {
|
||||
static_cast<Domain *>(obj)->DestroySelf();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -103,6 +103,8 @@ namespace ams::sf::cmif {
|
||||
|
||||
class MitmDomainServiceObject : public DomainServiceObject{};
|
||||
|
||||
static_assert(sizeof(DomainServiceObject) == sizeof(MitmDomainServiceObject));
|
||||
|
||||
template<>
|
||||
struct ServiceDispatchTraits<DomainServiceObject> {
|
||||
static_assert(std::is_base_of<sf::IServiceObject, DomainServiceObject>::value, "DomainServiceObject must derive from sf::IServiceObject");
|
||||
|
@ -32,10 +32,6 @@ namespace ams::sf::hipc {
|
||||
inline cmif::DomainServiceObject *AllocateDomainServiceObject() {
|
||||
return cmif::ServerDomainManager::AllocateDomainServiceObject();
|
||||
}
|
||||
|
||||
inline void FreeDomainServiceObject(cmif::DomainServiceObject *object) {
|
||||
cmif::ServerDomainManager::FreeDomainServiceObject(object);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ namespace ams::exosphere {
|
||||
namespace {
|
||||
|
||||
inline Result GetRcmBugPatched(bool *out) {
|
||||
u64 tmp;
|
||||
u64 tmp = 0;
|
||||
R_TRY(spl::smc::ConvertResult(spl::smc::GetConfig(&tmp, 1, SplConfigItem_ExosphereHasRcmBugPatch)));
|
||||
*out = (tmp != 0);
|
||||
return ResultSuccess();
|
||||
|
@ -31,6 +31,12 @@ namespace ams::sf::cmif {
|
||||
}
|
||||
}
|
||||
|
||||
void ServerDomainManager::Domain::DestroySelf() {
|
||||
ServerDomainManager *manager = this->manager;
|
||||
this->~Domain();
|
||||
manager->FreeDomain(this);
|
||||
}
|
||||
|
||||
Result ServerDomainManager::Domain::ReserveIds(DomainObjectId *out_ids, size_t count) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
Entry *entry = this->manager->entry_manager.AllocateEntry();
|
||||
|
@ -63,7 +63,7 @@ namespace ams::sf::hipc {
|
||||
/* Allocate a domain. */
|
||||
auto domain = this->manager->AllocateDomainServiceObject();
|
||||
R_UNLESS(domain, sf::hipc::ResultOutOfDomains());
|
||||
auto domain_guard = SCOPE_GUARD { this->manager->FreeDomainServiceObject(domain); };
|
||||
auto domain_guard = SCOPE_GUARD { cmif::ServerDomainManager::DestroyDomainServiceObject(static_cast<cmif::DomainServiceObject *>(domain)); };
|
||||
|
||||
cmif::DomainObjectId object_id = cmif::InvalidDomainObjectId;
|
||||
|
||||
@ -80,8 +80,8 @@ namespace ams::sf::hipc {
|
||||
|
||||
/* Create new object. */
|
||||
cmif::MitmDomainServiceObject *domain_ptr = static_cast<cmif::MitmDomainServiceObject *>(domain);
|
||||
new_holder = cmif::ServiceObjectHolder(std::move(std::shared_ptr<cmif::MitmDomainServiceObject>(domain_ptr, [&](cmif::MitmDomainServiceObject *obj) {
|
||||
this->manager->FreeDomainServiceObject(domain);
|
||||
new_holder = cmif::ServiceObjectHolder(std::move(std::shared_ptr<cmif::MitmDomainServiceObject>(domain_ptr, [](cmif::MitmDomainServiceObject *obj) {
|
||||
cmif::ServerDomainManager::DestroyDomainServiceObject(static_cast<cmif::DomainServiceObject *>(obj));
|
||||
})));
|
||||
} else {
|
||||
/* We're not a mitm session. Reserve a new object in the domain. */
|
||||
@ -89,8 +89,8 @@ namespace ams::sf::hipc {
|
||||
|
||||
/* Create new object. */
|
||||
cmif::DomainServiceObject *domain_ptr = static_cast<cmif::DomainServiceObject *>(domain);
|
||||
new_holder = cmif::ServiceObjectHolder(std::move(std::shared_ptr<cmif::DomainServiceObject>(domain_ptr, [&](cmif::DomainServiceObject *obj) {
|
||||
this->manager->FreeDomainServiceObject(domain);
|
||||
new_holder = cmif::ServiceObjectHolder(std::move(std::shared_ptr<cmif::DomainServiceObject>(domain_ptr, [](cmif::DomainServiceObject *obj) {
|
||||
cmif::ServerDomainManager::DestroyDomainServiceObject(static_cast<cmif::DomainServiceObject *>(obj));
|
||||
})));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user