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:
yellows8 2018-03-26 14:45:12 -04:00
parent 45b36774e0
commit 26d2e6d7f4
2 changed files with 162 additions and 17 deletions

View File

@ -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);

View File

@ -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;
}
}