diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index 70acd30f..344eba5f 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -68,7 +68,7 @@ typedef struct u64 titleID; ///< titleID of the savedata to access when accessing other titles' savedata via SaveData, otherwise FS_SAVEDATA_CURRENT_TITLEID. union { u128 userID; } PACKED; ///< userID of the user-specific savedata to access, otherwise FS_SAVEDATA_USERID_COMMONSAVE. See account.h. u64 saveID; ///< saveID, 0 for SaveData. - u8 SaveDataType; ///< See \ref FsSaveDataType. + u8 saveDataType; ///< See \ref FsSaveDataType. u8 rank; ///< Save data 'rank' or 'precedence'. 0 if this save data is considered the primary save data. 1 if it's considered the secondary save data. u16 index; ///< Save data index. u32 pad_x24; ///< Padding. @@ -77,11 +77,23 @@ typedef struct u64 unk_x38; ///< 0 for SystemSaveData/SaveData. } FsSave; +/// SaveCreate Struct +typedef struct { + u64 size; ///< Size of the save data. + u64 journalSize; ///< Journal size of the save data. + u64 blockSize; ///< Block size of the save data. + u64 ownerId; ///< Title id of the owner of this save data. 0 for SystemSaveData. + u32 flags; ///< Save data flags. + u8 saveDataSpaceId; ///< See \ref FsSaveDataSpaceId. + u8 unk; ///< 0 for SystemSaveData. + u8 padding[0x1A]; ///< Uninitialized for SystemSaveData. +} FsSaveCreate; + typedef struct { u64 saveID_unk; - u8 SaveDataSpaceId; ///< See \ref FsSaveDataSpaceId. - u8 SaveDataType; ///< See \ref FsSaveDataType. + u8 saveDataSpaceId; ///< See \ref FsSaveDataSpaceId. + u8 saveDataType; ///< See \ref FsSaveDataType. u8 pad[6]; ///< Padding. u128 userID; ///< See userID for \ref FsSave. u64 saveID; ///< See saveID for \ref FsSave. @@ -223,8 +235,10 @@ void fsExit(void); Service* fsGetServiceSession(void); -Result fsOpenBisStorage(FsStorage* out, FsBisStorageId PartitionId); -Result fsOpenBisFileSystem(FsFileSystem* out, FsBisStorageId PartitionId, const char* string); +Result fsOpenBisStorage(FsStorage* out, FsBisStorageId partitionId); +Result fsOpenBisFileSystem(FsFileSystem* out, FsBisStorageId partitionId, const char* string); + +Result fsCreateSaveDataFileSystemBySystemSaveDataId(const FsSave* save, const FsSaveCreate* create); Result fsIsExFatSupported(bool* out); @@ -233,7 +247,7 @@ Result fsMountSdcard(FsFileSystem* out); Result fsMountSaveData(FsFileSystem* out, u8 inval, FsSave *save); Result fsMountSystemSaveData(FsFileSystem* out, u8 inval, FsSave *save); -Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 SaveDataSpaceId); +Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 saveDataSpaceId); Result fsOpenContentStorageFileSystem(FsFileSystem* out, FsContentStorageId content_storage_id); Result fsOpenDataStorageByCurrentProcess(FsStorage* out); Result fsOpenDataStorageByDataId(FsStorage* out, u64 dataId, FsStorageId storageId); @@ -245,8 +259,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 saveDataSpaceId, u64 saveID, u128 userID, u64 ownerId, u64 size, u64 journalSize, u32 flags); +Result fsCreate_SystemSaveData(FsSaveDataSpaceId saveDataSpaceId, u64 saveID, u64 size, u64 journalSize, 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..57b670ca 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -70,7 +70,7 @@ Service* fsGetServiceSession(void) { return &g_fsSrv; } -Result fsOpenBisStorage(FsStorage* out, FsBisStorageId PartitionId) { +Result fsOpenBisStorage(FsStorage* out, FsBisStorageId partitionId) { IpcCommand c; ipcInitialize(&c); @@ -84,7 +84,7 @@ Result fsOpenBisStorage(FsStorage* out, FsBisStorageId PartitionId) { raw->magic = SFCI_MAGIC; raw->cmd_id = 12; - raw->PartitionId = PartitionId; + raw->PartitionId = partitionId; Result rc = serviceIpcDispatch(&g_fsSrv); @@ -108,7 +108,7 @@ Result fsOpenBisStorage(FsStorage* out, FsBisStorageId PartitionId) { return rc; } -Result fsOpenBisFileSystem(FsFileSystem* out, FsBisStorageId PartitionId, const char* string) { +Result fsOpenBisFileSystem(FsFileSystem* out, FsBisStorageId partitionId, const char* string) { IpcCommand c; ipcInitialize(&c); @@ -126,7 +126,7 @@ Result fsOpenBisFileSystem(FsFileSystem* out, FsBisStorageId PartitionId, const raw->magic = SFCI_MAGIC; raw->cmd_id = 11; - raw->PartitionId = PartitionId; + raw->PartitionId = partitionId; Result rc = serviceIpcDispatch(&g_fsSrv); @@ -150,6 +150,42 @@ Result fsOpenBisFileSystem(FsFileSystem* out, FsBisStorageId PartitionId, const return rc; } +Result fsCreateSaveDataFileSystemBySystemSaveDataId(const FsSave* save, const 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); @@ -266,7 +302,7 @@ Result fsMountSystemSaveData(FsFileSystem* out, u8 inval, FsSave *save) { return rc; } -Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 SaveDataSpaceId) { +Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 saveDataSpaceId) { IpcCommand c; ipcInitialize(&c); @@ -278,10 +314,10 @@ Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 SaveDataSpaceId) { struct { u64 magic; u64 cmd_id; - u8 SaveDataSpaceId; + u8 saveDataSpaceId; } *raw2; - if (SaveDataSpaceId == FsSaveDataSpaceId_All) { + if (saveDataSpaceId == FsSaveDataSpaceId_All) { raw = serviceIpcPrepareHeader(&g_fsSrv, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; @@ -292,7 +328,7 @@ Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 SaveDataSpaceId) { raw2->magic = SFCI_MAGIC; raw2->cmd_id = 61; - raw2->SaveDataSpaceId = SaveDataSpaceId; + raw2->saveDataSpaceId = saveDataSpaceId; } Result rc = serviceIpcDispatch(&g_fsSrv); @@ -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 saveDataSpaceId, u64 saveID, u128 userID, u64 ownerId, u64 size, u64 journalSize, u32 flags) { + FsSave save = { + .userID = userID, + .saveID = saveID, + }; + FsSaveCreate create = { + .size = size, + .journalSize = journalSize, + .blockSize = 0x4000, + .ownerId = ownerId, + .flags = flags, + .saveDataSpaceId = saveDataSpaceId, + }; + + return fsCreateSaveDataFileSystemBySystemSaveDataId(&save, &create); +} + +Result fsCreate_SystemSaveData(FsSaveDataSpaceId saveDataSpaceId, u64 saveID, u64 size, u64 journalSize, u32 flags) { + return fsCreate_SystemSaveDataWithOwner(saveDataSpaceId, saveID, 0, 0, size, journalSize, flags); +} + // Wrapper(s) for fsMountSaveData. Result fsMount_SaveData(FsFileSystem* out, u64 titleID, u128 userID) { FsSave save; @@ -640,7 +729,7 @@ Result fsMount_SaveData(FsFileSystem* out, u64 titleID, u128 userID) { memset(&save, 0, sizeof(save)); save.titleID = titleID; save.userID = userID; - save.SaveDataType = FsSaveDataType_SaveData; + save.saveDataType = FsSaveDataType_SaveData; return fsMountSaveData(out, FsSaveDataSpaceId_NandUser, &save); } @@ -650,7 +739,7 @@ Result fsMount_SystemSaveData(FsFileSystem* out, u64 saveID) { memset(&save, 0, sizeof(save)); save.saveID = saveID; - save.SaveDataType = FsSaveDataType_SystemSaveData; + save.saveDataType = FsSaveDataType_SystemSaveData; return fsMountSystemSaveData(out, FsSaveDataSpaceId_NandSystem, &save); }