mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-28 20:40:24 +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 <stratosphere/fs/fs_file.hpp>
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
class IFile;
|
||||
|
||||
}
|
||||
|
||||
namespace ams::util::ini {
|
||||
|
||||
/* Ini handler type. */
|
||||
|
@ -26,6 +32,6 @@ namespace ams::util::ini {
|
|||
/* Utilities for dealing with INI file configuration. */
|
||||
int ParseString(const char *ini_str, 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) {
|
||||
FileContext *ctx = static_cast<FileContext *>(stream);
|
||||
|
||||
|
@ -64,6 +74,38 @@ namespace ams::util::ini {
|
|||
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. */
|
||||
|
@ -76,14 +118,9 @@ namespace ams::util::ini {
|
|||
return ini_parse_stream(ini_reader_file_handle, &ctx, h, user_ctx);
|
||||
}
|
||||
|
||||
int ParseFile(const char *path, void *user_ctx, Handler h) {
|
||||
fs::FileHandle file;
|
||||
if (R_FAILED(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read))) {
|
||||
return -1;
|
||||
}
|
||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||
|
||||
return ParseFile(file, user_ctx, h);
|
||||
int ParseFile(fs::fsa::IFile *file, void *user_ctx, Handler h) {
|
||||
IFileContext ctx(file);
|
||||
return ini_parse_stream(ini_reader_ifile, &ctx, h, user_ctx);
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,6 @@ extern "C" {
|
|||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x1000000
|
||||
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)};
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
} else {
|
||||
/* 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);
|
||||
|
@ -220,7 +220,7 @@ namespace ams::mitm::fs {
|
|||
}
|
||||
|
||||
/* 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. */
|
||||
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 {
|
||||
private:
|
||||
ams::fs::ReadOnlyFileSystemAdapter fs_1;
|
||||
ams::fs::ReadOnlyFileSystemAdapter fs_2;
|
||||
ams::fs::ReadOnlyFileSystem fs_1;
|
||||
ams::fs::ReadOnlyFileSystem fs_2;
|
||||
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)) { /* ... */ }
|
||||
|
||||
|
|
|
@ -290,15 +290,17 @@ namespace ams::settings::fwdbg {
|
|||
|
||||
Result LoadSdCardKeyValueStore() {
|
||||
/* Open file. */
|
||||
FsFile config_file;
|
||||
if (R_FAILED(ams::mitm::fs::OpenAtmosphereSdFile(&config_file, "/config/system_settings.ini", fs::OpenMode_Read))) {
|
||||
/* It's okay if the file isn't readable/present, because we already loaded defaults. */
|
||||
return ResultSuccess();
|
||||
/* It's okay if the file isn't readable/present, because we already loaded defaults. */
|
||||
std::unique_ptr<ams::fs::fsa::IFile> file;
|
||||
{
|
||||
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();
|
||||
util::ini::ParseFile(&config_file, &parse_result, SystemSettingsIniHandler);
|
||||
util::ini::ParseFile(file.get(), &parse_result, SystemSettingsIniHandler);
|
||||
R_TRY(parse_result);
|
||||
|
||||
return ResultSuccess();
|
||||
|
|
|
@ -20,7 +20,6 @@ extern "C" {
|
|||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x2000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
|
|
|
@ -22,7 +22,6 @@ extern "C" {
|
|||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x4000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
|
|
|
@ -21,7 +21,6 @@ extern "C" {
|
|||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
/* TODO: Evaluate how much this can be reduced by. */
|
||||
#define INNER_HEAP_SIZE 0x20000
|
||||
|
|
|
@ -23,7 +23,6 @@ extern "C" {
|
|||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x240000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
|
|
|
@ -22,43 +22,15 @@ namespace ams::ldr {
|
|||
/* Global cache. */
|
||||
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. */
|
||||
bool HasLaunchedProgram(ncm::ProgramId program_id) {
|
||||
if (IsTrackableSystemProgramId(program_id)) {
|
||||
return HasLaunchedSystemProgram(ncm::SystemProgramId{program_id.value});
|
||||
} else {
|
||||
return g_launched_programs.find(program_id.value) != g_launched_programs.end();
|
||||
}
|
||||
return g_launched_programs.find(program_id.value) != g_launched_programs.end();
|
||||
}
|
||||
|
||||
void SetLaunchedProgram(ncm::ProgramId program_id) {
|
||||
if (IsTrackableSystemProgramId(program_id)) {
|
||||
SetLaunchedSystemProgram(ncm::SystemProgramId{program_id.value});
|
||||
} else {
|
||||
g_launched_programs.insert(static_cast<u64>(program_id));
|
||||
}
|
||||
g_launched_programs.insert(program_id.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ extern "C" {
|
|||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x8000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
|
@ -82,7 +81,6 @@ void __appInit(void) {
|
|||
|
||||
void __appExit(void) {
|
||||
/* Cleanup services. */
|
||||
fsdevUnmountAll();
|
||||
fsldrExit();
|
||||
lr::Finalize();
|
||||
fsExit();
|
||||
|
|
|
@ -21,7 +21,6 @@ extern "C" {
|
|||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x4000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
|
|
Loading…
Reference in a new issue