mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Introducing fs..
This commit is contained in:
parent
3926969ebc
commit
74b14f4c63
@ -19,6 +19,7 @@ extern "C" {
|
||||
#include <switch/kernel/virtmem.h>
|
||||
|
||||
#include <switch/services/sm.h>
|
||||
#include <switch/services/fs.h>
|
||||
#include <switch/services/bsd.h>
|
||||
#include <switch/services/fatal.h>
|
||||
#include <switch/services/vi.h>
|
||||
|
@ -8,13 +8,13 @@ typedef struct {
|
||||
size_t NumSend; // A
|
||||
size_t NumRecv; // B
|
||||
size_t NumTransfer; // W
|
||||
void* Buffers[4];
|
||||
const void* Buffers[4];
|
||||
size_t BufferSizes[4];
|
||||
u8 Flags[4];
|
||||
|
||||
size_t NumStaticIn; // X
|
||||
size_t NumStaticOut; // C
|
||||
void* Statics[4];
|
||||
const void* Statics[4];
|
||||
size_t StaticSizes[4];
|
||||
u8 Indices[4];
|
||||
|
||||
@ -53,7 +53,7 @@ typedef struct {
|
||||
u32 Packed;
|
||||
} IpcStaticRecvDescriptor;
|
||||
|
||||
static inline void ipcAddSendBuffer(IpcCommand* cmd, void* buffer, size_t size, u8 flags) {
|
||||
static inline void ipcAddSendBuffer(IpcCommand* cmd, const void* buffer, size_t size, u8 flags) {
|
||||
size_t off = cmd->NumSend;
|
||||
cmd->Buffers[off] = buffer;
|
||||
cmd->BufferSizes[off] = size;
|
||||
@ -77,7 +77,7 @@ static inline void ipcAddTransferBuffer(IpcCommand* cmd, void* buffer, size_t si
|
||||
cmd->NumTransfer++;
|
||||
}
|
||||
|
||||
static inline void ipcAddSendStatic(IpcCommand* cmd, void* buffer, size_t size, u8 index) {
|
||||
static inline void ipcAddSendStatic(IpcCommand* cmd, const void* buffer, size_t size, u8 index) {
|
||||
size_t off = cmd->NumStaticIn;
|
||||
cmd->Statics[off] = buffer;
|
||||
cmd->StaticSizes[off] = size;
|
||||
|
57
nx/include/switch/services/fs.h
Normal file
57
nx/include/switch/services/fs.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright 2017 plutoo
|
||||
|
||||
// We use wrapped handles for type safety.
|
||||
|
||||
typedef struct {
|
||||
Handle h;
|
||||
} FsFileSystem;
|
||||
|
||||
typedef struct {
|
||||
Handle h;
|
||||
} FsFile;
|
||||
|
||||
typedef struct {
|
||||
Handle h;
|
||||
} FsDir;
|
||||
|
||||
typedef struct {
|
||||
Handle h;
|
||||
} FsStorage;
|
||||
|
||||
typedef enum {
|
||||
ENTRYTYPE_FILE=0,
|
||||
ENTRYTYPE_DIR =1
|
||||
} FsEntryType;
|
||||
|
||||
#define FS_MAX_PATH 0x301
|
||||
|
||||
Result fsInitialize();
|
||||
Result fsMountSdcard(FsFileSystem* out);
|
||||
// todo: Rest of commands here
|
||||
|
||||
// IFileSystem
|
||||
Result fsFsCreateFile(FsFileSystem* fs, const char* path, size_t size, int flags);
|
||||
Result fsFsDeleteFile(FsFileSystem* fs, const char* path);
|
||||
Result fsFsCreateDirectory(FsFileSystem* fs, const char* path);
|
||||
Result fsFsDeleteDirectory(FsFileSystem* fs, const char* path);
|
||||
Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, const char* path);
|
||||
Result fsFsRenameFile(FsFileSystem* fs, const char* path0, const char* path1);
|
||||
Result fsFsRenameDirectory(FsFileSystem* fs, const char* path0, const char* path1);
|
||||
Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsEntryType* out);
|
||||
Result fsFsOpenFile(FsFileSystem* fs, const char* path, int flags, FsFile* out);
|
||||
Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, int flags, FsDir* out);
|
||||
Result fsFsCommit(FsFileSystem* fs);
|
||||
Result fsFsGetFreeSpace(FsFileSystem* fs, u64* out);
|
||||
Result fsFsGetTotalSpace(FsFileSystem* fs, u64* out);
|
||||
void fsFsClose(FsFileSystem* fs);
|
||||
|
||||
// IFile
|
||||
Result fsFileRead(FsFile* f, u64 off, void* buf, size_t len, size_t* out);
|
||||
Result fsFileWrite(FsFile* f, u64 off, void* buf, size_t len, size_t* out);
|
||||
Result fsFileFlush(FsFile* f);
|
||||
Result fsFileSetSize(FsFile* f, u64 sz);
|
||||
Result fsFileGetSize(FsFile* f, u64* out);
|
||||
void fsFileClose(FsFile* f);
|
||||
|
||||
// todo: IDirectory
|
||||
// todo: IStorage
|
720
nx/source/services/fs.c
Normal file
720
nx/source/services/fs.c
Normal file
@ -0,0 +1,720 @@
|
||||
// Copyright 2017 plutoo
|
||||
#include <switch.h>
|
||||
|
||||
static Handle g_fsHandle = -1;
|
||||
|
||||
Result fsInitialize() {
|
||||
Result rc = smGetService(&g_fsHandle, "fsp-srv");
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcSendPid(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 unk;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
raw->unk = 0;
|
||||
|
||||
rc = ipcDispatch(g_fsHandle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsMountSdcard(FsFileSystem* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 18;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// IFileSystem impl
|
||||
Result fsFsCreateFile(FsFileSystem* fs, const char* path, size_t size, int flags) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 zero;
|
||||
u64 size;
|
||||
u32 flags;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
raw->zero = 0;
|
||||
raw->size = size;
|
||||
raw->flags = flags;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFsDeleteFile(FsFileSystem* fs, const char* path) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFsCreateDirectory(FsFileSystem* fs, const char* path) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 2;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFsDeleteDirectory(FsFileSystem* fs, const char* path) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 3;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFsDeleteDirectoryRecursively(FsFileSystem* fs, const char* path) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 4;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsRenameFile(FsFileSystem* fs, const char* path0, const char* path1) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path0, FS_MAX_PATH, 0);
|
||||
ipcAddSendStatic(&c, path1, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 5;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsRenameDirectory(FsFileSystem* fs, const char* path0, const char* path1) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path0, FS_MAX_PATH, 0);
|
||||
ipcAddSendStatic(&c, path1, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 6;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsEntryType* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 7;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u32 type;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*out = resp->type;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFsOpenFile(FsFileSystem* fs, const char* path, int flags, FsFile* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 flags;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 8;
|
||||
raw->flags = flags;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, int flags, FsDir* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendStatic(&c, path, FS_MAX_PATH, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u32 flags;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 9;
|
||||
raw->flags = flags;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Result fsFsCommit(FsFileSystem* fs) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 10;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFsGetFreeSpace(FsFileSystem* fs, u64* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 11;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 space;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*out = resp->space;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFsGetTotalSpace(FsFileSystem* fs, u64* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 12;
|
||||
|
||||
Result rc = ipcDispatch(fs->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 space;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*out = resp->space;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void fsFsClose(FsFileSystem* fs) {
|
||||
svcCloseHandle(fs->h);
|
||||
}
|
||||
|
||||
// IFile implementation
|
||||
Result fsFileRead(FsFile* f, u64 off, void* buf, size_t len, size_t* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvBuffer(&c, buf, len, 1);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 zero;
|
||||
u64 offset;
|
||||
u64 read_size;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
raw->zero = 0;
|
||||
raw->offset = off;
|
||||
raw->read_size = len;
|
||||
|
||||
Result rc = ipcDispatch(f->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 bytes_read;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*out = resp->bytes_read;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFileWrite(FsFile* f, u64 off, void* buf, size_t len, size_t* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddSendBuffer(&c, buf, len, 1);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 zero;
|
||||
u64 offset;
|
||||
u64 write_size;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
raw->zero = 0;
|
||||
raw->offset = off;
|
||||
raw->write_size = len;
|
||||
|
||||
Result rc = ipcDispatch(f->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 bytes_written;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*out = resp->bytes_written;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFileFlush(FsFile* f) {
|
||||
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 = ipcDispatch(f->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFileSetSize(FsFile* f, 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 = ipcDispatch(f->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsFileGetSize(FsFile* f, u64* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 4;
|
||||
|
||||
Result rc = ipcDispatch(f->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcCommandResponse r;
|
||||
ipcParseResponse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 size;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->size;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void fsFileClose(FsFile* f) {
|
||||
svcCloseHandle(f->h);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user