mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Implemented FsSaveDataIterator (aka ISaveDataInfoReader). In fs*Close(), set the handle to INVALID_HANDLE after closing the handle. Changed ContentStorageId in FsSave to SaveDataType. Added enums FsSaveDataSpaceId and FsSaveDataType. Removed FS_MOUNTSAVEDATA_INVAL_DEFAULT/FS_MOUNTSYSTEMSAVEDATA_INVAL_DEFAULT.
This commit is contained in:
parent
45b36774e0
commit
26d2e6d7f4
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file fs.h
|
||||
* @brief Filesystem (fsp-srv) service IPC wrapper.
|
||||
* Normally applications should just use standard stdio not FS-serv directly. However this can be used if obtaining a FsFileSystem, FsFile, or FsStorage, for mounting with fs_dev/romfs_dev.
|
||||
* Normally applications should just use standard stdio not FS-serv directly. However this can be used if obtaining a FsFileSystem, FsFile, or FsStorage, for mounting with fs_dev/romfs_dev, etc.
|
||||
* @author plutoo
|
||||
* @author yellows8
|
||||
* @copyright libnx Authors
|
||||
@ -14,16 +14,10 @@
|
||||
|
||||
#define FS_MAX_PATH 0x301
|
||||
|
||||
/// For use with fsMountSaveData().
|
||||
#define FS_MOUNTSAVEDATA_INVAL_DEFAULT 0x1
|
||||
|
||||
/// For use with fsMountSystemSaveData().
|
||||
#define FS_MOUNTSYSTEMSAVEDATA_INVAL_DEFAULT 0x0
|
||||
|
||||
/// For use with FsSave.
|
||||
#define FS_SAVEDATA_CURRENT_TITLEID 0
|
||||
|
||||
/// For use with FsSave.
|
||||
/// For use with \ref FsSave and \ref FsSaveDataInfo.
|
||||
#define FS_SAVEDATA_USERID_COMMONSAVE 0
|
||||
|
||||
typedef struct {
|
||||
@ -42,6 +36,10 @@ typedef struct {
|
||||
Handle h;
|
||||
} FsStorage;
|
||||
|
||||
typedef struct {
|
||||
Handle h;
|
||||
} FsSaveDataIterator;
|
||||
|
||||
/// Directory entry.
|
||||
typedef struct
|
||||
{
|
||||
@ -58,12 +56,25 @@ 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 SaveDataType; ///< See \ref FsSaveDataType.
|
||||
u64 unk_x28; ///< 0 for SystemSaveData/SaveData.
|
||||
u64 unk_x30; ///< 0 for SystemSaveData/SaveData.
|
||||
u64 unk_x38; ///< 0 for SystemSaveData/SaveData.
|
||||
} PACKED FsSave;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 saveID_unk;
|
||||
u8 SaveDataSpaceId; ///< See \ref FsSaveDataSpaceId.
|
||||
u8 SaveDataType; ///< See \ref FsSaveDataType.
|
||||
u8 pad[6];
|
||||
u128 userID; ///< See userID for \ref FsSave.
|
||||
u64 saveID; ///< See saveID for \ref FsSave.
|
||||
u64 titleID; ///< titleID for FsSaveDataType_SaveData.
|
||||
u64 size; ///< Raw saveimage size.
|
||||
u8 unk_x38[0x28]; ///< Unknown. Usually zeros?
|
||||
} PACKED FsSaveDataInfo;
|
||||
|
||||
typedef enum {
|
||||
ENTRYTYPE_DIR = 0,
|
||||
ENTRYTYPE_FILE = 1
|
||||
@ -90,6 +101,26 @@ typedef enum
|
||||
FS_CONTENTSTORAGEID_SdCard = 2,
|
||||
} FsContentStorageId;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FsSaveDataSpaceId_NandSystem = 0,
|
||||
FsSaveDataSpaceId_NandUser = 1,
|
||||
FsSaveDataSpaceId_SdCard = 2,
|
||||
FsSaveDataSpaceId_TemporaryStorage = 3,
|
||||
|
||||
FsSaveDataSpaceId_All = -1, ///< Pseudo value for fsOpenSaveDataIterator().
|
||||
} FsSaveDataSpaceId;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FsSaveDataType_SystemSaveData = 0,
|
||||
FsSaveDataType_SaveData = 1,
|
||||
FsSaveDataType_BcatDeliveryCacheStorage = 2,
|
||||
FsSaveDataType_DeviceSaveData = 3,
|
||||
FsSaveDataType_TemporaryStorage = 4, ///< [3.0.0+]
|
||||
FsSaveDataType_CacheStorage = 5, ///< [3.0.0+]
|
||||
} FsSaveDataType;
|
||||
|
||||
Result fsInitialize(void);
|
||||
void fsExit(void);
|
||||
|
||||
@ -100,6 +131,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 fsOpenDataStorageByCurrentProcess(FsStorage* out);
|
||||
// todo: Rest of commands here
|
||||
|
||||
@ -145,3 +177,9 @@ void fsDirClose(FsDir* d);
|
||||
// IStorage
|
||||
Result fsStorageRead(FsStorage* s, u64 off, void* buf, size_t len);
|
||||
void fsStorageClose(FsStorage* s);
|
||||
|
||||
// ISaveDataInfoReader
|
||||
|
||||
/// Read FsSaveDataInfo data into the buf array.
|
||||
Result fsSaveDataIteratorRead(FsSaveDataIterator *s, FsSaveDataInfo* buf, size_t max_entries, size_t* total_entries);
|
||||
void fsSaveDataIteratorClose(FsSaveDataIterator *s);
|
||||
|
@ -177,6 +177,56 @@ Result fsMountSystemSaveData(FsFileSystem* out, u8 inval, FsSave *save) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsOpenSaveDataIterator(FsSaveDataIterator* out, s32 SaveDataSpaceId) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u8 SaveDataSpaceId;
|
||||
} *raw2;
|
||||
|
||||
if (SaveDataSpaceId == FsSaveDataSpaceId_All) {
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 60;
|
||||
}
|
||||
else {
|
||||
raw2 = ipcPrepareHeader(&c, sizeof(*raw2));
|
||||
|
||||
raw2->magic = SFCI_MAGIC;
|
||||
raw2->cmd_id = 61;
|
||||
raw2->SaveDataSpaceId = SaveDataSpaceId;
|
||||
}
|
||||
|
||||
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)) {
|
||||
out->h = r.Handles[0];
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result fsOpenDataStorageByCurrentProcess(FsStorage* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
@ -219,9 +269,9 @@ Result fsMount_SaveData(FsFileSystem* out, u64 titleID, u128 userID) {
|
||||
memset(&save, 0, sizeof(save));
|
||||
save.titleID = titleID;
|
||||
save.userID = userID;
|
||||
save.ContentStorageId = FS_CONTENTSTORAGEID_NandUser;
|
||||
save.SaveDataType = FsSaveDataType_SaveData;
|
||||
|
||||
return fsMountSaveData(out, FS_MOUNTSAVEDATA_INVAL_DEFAULT, &save);
|
||||
return fsMountSaveData(out, FsSaveDataSpaceId_NandUser, &save);
|
||||
}
|
||||
|
||||
Result fsMount_SystemSaveData(FsFileSystem* out, u64 saveID) {
|
||||
@ -229,9 +279,9 @@ Result fsMount_SystemSaveData(FsFileSystem* out, u64 saveID) {
|
||||
|
||||
memset(&save, 0, sizeof(save));
|
||||
save.saveID = saveID;
|
||||
save.ContentStorageId = FS_CONTENTSTORAGEID_NandSystem;
|
||||
save.SaveDataType = FsSaveDataType_SystemSaveData;
|
||||
|
||||
return fsMountSystemSaveData(out, FS_MOUNTSYSTEMSAVEDATA_INVAL_DEFAULT, &save);
|
||||
return fsMountSystemSaveData(out, FsSaveDataSpaceId_NandSystem, &save);
|
||||
}
|
||||
|
||||
// IFileSystem impl
|
||||
@ -686,7 +736,10 @@ Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, u64* out) {
|
||||
}
|
||||
|
||||
void fsFsClose(FsFileSystem* fs) {
|
||||
if(fs->h != INVALID_HANDLE) svcCloseHandle(fs->h);
|
||||
if(fs->h != INVALID_HANDLE) {
|
||||
svcCloseHandle(fs->h);
|
||||
fs->h = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
// IFile implementation
|
||||
@ -869,12 +922,18 @@ Result fsFileGetSize(FsFile* f, u64* out) {
|
||||
}
|
||||
|
||||
void fsFileClose(FsFile* f) {
|
||||
if(f->h != INVALID_HANDLE) svcCloseHandle(f->h);
|
||||
if(f->h != INVALID_HANDLE) {
|
||||
svcCloseHandle(f->h);
|
||||
f->h = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
// IDirectory implementation
|
||||
void fsDirClose(FsDir* d) {
|
||||
if(d->h != INVALID_HANDLE) svcCloseHandle(d->h);
|
||||
if(d->h != INVALID_HANDLE) {
|
||||
svcCloseHandle(d->h);
|
||||
d->h = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
Result fsDirRead(FsDir* d, u64 inval, size_t* total_entries, size_t max_entries, FsDirectoryEntry *buf) {
|
||||
@ -987,6 +1046,54 @@ Result fsStorageRead(FsStorage* s, u64 off, void* buf, size_t len) {
|
||||
}
|
||||
|
||||
void fsStorageClose(FsStorage* s) {
|
||||
if(s->h != INVALID_HANDLE) svcCloseHandle(s->h);
|
||||
if(s->h != INVALID_HANDLE) {
|
||||
svcCloseHandle(s->h);
|
||||
s->h = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
// ISaveDataInfoReader
|
||||
Result fsSaveDataIteratorRead(FsSaveDataIterator *s, FsSaveDataInfo* buf, size_t max_entries, size_t* total_entries) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvBuffer(&c, buf, sizeof(FsSaveDataInfo)*max_entries, 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
|
||||
Result rc = ipcDispatch(s->h);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 total_entries;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (total_entries) *total_entries = resp->total_entries;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void fsSaveDataIteratorClose(FsSaveDataIterator* s) {
|
||||
if(s->h != INVALID_HANDLE) {
|
||||
svcCloseHandle(s->h);
|
||||
s->h = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user