ams: finish stdio -> fs bindings for stratosphere

This commit is contained in:
Michael Scire 2020-03-09 03:58:02 -07:00
parent 237b513408
commit 93004be59e
13 changed files with 67 additions and 58 deletions

View file

@ -18,6 +18,12 @@
#include <vapours.hpp> #include <vapours.hpp>
#include <stratosphere/fs/fs_file.hpp> #include <stratosphere/fs/fs_file.hpp>
namespace ams::fs::fsa {
class IFile;
}
namespace ams::util::ini { namespace ams::util::ini {
/* Ini handler type. */ /* Ini handler type. */
@ -26,6 +32,6 @@ namespace ams::util::ini {
/* Utilities for dealing with INI file configuration. */ /* Utilities for dealing with INI file configuration. */
int ParseString(const char *ini_str, void *user_ctx, Handler h); int ParseString(const char *ini_str, void *user_ctx, Handler h);
int ParseFile(fs::FileHandle file, void *user_ctx, Handler h); int ParseFile(fs::FileHandle file, void *user_ctx, Handler h);
int ParseFile(const char *path, void *user_ctx, Handler h); int ParseFile(fs::fsa::IFile *file, void *user_ctx, Handler h);
} }

View file

@ -34,6 +34,16 @@ namespace ams::util::ini {
} }
}; };
struct IFileContext {
fs::fsa::IFile *file;
s64 offset;
s64 num_left;
explicit IFileContext(fs::fsa::IFile *f) : file(f), offset(0) {
R_ABORT_UNLESS(file->GetSize(std::addressof(this->num_left)));
}
};
char *ini_reader_file_handle(char *str, int num, void *stream) { char *ini_reader_file_handle(char *str, int num, void *stream) {
FileContext *ctx = static_cast<FileContext *>(stream); FileContext *ctx = static_cast<FileContext *>(stream);
@ -64,6 +74,38 @@ namespace ams::util::ini {
return str; return str;
} }
char *ini_reader_ifile(char *str, int num, void *stream) {
IFileContext *ctx = static_cast<IFileContext *>(stream);
if (ctx->num_left == 0 || num < 2) {
return nullptr;
}
/* Read as many bytes as we can. */
s64 cur_read = std::min<s64>(num - 1, ctx->num_left);
size_t read;
R_ABORT_UNLESS(ctx->file->Read(std::addressof(read), ctx->offset, str, cur_read, fs::ReadOption()));
AMS_ABORT_UNLESS(static_cast<s64>(read) == cur_read);
/* Only "read" up to the first \n. */
size_t offset = cur_read;
for (auto i = 0; i < cur_read; i++) {
if (str[i] == '\n') {
offset = i + 1;
break;
}
}
/* Ensure null termination. */
str[offset] = '\0';
/* Update context. */
ctx->offset += offset;
ctx->num_left -= offset;
return str;
}
} }
/* Utilities for dealing with INI file configuration. */ /* Utilities for dealing with INI file configuration. */
@ -76,14 +118,9 @@ namespace ams::util::ini {
return ini_parse_stream(ini_reader_file_handle, &ctx, h, user_ctx); return ini_parse_stream(ini_reader_file_handle, &ctx, h, user_ctx);
} }
int ParseFile(const char *path, void *user_ctx, Handler h) { int ParseFile(fs::fsa::IFile *file, void *user_ctx, Handler h) {
fs::FileHandle file; IFileContext ctx(file);
if (R_FAILED(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read))) { return ini_parse_stream(ini_reader_ifile, &ctx, h, user_ctx);
return -1;
}
ON_SCOPE_EXIT { fs::CloseFile(file); };
return ParseFile(file, user_ctx, h);
} }
} }

View file

@ -22,7 +22,6 @@ extern "C" {
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1; u32 __nx_fs_num_sessions = 1;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x1000000 #define INNER_HEAP_SIZE 0x1000000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;

View file

@ -85,7 +85,7 @@ namespace ams::mitm::fs {
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(&sd_fs.s)}; const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(&sd_fs.s)};
std::unique_ptr<fs::fsa::IFileSystem> sd_ifs = std::make_unique<fs::RemoteFileSystem>(sd_fs); std::unique_ptr<fs::fsa::IFileSystem> sd_ifs = std::make_unique<fs::RemoteFileSystem>(sd_fs);
out.SetValue(std::make_shared<IFileSystemInterface>(std::make_shared<fs::ReadOnlyFileSystemAdapter>(std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_ifs), AtmosphereHblWebContentDir)), false), target_object_id); out.SetValue(std::make_shared<IFileSystemInterface>(std::make_shared<fs::ReadOnlyFileSystem>(std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_ifs), AtmosphereHblWebContentDir)), false), target_object_id);
return ResultSuccess(); return ResultSuccess();
} }
@ -126,7 +126,7 @@ namespace ams::mitm::fs {
new_fs = std::make_shared<ReadOnlyLayeredFileSystem>(std::move(subdir_fs), std::make_unique<fs::RemoteFileSystem>(base_fs)); new_fs = std::make_shared<ReadOnlyLayeredFileSystem>(std::move(subdir_fs), std::make_unique<fs::RemoteFileSystem>(base_fs));
} else { } else {
/* Without an existing FS, just make a read only adapter to the subdirectory. */ /* Without an existing FS, just make a read only adapter to the subdirectory. */
new_fs = std::make_shared<fs::ReadOnlyFileSystemAdapter>(std::move(subdir_fs)); new_fs = std::make_shared<fs::ReadOnlyFileSystem>(std::move(subdir_fs));
} }
out.SetValue(std::make_shared<IFileSystemInterface>(std::move(new_fs), false), target_object_id); out.SetValue(std::make_shared<IFileSystemInterface>(std::move(new_fs), false), target_object_id);
@ -220,7 +220,7 @@ namespace ams::mitm::fs {
} }
/* Ensure the directory exists. */ /* Ensure the directory exists. */
R_TRY(fssystem::EnsureDirectoryExistsRecursively(sd_ifs.get(), save_dir_path)); R_TRY(fssystem::EnsureDirectoryRecursively(sd_ifs.get(), save_dir_path));
/* Create directory savedata filesystem. */ /* Create directory savedata filesystem. */
std::unique_ptr<fs::fsa::IFileSystem> subdir_fs = std::make_unique<fssystem::SubDirectoryFileSystem>(sd_ifs, save_dir_path); std::unique_ptr<fs::fsa::IFileSystem> subdir_fs = std::make_unique<fssystem::SubDirectoryFileSystem>(sd_ifs, save_dir_path);

View file

@ -20,8 +20,8 @@ namespace ams::mitm::fs {
class ReadOnlyLayeredFileSystem : public ams::fs::fsa::IFileSystem { class ReadOnlyLayeredFileSystem : public ams::fs::fsa::IFileSystem {
private: private:
ams::fs::ReadOnlyFileSystemAdapter fs_1; ams::fs::ReadOnlyFileSystem fs_1;
ams::fs::ReadOnlyFileSystemAdapter fs_2; ams::fs::ReadOnlyFileSystem fs_2;
public: public:
explicit ReadOnlyLayeredFileSystem(std::unique_ptr<ams::fs::fsa::IFileSystem> a, std::unique_ptr<ams::fs::fsa::IFileSystem> b) : fs_1(std::move(a)), fs_2(std::move(b)) { /* ... */ } explicit ReadOnlyLayeredFileSystem(std::unique_ptr<ams::fs::fsa::IFileSystem> a, std::unique_ptr<ams::fs::fsa::IFileSystem> b) : fs_1(std::move(a)), fs_2(std::move(b)) { /* ... */ }

View file

@ -290,15 +290,17 @@ namespace ams::settings::fwdbg {
Result LoadSdCardKeyValueStore() { Result LoadSdCardKeyValueStore() {
/* Open file. */ /* Open file. */
FsFile config_file; /* It's okay if the file isn't readable/present, because we already loaded defaults. */
if (R_FAILED(ams::mitm::fs::OpenAtmosphereSdFile(&config_file, "/config/system_settings.ini", fs::OpenMode_Read))) { std::unique_ptr<ams::fs::fsa::IFile> file;
/* It's okay if the file isn't readable/present, because we already loaded defaults. */ {
return ResultSuccess(); FsFile f;
R_SUCCEED_IF(R_FAILED(ams::mitm::fs::OpenAtmosphereSdFile(std::addressof(f), "/config/system_settings.ini", fs::OpenMode_Read)));
file = std::make_unique<ams::fs::RemoteFile>(f);
} }
ON_SCOPE_EXIT { fsFileClose(&config_file); }; AMS_ABORT_UNLESS(file != nullptr);
Result parse_result = ResultSuccess(); Result parse_result = ResultSuccess();
util::ini::ParseFile(&config_file, &parse_result, SystemSettingsIniHandler); util::ini::ParseFile(file.get(), &parse_result, SystemSettingsIniHandler);
R_TRY(parse_result); R_TRY(parse_result);
return ResultSuccess(); return ResultSuccess();

View file

@ -20,7 +20,6 @@ extern "C" {
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1; u32 __nx_fs_num_sessions = 1;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x2000 #define INNER_HEAP_SIZE 0x2000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;

View file

@ -22,7 +22,6 @@ extern "C" {
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1; u32 __nx_fs_num_sessions = 1;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x4000 #define INNER_HEAP_SIZE 0x4000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;

View file

@ -21,7 +21,6 @@ extern "C" {
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1; u32 __nx_fs_num_sessions = 1;
u32 __nx_fsdev_direntry_cache_size = 1;
/* TODO: Evaluate how much this can be reduced by. */ /* TODO: Evaluate how much this can be reduced by. */
#define INNER_HEAP_SIZE 0x20000 #define INNER_HEAP_SIZE 0x20000

View file

@ -23,7 +23,6 @@ extern "C" {
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1; u32 __nx_fs_num_sessions = 1;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x240000 #define INNER_HEAP_SIZE 0x240000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;

View file

@ -22,43 +22,15 @@ namespace ams::ldr {
/* Global cache. */ /* Global cache. */
std::set<u64> g_launched_programs; std::set<u64> g_launched_programs;
constexpr size_t NumSystemProgramIds = ncm::SystemProgramId::End.value - ncm::SystemProgramId::Start.value + 1;
static_assert(util::IsPowerOfTwo(NumSystemProgramIds));
static_assert(util::IsAligned(NumSystemProgramIds, BITSIZEOF(u64)));
bool IsTrackableSystemProgramId(ncm::ProgramId program_id) {
return ncm::SystemProgramId::Start <= program_id && program_id <= ncm::SystemProgramId::End;
}
u64 g_system_launch_records[NumSystemProgramIds / BITSIZEOF(u64)];
void SetLaunchedSystemProgram(ncm::SystemProgramId program_id) {
const u64 val = program_id.value - ncm::SystemProgramId::Start.value;
g_system_launch_records[val / BITSIZEOF(u64)] |= (1ul << (val % BITSIZEOF(u64)));
}
bool HasLaunchedSystemProgram(ncm::SystemProgramId program_id) {
const u64 val = program_id.value - ncm::SystemProgramId::Start.value;
return (g_system_launch_records[val / BITSIZEOF(u64)] & (1ul << (val % BITSIZEOF(u64)))) != 0;
}
} }
/* Launch Record API. */ /* Launch Record API. */
bool HasLaunchedProgram(ncm::ProgramId program_id) { bool HasLaunchedProgram(ncm::ProgramId program_id) {
if (IsTrackableSystemProgramId(program_id)) { return g_launched_programs.find(program_id.value) != g_launched_programs.end();
return HasLaunchedSystemProgram(ncm::SystemProgramId{program_id.value});
} else {
return g_launched_programs.find(program_id.value) != g_launched_programs.end();
}
} }
void SetLaunchedProgram(ncm::ProgramId program_id) { void SetLaunchedProgram(ncm::ProgramId program_id) {
if (IsTrackableSystemProgramId(program_id)) { g_launched_programs.insert(program_id.value);
SetLaunchedSystemProgram(ncm::SystemProgramId{program_id.value});
} else {
g_launched_programs.insert(static_cast<u64>(program_id));
}
} }
} }

View file

@ -21,7 +21,6 @@ extern "C" {
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1; u32 __nx_fs_num_sessions = 1;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x8000 #define INNER_HEAP_SIZE 0x8000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;
@ -82,7 +81,6 @@ void __appInit(void) {
void __appExit(void) { void __appExit(void) {
/* Cleanup services. */ /* Cleanup services. */
fsdevUnmountAll();
fsldrExit(); fsldrExit();
lr::Finalize(); lr::Finalize();
fsExit(); fsExit();

View file

@ -21,7 +21,6 @@ extern "C" {
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1; u32 __nx_fs_num_sessions = 1;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x4000 #define INNER_HEAP_SIZE 0x4000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;