diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index 70acd30f..7ad20b4a 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -77,6 +77,19 @@ typedef struct u64 unk_x38; ///< 0 for SystemSaveData/SaveData. } FsSave; +/// SaveCreate Struct +typedef struct +{ + u64 journalSize; + u64 flags; + u64 blockSize; + u64 size; + u32 unk_x20; + u8 SaveDataSpaceId; + u8 unk_x25; + u8 uninitialized[0x1A]; +} FsSaveCreate; + typedef struct { u64 saveID_unk; @@ -226,6 +239,8 @@ Service* fsGetServiceSession(void); Result fsOpenBisStorage(FsStorage* out, FsBisStorageId PartitionId); Result fsOpenBisFileSystem(FsFileSystem* out, FsBisStorageId PartitionId, const char* string); +Result fsCreateSaveDataFileSystemBySystemSaveDataId(FsSave* save, FsSaveCreate* create); + Result fsIsExFatSupported(bool* out); /// Do not call this directly, see fs_dev.h. @@ -245,8 +260,14 @@ Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id); /// Retrieves the rights id and key generation corresponding to the content path. Only available on [3.0.0+]. Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generation, FsRightsId* out_rights_id); + +Result fsDisableAutoSaveDataCreation(void); // todo: Rest of commands here +// Wrapper(s) for fsCreateSaveDataFileSystemBySystemSaveDataId. +Result fsCreate_SystemSaveDataWithOwner(FsSaveDataSpaceId space_id, u64 save_data_id, u64 user_id, u64 owner_id, u64 size, u64 journal_size, u32 flags); +Result fsCreate_SystemSaveData(FsSaveDataSpaceId space_id, u64 save_data_id, u64 size, u64 journal_size, u32 flags); + /// FsFileSystem can be mounted with fs_dev for use with stdio, see fs_dev.h. /// Wrapper(s) for fsMountSaveData. diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index 1653e5bc..c3524ff5 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -150,6 +150,42 @@ Result fsOpenBisFileSystem(FsFileSystem* out, FsBisStorageId PartitionId, const return rc; } +Result fsCreateSaveDataFileSystemBySystemSaveDataId(FsSave* save, FsSaveCreate* create) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + FsSave save; + FsSaveCreate create; + } PACKED *raw; + + raw = serviceIpcPrepareHeader(&g_fsSrv, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 23; + memcpy(&raw->save, save, sizeof(FsSave)); + memcpy(&raw->create, create, sizeof(FsSaveCreate)); + + 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; + } + + return rc; +} + Result fsMountSdcard(FsFileSystem* out) { IpcCommand c; ipcInitialize(&c); @@ -590,6 +626,37 @@ Result fsGetRightsIdAndKeyGenerationByPath(const char* path, u8* out_key_generat return rc; } +Result fsDisableAutoSaveDataCreation(void) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = serviceIpcPrepareHeader(&g_fsSrv, &c, sizeof(*raw)); + raw->magic = SFCI_MAGIC; + raw->cmd_id = 1003; + + 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; + } + + return rc; +} + Result fsIsExFatSupported(bool* out) { if (hosversionBefore(2,0,0)) { @@ -633,6 +700,28 @@ Result fsIsExFatSupported(bool* out) return rc; } +// Wrapper(s) for fsCreateSaveDataFileSystemBySystemSaveDataId. +Result fsCreate_SystemSaveDataWithOwner(FsSaveDataSpaceId space_id, u64 save_data_id, u64 user_id, u64 owner_id, u64 size, u64 journal_size, u32 flags) { + FsSave save; + FsSaveCreate create; + + memset(&save, 0, sizeof(save)); + save.userID = (u128)user_id | ((u128)owner_id << 64); + save.saveID = save_data_id; + memset(&create, 0, sizeof(create)); + create.SaveDataSpaceId = space_id; + create.blockSize = 0x4000; + create.journalSize = journal_size; + create.flags = flags; + create.size = size; + + return fsCreateSaveDataFileSystemBySystemSaveDataId(&save, &create); +} + +Result fsCreate_SystemSaveData(FsSaveDataSpaceId space_id, u64 save_data_id, u64 size, u64 journal_size, u32 flags) { + return fsCreate_SystemSaveDataWithOwner(space_id, save_data_id, 0, 0, size, journal_size, flags); +} + // Wrapper(s) for fsMountSaveData. Result fsMount_SaveData(FsFileSystem* out, u64 titleID, u128 userID) { FsSave save;