mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-13 00:26:35 +00:00
ams: finish stdio -> fs bindings for stratosphere
This commit is contained in:
parent
237b513408
commit
93004be59e
13 changed files with 67 additions and 58 deletions
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)) { /* ... */ }
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue