From f79f4d175bd4ffad041e3e32820f484653d8ff98 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 6 Dec 2018 20:21:15 -0800 Subject: [PATCH] tma: add more dmnt wrapper commands --- stratosphere/tma/source/dmnt.c | 98 ++++++++++++++++++++++++++++++++++ stratosphere/tma/source/dmnt.h | 11 ++++ 2 files changed, 109 insertions(+) diff --git a/stratosphere/tma/source/dmnt.c b/stratosphere/tma/source/dmnt.c index c79f7765c..d8124520a 100644 --- a/stratosphere/tma/source/dmnt.c +++ b/stratosphere/tma/source/dmnt.c @@ -186,3 +186,101 @@ Result dmntTargetIOFileWrite(DmntFile *f, u64 off, const void* buf, size_t len, return rc; } + +Result dmntTargetIOFileGetInformation(const char *path, bool *out_is_dir, DmntFileInformation *out_info) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, path, FS_MAX_PATH, BufferType_Normal); + ipcAddRecvBuffer(&c, out_info, sizeof(*out_info), BufferType_Normal); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = serviceIpcPrepareHeader(&g_dmntSrv, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 34; + + Result rc = serviceIpcDispatch(&g_dmntSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + int is_dir; + } *resp; + + serviceIpcParse(&g_dmntSrv, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + *out_is_dir = resp->is_dir != 0; + } + } + + return rc; +} + +Result dmntTargetIOFileGetSize(const char *path, u64 *out_size) { + DmntFileInformation info; + bool is_dir; + Result rc = dmntTargetIOFileGetInformation(path, &is_dir, &info); + if (R_SUCCEEDED(rc)) { + if (is_dir) { + /* TODO: error code? */ + rc = 0x202; + } else { + *out_size = info.size; + } + } + return rc; +} + +static Result _dmntTargetIOFileSetSize(const void *arg, size_t arg_size, u64 size) { + IpcCommand c; + ipcInitialize(&c); + ipcAddSendBuffer(&c, arg, arg_size, BufferType_Normal); + + struct { + u64 magic; + u64 cmd_id; + u64 size; + } *raw; + + raw = serviceIpcPrepareHeader(&g_dmntSrv, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 36; + raw->size = size; + + Result rc = serviceIpcDispatch(&g_dmntSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + } *resp; + + serviceIpcParse(&g_dmntSrv, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result dmntTargetIOFileSetSize(const char *path, u64 size) { + return _dmntTargetIOFileSetSize(path, FS_MAX_PATH, size); +} + +Result dmntTargetIOFileSetOpenFileSize(DmntFile *f, u64 size) { + /* Atmosphere extension */ + return _dmntTargetIOFileSetSize(f, sizeof(*f), size); +} diff --git a/stratosphere/tma/source/dmnt.h b/stratosphere/tma/source/dmnt.h index 15382fb53..2858cd96f 100644 --- a/stratosphere/tma/source/dmnt.h +++ b/stratosphere/tma/source/dmnt.h @@ -33,6 +33,13 @@ typedef enum { DmntTIOCreateOption_ResetSize = 5, } DmntTIOCreateOption; +typedef struct { + u64 size; + u64 create_time; + u64 access_time; + u64 modify_time; +} DmntFileInformation; + Result dmntInitialize(void); void dmntExit(void); @@ -40,6 +47,10 @@ Result dmntTargetIOFileOpen(DmntFile *out, const char *path, int flags, DmntTIOC Result dmntTargetIOFileClose(DmntFile *f); Result dmntTargetIOFileRead(DmntFile *f, u64 off, void* buf, size_t len, size_t* out_read); Result dmntTargetIOFileWrite(DmntFile *f, u64 off, const void* buf, size_t len, size_t* out_written); +Result dmntTargetIOFileGetInformation(const char *path, bool *out_is_dir, DmntFileInformation *out_info); +Result dmntTargetIOFileGetSize(const char *path, u64 *out_size); +Result dmntTargetIOFileSetSize(const char *path, u64 size); +Result dmntTargetIOFileSetOpenFileSize(DmntFile *f, u64 size); /* Atmosphere extension */ #ifdef __cplusplus }