From d726c7c55c2367b163a6aa7bbc455f1712c09a23 Mon Sep 17 00:00:00 2001 From: Rajko Stojadinovic Date: Sat, 28 Jul 2018 17:49:14 +0200 Subject: [PATCH] Implement some missing fs functions (#141) --- nx/include/switch/services/fs.h | 17 +++ nx/source/services/fs.c | 182 ++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index 0cdd3358..7b1fadf8 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -168,6 +168,20 @@ Result fsMount_SaveData(FsFileSystem* out, u64 titleID, u128 userID); /// WARNING: You can brick when writing to SystemSaveData, if the data is corrupted etc. Result fsMount_SystemSaveData(FsFileSystem* out, u64 saveID); +typedef enum +{ + FsFileSystemType_Logo = 2, + FsFileSystemType_ContentControl = 3, + FsFileSystemType_ContentManual = 4, + FsFileSystemType_ContentMeta = 5, + FsFileSystemType_ContentData = 6, + FsFileSystemType_ApplicationPackage = 7 +} FsFileSystemType; + +/// Mount requested filesystem type from content file +Result fsOpenFileSystem(FsFileSystem* out, u64 titleId, FsFileSystemType fsType); /// only on 1.0.0, only works with registered content +Result fsOpenFileSystemWithId(FsFileSystem* out, u64 titleId, FsFileSystemType fsType, const char* contentPath); /// 2.0.0+, contentPath must be resolved manually + // IFileSystem Result fsFsCreateFile(FsFileSystem* fs, const char* path, size_t size, int flags); Result fsFsDeleteFile(FsFileSystem* fs, const char* path); @@ -200,6 +214,9 @@ void fsDirClose(FsDir* d); // IStorage Result fsStorageRead(FsStorage* s, u64 off, void* buf, size_t len); +Result fsStorageWrite(FsStorage* s, u64 off, const void* buf, size_t len); +Result fsStorageFlush(FsStorage* s); +Result fsStorageSetSize(FsStorage* s, u64 sz); Result fsStorageGetSize(FsStorage* s, u64* out); void fsStorageClose(FsStorage* s); diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index 0652c8aa..f36c273d 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -432,6 +432,88 @@ Result fsMount_SystemSaveData(FsFileSystem* out, u64 saveID) { return fsMountSystemSaveData(out, FsSaveDataSpaceId_NandSystem, &save); } +Result fsOpenFileSystem(FsFileSystem* out, u64 titleId, FsFileSystemType fsType) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 fsType; + u64 titleId; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + raw->fsType = fsType; + raw->titleId = titleId; + + Result rc = serviceIpcDispatch(&g_fsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + serviceCreate(&out->s, r.Handles[0]); + } + } + + return rc; +} + +Result fsOpenFileSystemWithId(FsFileSystem* out, u64 titleId, FsFileSystemType fsType, const char* contentPath) { + char sendStr[FS_MAX_PATH] = {0}; + strncpy(sendStr, contentPath, sizeof(sendStr)-1); + + IpcCommand c; + ipcInitialize(&c); + ipcAddSendStatic(&c, sendStr, sizeof(sendStr), 0); + + struct { + u64 magic; + u64 cmd_id; + u32 fsType; + u64 titleId; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 8; + raw->fsType = fsType; + raw->titleId = titleId; + + Result rc = serviceIpcDispatch(&g_fsSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + serviceCreate(&out->s, r.Handles[0]); + } + } + + return rc; +} + // IFileSystem impl Result fsFsCreateFile(FsFileSystem* fs, const char* path, size_t size, int flags) { IpcCommand c; @@ -1216,6 +1298,106 @@ Result fsStorageRead(FsStorage* s, u64 off, void* buf, size_t len) { return rc; } +Result fsStorageWrite(FsStorage* s, u64 off, const void* buf, size_t len) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, buf, len, 1); + + struct { + u64 magic; + u64 cmd_id; + u64 offset; + u64 write_size; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 1; + raw->offset = off; + raw->write_size = len; + + Result rc = serviceIpcDispatch(&s->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result fsStorageFlush(FsStorage* s) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 2; + + Result rc = serviceIpcDispatch(&s->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result fsStorageSetSize(FsStorage* s, u64 sz) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 size; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 3; + raw->size = sz; + + Result rc = serviceIpcDispatch(&s->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + Result fsStorageGetSize(FsStorage* s, u64* out) { IpcCommand c; ipcInitialize(&c);