diff --git a/nx/include/switch/runtime/devices/romfs_dev.h b/nx/include/switch/runtime/devices/romfs_dev.h index 5fc02913..d5f34166 100644 --- a/nx/include/switch/runtime/devices/romfs_dev.h +++ b/nx/include/switch/runtime/devices/romfs_dev.h @@ -84,6 +84,13 @@ static inline Result romfsInitFromStorage(FsStorage storage, u64 offset) return romfsMountFromStorage(storage, offset, "romfs"); } +/** + * @brief Mounts RomFS from a system data archive. + * @param dataId Title ID of system data archive to mount. + * @param storageId Storage ID to mount from. + * @param name Device mount name. + */ +Result romfsMountFromDataArchive(u64 dataId, FsStorageId storageId, const char *name); /// Unmounts the RomFS device. Result romfsUnmount(const char *name); diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index b114941f..12caa8d6 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -175,6 +175,7 @@ Result fsMountSaveData(FsFileSystem* out, u8 inval, FsSave *save); Result fsMountSystemSaveData(FsFileSystem* out, u8 inval, FsSave *save); Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 SaveDataSpaceId); Result fsOpenDataStorageByCurrentProcess(FsStorage* out); +Result fsOpenDataStorageByDataId(FsStorage* out, u64 dataId, FsStorageId storageId); Result fsOpenDeviceOperator(FsDeviceOperator* out); Result fsOpenSdCardDetectionEventNotifier(FsEventNotifier* out); // todo: Rest of commands here diff --git a/nx/source/runtime/devices/romfs_dev.c b/nx/source/runtime/devices/romfs_dev.c index 115a422f..51e65c96 100644 --- a/nx/source/runtime/devices/romfs_dev.c +++ b/nx/source/runtime/devices/romfs_dev.c @@ -305,7 +305,16 @@ Result romfsMountFromStorage(FsStorage storage, u64 offset, const char *name) mount->offset = offset; return romfsMountCommon(name, mount); +} +Result romfsMountFromDataArchive(u64 dataId, FsStorageId storageId, const char *name) { + FsStorage storage; + + Result rc = fsOpenDataStorageByDataId(&storage, dataId, storageId); + if (R_FAILED(rc)) + return rc; + + return romfsMountFromStorage(storage, 0, name); } Result romfsMountCommon(const char *name, romfs_mount *mount) diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index b6cb44a7..b527ca27 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -353,6 +353,46 @@ Result fsOpenDataStorageByCurrentProcess(FsStorage* out) { return rc; } +Result fsOpenDataStorageByDataId(FsStorage* out, u64 dataId, FsStorageId storageId) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 storage_id; + u64 data_id; + } *raw; + + raw = serviceIpcPrepareHeader(&g_fsSrv, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 202; + raw->storage_id = storageId; + raw->data_id = dataId; + + Result rc = serviceIpcDispatch(&g_fsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + } *resp; + + serviceIpcParse(&g_fsSrv, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + serviceCreateSubservice(&out->s, &g_fsSrv, &r, 0); + } + } + + return rc; +} + Result fsOpenDeviceOperator(FsDeviceOperator* out) { IpcCommand c; ipcInitialize(&c);