From 0c5efe5f9ca3e14e2dd82e596456b91ad1dbf25c Mon Sep 17 00:00:00 2001 From: yellows8 Date: Thu, 30 Nov 2017 01:58:21 -0500 Subject: [PATCH] Added a comment in fs_dev.h. Adjusted fs.h formatting, etc. Added support for mounting SaveData. --- nx/include/switch/devices/fs_dev.h | 1 + nx/include/switch/services/fs.h | 55 ++++++++++++++++++++++++------ nx/source/devices/fs_dev.c | 1 + nx/source/services/fs.c | 51 +++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 10 deletions(-) diff --git a/nx/include/switch/devices/fs_dev.h b/nx/include/switch/devices/fs_dev.h index e6b6edcd..95ca5785 100644 --- a/nx/include/switch/devices/fs_dev.h +++ b/nx/include/switch/devices/fs_dev.h @@ -25,6 +25,7 @@ Result fsdevInit(void); Result fsdevExit(void); /// Mounts the input fs with the specified device name. fsdev will handle closing the fs when required, including when fsdevMountDevice() fails. +/// Returns -1 when any errors occur. int fsdevMountDevice(const char *name, FsFileSystem fs); /// Unmounts the specified device. diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index 0e48b054..a4610a00 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -4,6 +4,15 @@ #define FS_MAX_PATH 0x301 +/// For use with fsMountSaveData(). +#define FS_MOUNTSAVEDATA_INVAL_DEFAULT 0x1 + +/// For use with FsSave. +#define FS_SAVEDATA_CURRENT_TITLEID 0 + +/// For use with FsSave. +#define FS_SAVEDATA_USERID_COMMONSAVE 0 + typedef struct { Handle h; } FsFileSystem; @@ -23,13 +32,25 @@ typedef struct { /// Directory entry. typedef struct { - char name[FS_MAX_PATH]; ///< Entry name. - u8 pad[3]; - s8 type; ///< See FsEntryType. - u8 pad2[3]; ///< ? - u64 fileSize; ///< File size. + char name[FS_MAX_PATH]; ///< Entry name. + u8 pad[3]; + s8 type; ///< See FsEntryType. + u8 pad2[3]; ///< ? + u64 fileSize; ///< File size. } FsDirectoryEntry; +/// Save Struct +typedef struct +{ + u64 titleID; ///< titleID of the savedata to access when accessing other titles' savedata via SaveData, otherwise FS_SAVEDATA_CURRENT_TITLEID. + u128 userID; ///< userID of the user-specific savedata to access, otherwise FS_SAVEDATA_USERID_COMMONSAVE. See account.h. + u64 saveID; ///< saveID, 0 for SaveData. + u64 ContentStorageId; ///< ContentStorageId? See FsContentStorageId. + u64 unk_x28; ///< 0 for SystemSaveData/SaveData. + u64 unk_x30; ///< 0 for SystemSaveData/SaveData. + u64 unk_x38; ///< 0 for SystemSaveData/SaveData. +} PACKED FsSave; + typedef enum { ENTRYTYPE_DIR = 0, ENTRYTYPE_FILE = 1 @@ -37,26 +58,40 @@ typedef enum { typedef enum { - FS_OPEN_READ = BIT(0), ///< Open for reading. - FS_OPEN_WRITE = BIT(1), ///< Open for writing. - FS_OPEN_APPEND = BIT(2), ///< Append file. + FS_OPEN_READ = BIT(0), ///< Open for reading. + FS_OPEN_WRITE = BIT(1), ///< Open for writing. + FS_OPEN_APPEND = BIT(2), ///< Append file. } FsFileFlags; /// For use with fsFsOpenDirectory. typedef enum { - FS_DIROPEN_DIRECTORY = BIT(0), ///< Enable reading directory entries. - FS_DIROPEN_FILE = BIT(1), ///< Enable reading file entries. + FS_DIROPEN_DIRECTORY = BIT(0), ///< Enable reading directory entries. + FS_DIROPEN_FILE = BIT(1), ///< Enable reading file entries. } FsDirectoryFlags; +typedef enum +{ + FS_CONTENTSTORAGEID_NandSystem = 0, + FS_CONTENTSTORAGEID_NandUser = 1, + FS_CONTENTSTORAGEID_SdCard = 2, +} FsContentStorageId; + Result fsInitialize(); void fsExit(void); Handle fsGetServiceSession(void); Result fsMountSdcard(FsFileSystem* out); +Result fsMountSaveData(FsFileSystem* out, u8 inval, FsSave *save); // todo: Rest of commands here +/// FsFileSystem can be mounted with fs_dev for use with stdio, see fs_dev.h. + +/// Wrapper(s) for fsMountSaveData. +/// See FsSave for titleID and userID. +Result fsMount_SaveData(FsFileSystem* out, u64 titleID, u128 userID); + // IFileSystem Result fsFsCreateFile(FsFileSystem* fs, const char* path, size_t size, int flags); Result fsFsDeleteFile(FsFileSystem* fs, const char* path); diff --git a/nx/source/devices/fs_dev.c b/nx/source/devices/fs_dev.c index f04b7043..6fbaaa62 100644 --- a/nx/source/devices/fs_dev.c +++ b/nx/source/devices/fs_dev.c @@ -308,6 +308,7 @@ static int _fsdevMountDevice(const char *name, FsFileSystem fs, fsdev_fsdevice * return dev; } + int fsdevMountDevice(const char *name, FsFileSystem fs) { return _fsdevMountDevice(name, fs, NULL); diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index a3defb62..f0904404 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -87,6 +87,57 @@ Result fsMountSdcard(FsFileSystem* out) { return rc; } +Result fsMountSaveData(FsFileSystem* out, u8 inval, FsSave *save) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 inval;//Actually u8. + FsSave save; + } PACKED *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 51; + raw->inval = (u64)inval; + memcpy(&raw->save, save, sizeof(FsSave)); + + Result rc = ipcDispatch(g_fsHandle); + + if (R_SUCCEEDED(rc)) { + IpcCommandResponse r; + ipcParseResponse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + out->h = r.Handles[0]; + } + } + + return rc; +} + +// Wrapper(s) for fsMountSaveData. +Result fsMount_SaveData(FsFileSystem* out, u64 titleID, u128 userID) { + FsSave save; + + memset(&save, 0, sizeof(save)); + save.titleID = titleID; + save.userID = userID; + save.ContentStorageId = FS_CONTENTSTORAGEID_NandUser; + + return fsMountSaveData(out, FS_MOUNTSAVEDATA_INVAL_DEFAULT, &save); +} + // IFileSystem impl Result fsFsCreateFile(FsFileSystem* fs, const char* path, size_t size, int flags) { IpcCommand c;