ams_mitm: implement layeredfs
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
|
||||
namespace ams::mitm::fs {
|
||||
|
||||
using namespace ams::fs;
|
||||
|
||||
namespace {
|
||||
|
||||
/* Globals. */
|
||||
@@ -46,6 +48,18 @@ namespace ams::mitm::fs {
|
||||
}
|
||||
}
|
||||
|
||||
void FormatAtmosphereSdPath(char *dst_path, size_t dst_path_size, ncm::ProgramId program_id, const char *subdir, const char *src_path) {
|
||||
if (src_path[0] == '/') {
|
||||
std::snprintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx/%s%s", static_cast<u64>(program_id), subdir, src_path);
|
||||
} else {
|
||||
std::snprintf(dst_path, dst_path_size, "/atmosphere/contents/%016lx/%s/%s", static_cast<u64>(program_id), subdir, src_path);
|
||||
}
|
||||
}
|
||||
|
||||
void FormatAtmosphereRomfsPath(char *dst_path, size_t dst_path_size, ncm::ProgramId program_id, const char *src_path) {
|
||||
return FormatAtmosphereSdPath(dst_path, dst_path_size, program_id, "romfs", src_path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void OpenGlobalSdCardFileSystem() {
|
||||
@@ -69,4 +83,95 @@ namespace ams::mitm::fs {
|
||||
return OpenSdFile(out, fixed_path, mode);
|
||||
}
|
||||
|
||||
Result OpenAtmosphereSdRomfsFile(FsFile *out, ncm::ProgramId program_id, const char *path, u32 mode) {
|
||||
char fixed_path[FS_MAX_PATH];
|
||||
FormatAtmosphereRomfsPath(fixed_path, sizeof(fixed_path), program_id, path);
|
||||
return OpenSdFile(out, fixed_path, mode);
|
||||
}
|
||||
|
||||
Result OpenAtmosphereRomfsFile(FsFile *out, ncm::ProgramId program_id, const char *path, u32 mode, FsFileSystem *fs) {
|
||||
char fixed_path[FS_MAX_PATH];
|
||||
FormatAtmosphereRomfsPath(fixed_path, sizeof(fixed_path), program_id, path);
|
||||
return fsFsOpenFile(fs, fixed_path, mode, out);
|
||||
}
|
||||
|
||||
Result OpenSdDirectory(FsDir *out, const char *path, u32 mode) {
|
||||
R_TRY(EnsureSdInitialized());
|
||||
return fsFsOpenDirectory(&g_sd_filesystem, path, mode, out);
|
||||
}
|
||||
|
||||
Result OpenAtmosphereSdDirectory(FsDir *out, const char *path, u32 mode) {
|
||||
char fixed_path[FS_MAX_PATH];
|
||||
FormatAtmosphereSdPath(fixed_path, sizeof(fixed_path), path);
|
||||
return OpenSdDirectory(out, fixed_path, mode);
|
||||
}
|
||||
|
||||
Result OpenAtmosphereSdDirectory(FsDir *out, ncm::ProgramId program_id, const char *path, u32 mode) {
|
||||
char fixed_path[FS_MAX_PATH];
|
||||
FormatAtmosphereSdPath(fixed_path, sizeof(fixed_path), program_id, path);
|
||||
return OpenSdDirectory(out, fixed_path, mode);
|
||||
}
|
||||
|
||||
Result OpenAtmosphereSdRomfsDirectory(FsDir *out, ncm::ProgramId program_id, const char *path, u32 mode) {
|
||||
char fixed_path[FS_MAX_PATH];
|
||||
FormatAtmosphereRomfsPath(fixed_path, sizeof(fixed_path), program_id, path);
|
||||
return OpenSdDirectory(out, fixed_path, mode);
|
||||
}
|
||||
|
||||
Result OpenAtmosphereRomfsDirectory(FsDir *out, ncm::ProgramId program_id, const char *path, u32 mode, FsFileSystem *fs) {
|
||||
char fixed_path[FS_MAX_PATH];
|
||||
FormatAtmosphereRomfsPath(fixed_path, sizeof(fixed_path), program_id, path);
|
||||
return fsFsOpenDirectory(fs, fixed_path, mode, out);
|
||||
}
|
||||
|
||||
|
||||
bool HasSdRomfsContent(ncm::ProgramId program_id) {
|
||||
/* Check if romfs.bin is present. */
|
||||
{
|
||||
FsFile romfs_file;
|
||||
if (R_SUCCEEDED(OpenAtmosphereSdFile(&romfs_file, program_id, "romfs.bin", OpenMode_Read))) {
|
||||
fsFileClose(&romfs_file);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for romfs folder with content. */
|
||||
FsDir romfs_dir;
|
||||
if (R_FAILED(OpenAtmosphereSdRomfsDirectory(&romfs_dir, program_id, "", OpenDirectoryMode_All))) {
|
||||
return false;
|
||||
}
|
||||
ON_SCOPE_EXIT { fsDirClose(&romfs_dir); };
|
||||
|
||||
/* Verify the folder has at least one entry. */
|
||||
s64 num_entries = 0;
|
||||
return R_SUCCEEDED(fsDirGetEntryCount(&romfs_dir, &num_entries)) && num_entries > 0;
|
||||
}
|
||||
|
||||
Result SaveAtmosphereSdFile(FsFile *out, ncm::ProgramId program_id, const char *path, void *data, size_t size) {
|
||||
R_TRY(EnsureSdInitialized());
|
||||
|
||||
char fixed_path[FS_MAX_PATH];
|
||||
FormatAtmosphereSdPath(fixed_path, sizeof(fixed_path), program_id, path);
|
||||
|
||||
/* Unconditionally create. */
|
||||
/* Don't check error, as a failure here should be okay. */
|
||||
FsFile f;
|
||||
fsFsCreateFile(&g_sd_filesystem, fixed_path, size, 0);
|
||||
|
||||
/* Try to open. */
|
||||
R_TRY(fsFsOpenFile(&g_sd_filesystem, fixed_path, OpenMode_ReadWrite, &f));
|
||||
auto file_guard = SCOPE_GUARD { fsFileClose(&f); };
|
||||
|
||||
/* Try to set the size. */
|
||||
R_TRY(fsFileSetSize(&f, static_cast<s64>(size)));
|
||||
|
||||
/* Try to write data. */
|
||||
R_TRY(fsFileWrite(&f, 0, data, size, FsWriteOption_Flush));
|
||||
|
||||
/* Set output. */
|
||||
file_guard.Cancel();
|
||||
*out = f;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user